views:

50

answers:

4

I would like to update a record with two dates, leaving existing data intact if I do not have a new value to update with.

Here is a sample table record:

id  last_foo    last_bar
--  ----------  ----------
 1  2010-05-30  2010-05-30

And the query I am using:

UPDATE sampledates
   SET last_foo = @LastFoo, 
       last_bar = @LastBar
 WHERE id = @ID;

If my nullable datetimes LastFoo or LastBar are null, I would like to leave the existing SQL value as-is, otherwise update.

For example, say I am updating this record with the following values (this is C# but any language applies):

DateTime? LastFoo = new DateTime('2010-06-04');
DateTime? LastBar = null;

I would like the record to then be:

id  last_foo    last_bar
--  ----------  ----------
 1  2010-06-04  2010-05-30

I realize I can alter my query text to omit the second column if the value is null, but I wondered if there is a way I can leave the query as-is and specify that I am not changing the column specified.

+7  A: 

Try

UPDATE sampledates
SET last_foo = COALESCE(@LastFoo,last_foo ), 
last_bar = COALESCE(@LastBar,last_bar )
WHERE id = @ID;
SQLMenace
Worked perfectly. Thanks for pointing out `COALESCE` to me.
JYelton
+5  A: 

You can use COALESCE:

UPDATE sampledates
SET last_foo = COALESCE(@LastFoo, last_foo),
    last_bar = COALESCE(@LastBar, last_bar)
WHERE id = @ID;

In SQL Server you get a minor performance improvement by using ISNULL instead of COALESCE.

UPDATE sampledates
SET last_foo = ISNULL(@LastFoo, last_foo),
    last_bar = ISNULL(@LastBar, last_bar)
WHERE id = @ID;
Mark Byers
Thanks Mark for the `ISNULL` reference as well. SQLMenace had the same idea a tad earlier, so I picked his answer.
JYelton
+2  A: 

Try this (this is untested, I don't have SSMS available to me right now)

UPDATE sampledates
   SET last_foo = CASE WHEN @LastFoo IS NULL THEN last_foo ELSE @LastFoo END, 
       last_bar = CASE WHEN @LastBar IS NULL THEN last_foo ELSE @LastBar END
  WHERE id = @ID;
Mike M.
Just out of curiosity, what's faster? COALESCE, ISNULL or CASE logic?
kprobst
ISNULL last I have heard. Coalesce is ANSI standard though, and works for more than 1 case. ISNULL only accepts one parameter that can be null, coalesce takes as many as you throw at it.
Mike M.
+1 because without coalesce or isnull, this would work too. :)
JYelton
+1  A: 

You could try something like

UPDATE sampledates
SET last_foo = (case when @LastFoo IS NULL then last_foo else @LastFoo end), 
last_bar = (case when @LastBar IS NULL then last_bar else @LastBar end)
WHERE id = @ID;
VeeArr
+1 because without coalesce or isnull, this would work too. :)
JYelton