Stringhe vuote: perché o quando '' è uguale a ''?


17

Chi può spiegare perché

select case when '' = ' ' then 1 else 0 end, LEN(''), LEN(' '), DATALENGTH(''), DATALENGTH(' ');

i rendimenti

----------- ----------- ----------- ----------- -----------
1           0           0           0           1

La divertente conseguenza di ciò è che dentro

create table test ( val varchar(10) );
insert into test values( '' );
update test set val = ' ' where val = '';

l'aggiornamento sostituirà effettivamente la stringa vuota con uno spazio vuoto, ma la clausola where continua ad essere vera e le esecuzioni ripetute dell'istruzione update indicano

(1 row(s) affected)

Risposte:


22

Spazi vuoti finali spiegati :

SQL Server segue le specifiche ANSI / ISO SQL-92 (Sezione 8.2,, Regole generali n. 3) su come confrontare le stringhe con gli spazi. Lo standard ANSI richiede il riempimento per le stringhe di caratteri utilizzate nei confronti in modo che le loro lunghezze corrispondano prima di confrontarle. Il padding influenza direttamente la semantica dei predicati della clausola WHERE e HAVING e altri confronti di stringhe Transact-SQL. Ad esempio, Transact-SQL considera le stringhe 'abc' e 'abc' equivalenti per la maggior parte delle operazioni di confronto.

L'unica eccezione a questa regola è il predicato LIKE. Quando il lato destro di un'espressione di predicato LIKE presenta un valore con uno spazio finale, SQL Server non riempie i due valori della stessa lunghezza prima che si verifichi il confronto. Poiché lo scopo del predicato LIKE, per definizione, è facilitare le ricerche di schemi piuttosto che semplici test di uguaglianza di stringhe, ciò non viola la sezione della specifica ANSI SQL-92 menzionata in precedenza.

Ecco un esempio ben noto di tutti i casi sopra menzionati:

DECLARE @a VARCHAR(10)
DECLARE @b varchar(10)

SET @a = '1'
SET @b = '1 ' --with trailing blank

SELECT 1
WHERE 
    @a = @b 
AND @a NOT LIKE @b
AND @b LIKE @a

Ecco alcuni dettagli in più sul bianco finale e sulla LIKEclausola .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.