Utilizzo di dati dati (Varbinary Datatype) nella sottostringa
-
28-10-2019 - |
Domanda
Sto cercando di selezionare alcuni dati varbinari dalla tabella (dati varbinary (2048)) al mio .net dll senza alcuna imbottitura. Tutti i miei record sono attualmente lunghi 64 byte ma possono variare in futuro.
Uso una procedura memorizzata che lo fa:
select substring(DATA, 1, datalength(DATA)) as DATA from TABLE
Mi aspetto che funzioni, ma il flusso che ottengo nella mia DLL è 2050 (2048 + 2) byte di lunghezza.
Quando codifica duramente il valore (select substring(DATA, 1, 64) as DATA from TABLE
) Restituisce 66 byte come mi aspetterei.
Mi manca qualcosa (ovvio)?
Soluzione
select substring(DATA, 1, datalength(DATA)) as DATA from TABLE
Questo è un malinteso dei tipi di server SQL. Quando inizi con una colonna Varbinary (2048), a meno che non si allunga, rimarrà al 2048 e non crollerà anche se si riduce il contenuto di dati effettivi.
Questo mostra che la durata dei dati in Temptbl è ancora 2048, anche se c'è solo un record nella tabella di origine ed è di lunghezza 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
Se lo volessi davvero, dovresti usare SQL dinamico per dimensionare la colonna di output, ma non c'è raramente alcun bisogno di fare una cosa del genere.
declare @nsql nvarchar(max)
set @nsql = 'select convert(varbinary(' +
right((select max(datalength(Data)) as MaxLen from tbl),12) +
'), data) as Data from tbl'