2016-04-18 8 views
2

Ich habe ein Benutzereingabefeld, das aufgrund meiner eigenen dummen Aufsicht Benutzern erlaubt, leere Zeichenfolgen einzugeben, um zu identifizieren, auf welche Daten ein neuer Datensatz bezogen wurde ...T-SQL Umgang mit White-Space

Dies hat dazu geführt, dass mehrere Datensätze mit leeren Bezeichnern oder Bezeichnern aus mehreren Leerzeichen aufgezeichnet wurden. Diese sind für die Benutzer nicht unterscheidbar, da sie alle nur als leer erscheinen, aber ich würde nicht erwarten, dass dies ein programmatisches Problem ist, da die Strings unterschiedlich sind.

Und dennoch, wenn ich versuche, diese Datensätze abrufen, bekomme ich alle von ihnen, die nur Leerzeichen als die Kennung haben.

Im Wesentlichen kann das Problem wie unten isoliert werden, warum erzeugt diese Abfrage 4 Zeilen mit Ergebnissen für jede SELECT, anstatt nur die, die tatsächlich übereinstimmt?

DECLARE @testTable TABLE ([NumberOfSpaces] INT, [SpaceString] VARCHAR(50)) 

INSERT INTO @testTable ([NumberOfSpaces],[SpaceString]) VALUES 
(0,''), 
(1,' '), 
(2,' '), 
(3,' ') 

SELECT * FROM @testTable WHERE [SpaceString] = '' 
SELECT * FROM @testTable WHERE [SpaceString] = ' ' 
SELECT * FROM @testTable WHERE [SpaceString] = ' ' 
SELECT * FROM @testTable WHERE [SpaceString] = ' ' 

Das ist aus Gründen der Neugier, wie meine eigentlichen Update müssen die Kennungen entfernen, die nur Leerraum enthalten.

+0

HoneyBadgers Kommentar oben ist die Antwort, die ich gesucht habe - leider können Sie keinen Kommentar als Antwort markieren. – Morvael

+0

Kommentar entfernt, durch Antwort ersetzt. – HoneyBadger

+0

Als Antwort markiert – Morvael

Antwort

1

Wie ich es verstehe, trimmt sql-server alle nachfolgenden Leerzeichen, wenn sie in Vergleichen/Joins usw. verwendet wird. Dies ist eigentlich ANSI-Standard. Weitere Informationen here.

1

Sie könnten Ihrer where-Klausel ein zusätzliches Prädikat hinzufügen, um nach DATALENGTH zu suchen.

declare @SpaceString varchar(10) = ' ' 
SELECT * 
FROM @testTable 
WHERE [SpaceString] = '' 
and DATALENGTH(SpaceString) = DATALENGTH(@SpaceString) 

Natürlich das wird ein nonSARGable Prädikat, aber sie haben nicht viel Wahl, da die Tabelle in dieser Daten ermöglicht. Sie hier als LEN und DATALENGTH als nicht ganz die gleiche vorsichtig sein. LEN ignoriert nachfolgende Leerzeichen, DATALENGTH jedoch nicht.

+1

Für zukünftige Leser: Seien Sie vorsichtig beim Kompaktieren von 'DATALENGTH (varchar)' und 'DATALENGTH (nvarchar)'. Ein Unicode-String ('nvarchar') benötigt doppelt so viele Bytes wie derselbe String in' varchar'. Also 'DATALENGTH (N'test ')/2 = DATALENGTH (' test ')'. – HoneyBadger