Uso de DataLength (VarBinary DataType) en la subcadena
-
28-10-2019 - |
Pregunta
Estoy tratando de seleccionar algunos datos varbinarios de la tabla (Data Varbinary (2048)) a mi DLL .NET sin ningún relleno. Todos mis registros tienen actualmente 64 bytes de largo, pero pueden variar en el futuro.
Utilizo un procedimiento almacenado que hace esto:
select substring(DATA, 1, datalength(DATA)) as DATA from TABLE
Esperaría que esto funcione, pero la corriente que obtengo en mi DLL es 2050 (2048 + 2) bytes de largo.
Cuando codice el valor (select substring(DATA, 1, 64) as DATA from TABLE
) Devuelve 66 bytes como era de esperar.
¿Me estoy perdiendo algo (obvio)?
Solución
select substring(DATA, 1, datalength(DATA)) as DATA from TABLE
Este es un malentendido de los tipos de servidores SQL. Cuando comience con una columna Varbinary (2048), a menos que lo haga más tiempo, permanecerá en 2048 y no colapsará incluso si reduce el contenido de datos real.
Esto le muestra que la longitud de los datos en TemptBL sigue siendo 2048, a pesar de que solo hay un registro en la tabla de origen y es de longitud 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
Si realmente quisiera, necesitaría usar SQL dinámico para dimensionar la columna de salida, pero rara vez es necesario hacer tal cosa.
declare @nsql nvarchar(max)
set @nsql = 'select convert(varbinary(' +
right((select max(datalength(Data)) as MaxLen from tbl),12) +
'), data) as Data from tbl'