views:

49

answers:

3

I have a table with varbinary(max) column and nvarchar(max) column. One of them is null and the other has a value.

I would like to return the column that has the value as a varbinary(max) column. So far I have tried this, that does not work:

SELECT 
      A =  
      CASE A
         WHEN NULL THEN B
         ELSE A 
      END
FROM Table
+2  A: 

Try SELECT ISNULL(A, cast(B AS varbinary(max))) FROM TABLE

Noel Abrahams
+5  A: 
SELECT COALESCE(A, CAST(B As varbinary(max)))

UPDATE: In response to comments (thanks) and assuming B is the nvarchar(max) column, I have moved the CAST inside the COALESCE

Mitch Wheat
If `A` is the `nvarchar(max)` column, this would cause a double conversion for B. I.e. from `varbinary` to `nvarchar` to match the first argument to `coalesce`, and then back again for the explicit cast
Andomar
@Andomar - it doesn't matter what order the columns are in. COALESCE picks the "best" data type from all available. ISNULL uses the first data type.
Damien_The_Unbeliever
@Damien_The_Unbeliever: You're right, though you'll still get a double conversion. (Looks like `nvarchar` has a higher precedence than `varbinary`, http://msdn.microsoft.com/en-us/library/ms190309.aspx)
Andomar
Thanks worked great
Shiraz Bhaiji
@Andomar - agreed. It would be better to put the CAST inside the COALESCE, just against the nvarchar column.
Damien_The_Unbeliever
+1  A: 

Your case statement evaluates to the dreaded A = NULL:

CASE A WHEN NULL THEN B ELSE A END

Is the same as:

CASE WHEN A = NULL then B ELSE A END

One way to fix this is to use A IS NULL, like:

CASE WHEN A IS NULL THEN B ELSE A END

Or even simpler:

COALESCE(A,B)

Both the when and the coalesce will assume the data type of the first argument. To cast the result to varbinary, you can place the varbinary column first, or explicitly cast:

COALESCE(CAST(A AS VARBINARY(MAX)),B)
Andomar
@Andomar - From BOL for COALESCE "Returns the data type of expression with the highest data type precedence.". Whereas ISNULL "Returns the same type as check_expression." (where check_expression is the first argument)
Damien_The_Unbeliever
Also, CASE: "Returns the highest precedence type from the set of types in result_expressions and the optional else_result_expression"
Damien_The_Unbeliever