Eindeutiger Bezeichner mit zusätzlichen Zeichen, die in Select noch übereinstimmen

19

Wir verwenden SQL Server 2012 mit einem eindeutigen Bezeichner und haben festgestellt, dass bei Auswahl mit zusätzlichen Zeichen am Ende (also nicht 36 Zeichen) immer noch eine Übereinstimmung mit einer UUID zurückgegeben wird.

Beispielsweise:

select * from some_table where uuid = '7DA26ECB-D599-4469-91D4-F9136EC0B4E8' 

Gibt die Zeile mit uuid zurück 7DA26ECB-D599-4469-91D4-F9136EC0B4E8.

Aber wenn du rennst:

select * from some_table where uuid = '7DA26ECB-D599-4469-91D4-F9136EC0B4E8EXTRACHARS'

Es gibt auch die Zeile mit der UUID zurück 7DA26ECB-D599-4469-91D4-F9136EC0B4E8.

SQL Server scheint bei der Auswahl alle Zeichen jenseits von 36 zu ignorieren. Ist dies ein Fehler / eine Funktion oder etwas, das konfiguriert werden kann?

Es ist kein großes Problem, da wir eine Bestätigung für die Länge des Frontends haben, aber es scheint mir kein korrektes Verhalten zu sein.

Chris Jones - Belgien
quelle

Antworten:

10

Die implizite Konvertierung funktioniert auch, wenn der Wert in geschweiften Klammern steht {...}.

Wenn Sie diese in die Abfrage einfügen, schlägt die implizite Konvertierung fehl, wenn der ursprüngliche Wert zu lang ist, da der letzte }am falschen Ort endet.

select * 
from some_table 
where uuid = '{'+'7DA26ECB-D599-4469-91D4-F9136EC0B4E8'+'}'

Wenn Sie versuchen, konvertieren

SELECT CONVERT(UNIQUEIDENTIFIER, '{'+'7DA26ECB-D599-4469-91D4-F9136EC0B4E8EXTRACHARS'+'}');

du erhältst

Msg 8169, Level 16, State 2, Line 1
Conversion failed when converting from a character string to uniqueidentifier.
Mikael Eriksson
quelle
10

SQL Server scheint bei der Auswahl alle Zeichen jenseits von 36 zu ignorieren. Ist dies ein Fehler / eine Funktion oder etwas, das konfiguriert werden kann?

Das Verhalten ist in deruniqueidentifier Onlinedokumentation für den Typ dokumentiert :

Auszug aus dem BOL-Eintrag

Das Beispiel, auf das Bezug genommen wird, ist:

BOL-Beispiel

Trotzdem vermeide ich lieber die impliziten Konvertierungen. Ein uniqueidentifierLiteral kann direkt in T-SQL mithilfe der ODBC-Escape-Syntax eingegeben werden:

DECLARE @T AS TABLE
(
    uuid uniqueidentifier UNIQUE NOT NULL
);

INSERT @T (uuid)
SELECT {guid '{7DA26ECB-D599-4469-91D4-F9136EC0B4E8}'};

SELECT t.uuid 
FROM @T AS t 
WHERE 
    t.uuid = {guid '{7DA26ECB-D599-4469-91D4-F9136EC0B4E8}'};

Dies ist die gleiche Syntax, die SQL Server intern in Ausführungsplänen verwendet, wenn eine Zeichenfolgendarstellung in eine eingegebene Konstante gefaltet wird uniqueidentifier:

SELECT t.uuid 
FROM @T AS t 
WHERE 
    t.uuid = '7DA26ECB-D599-4469-91D4-F9136EC0B4E8';

Indexsuche auf uuid

Ob Sie getippt uniqueidentifiersan und von SQL Server übergeben können, hängt möglicherweise von der verwendeten Bibliothek ab, aber Zeichenfolgen mit 36 ​​Zeichen erscheinen mir als die am wenigsten wünschenswerte der verfügbaren Optionen. Wenn Sie Konvertierungen durchführen müssen, geben Sie diese explizit an und verwenden Sie einen 16-Byte-Binärwert anstelle einer Zeichenfolge.

Paul White sagt GoFundMonica
quelle
9

Die zusätzlichen Zeichen werden von SQL Server bei der impliziten Konvertierung einfach ignoriert (und stillschweigend abgeschnitten). Beispielsweise:

SELECT CONVERT(UNIQUEIDENTIFIER, '7DA26ECB-D599-4469-91D4-F9136EC0B4E8EXTRACHARS');

Ergebnis:

------------------------------------
7DA26ECB-D599-4469-91D4-F9136EC0B4E8

Dies ist nicht anders als in diesem Szenario:

DECLARE @x VARCHAR(1) = 'xyz';
SELECT @x;

Ergebnis:

----
x  

Sie können dies nicht konfigurieren, aber wenn Sie möchten, dass die Konvertierung Ihrer Variablen fehlschlägt, können Sie versuchen, die Variable zuerst in eine Tabelle mit zu stopfen CHAR(36), was aufgrund von Kürzungen fehlschlägt:

DECLARE @x TABLE(y CHAR(36));
INSERT @x SELECT '7DA26ECB-D599-4469-91D4-F9136EC0B4E8EXTRACHARS';

Ergebnis:

Msg 8152, Level 16, State 14, Line 2
String or binary data would be truncated.
The statement has been terminated.
Aaron Bertrand
quelle