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)?

È stato utile?

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'
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top