Using datalength(varbinary datatype) in substring

3.4k views Asked by At

I am trying to select some varbinary data from TABLE(DATA varbinary(2048)) to my .NET dll without any padding. All my records are currently 64 bytes long but they may vary in the future.

I use a stored procedure that does this:

 select substring(DATA, 1, datalength(DATA)) as DATA from TABLE

I would expect this to work but the stream I get in my dll is 2050(2048 + 2) bytes long.

When I hard code the value (select substring(DATA, 1, 64) as DATA from TABLE) it returns 66 bytes as I would expect.

Am I missing something (obvious)?

1

There are 1 answers

5
RichardTheKiwi On BEST ANSWER
select substring(DATA, 1, datalength(DATA)) as DATA from TABLE

This is a misunderstanding of SQL Server types. When you start off with a varbinary(2048) column, unless you make it longer, it will stay at 2048 and will not collapse even if you reduce the actual data content.

This shows you that the length of DATA in temptbl is still 2048, even though there is only one record in the source table and it is of length 64.

create table tbl(data varbinary(2048))
;
insert into tbl select convert(varbinary(2048),REPLICATE('a',64))
;
select substring(DATA, 1, datalength(Data)) as DATA
into temptbl
from tbl
;
exec sp_help temptbl

If you really wanted to, you would need to use dynamic SQL to size the output column, but there is very rarely any need to do such a thing.

declare @nsql nvarchar(max)
set @nsql = 'select convert(varbinary(' +
 right((select max(datalength(Data)) as MaxLen from tbl),12) +
 '), data) as Data from tbl'