Identifiant unique avec des caractères supplémentaires toujours identiques dans certains

19

Nous utilisons SQL Server 2012 avec un identifiant unique et nous avons remarqué que lorsque vous effectuez des sélections avec des caractères supplémentaires ajoutés à la fin (donc pas 36 caractères), il renvoie toujours une correspondance à un UUID.

Par exemple:

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

renvoie la ligne avec uuid 7DA26ECB-D599-4469-91D4-F9136EC0B4E8.

Mais si vous exécutez:

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

il renvoie également la ligne avec l'uuid 7DA26ECB-D599-4469-91D4-F9136EC0B4E8.

SQL Server semble ignorer tous les caractères au-delà du 36 lors de ses sélections. Est-ce un bug / fonctionnalité ou quelque chose qui peut être configuré?

Ce n'est pas un problème majeur car nous avons une validation sur le front-end pour la longueur, mais cela ne me semble pas correct.

Chris Jones - Belgique
la source

Réponses:

10

La conversion implicite fonctionne également si la valeur est placée entre crochets {...}.

Si vous ajoutez ceux dans la requête, la conversion implicite échouera si la valeur d'origine est trop longue car la dernière }se retrouve au mauvais endroit.

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

Si vous essayez la conversion

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

vous obtenez

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

SQL Server semble ignorer tous les caractères au-delà du 36 lors de ses sélections. Est-ce un bug / fonctionnalité ou quelque chose qui peut être configuré?

Le comportement est documenté dans l'entrée Books Online pour le uniqueidentifiertype :

Extrait d'entrée BOL

L'exemple auquel il est fait référence est:

Exemple BOL

Cela étant dit, je préfère éviter les conversions implicites. Un uniqueidentifierlittéral peut être saisi directement dans T-SQL à l'aide de la syntaxe d'échappement ODBC:

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}'};

Il s'agit de la même syntaxe que SQL Server utilise en interne dans les plans d'exécution lors du pliage constant d'une représentation sous forme de chaîne en une saisie uniqueidentifier:

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

Recherche d'index sur uuid

Le fait que vous puissiez passer ou non la dactylographie uniqueidentifiersvers SQL Server peut dépendre de la bibliothèque que vous utilisez, mais les chaînes de 36 caractères me semblent être la moins souhaitable des options disponibles. Si vous devez effectuer des conversions, rendez-les explicites et utilisez une valeur binaire de 16 octets au lieu d'une chaîne.

Paul White dit GoFundMonica
la source
9

Les caractères supplémentaires sont simplement ignorés (enfin, tronqués en silence) par SQL Server lors de la conversion implicite. Par exemple:

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

Résultat:

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

Ce n'est pas différent de ce scénario:

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

Résultat:

----
x  

Vous ne pouvez pas configurer cela mais si vous voulez que votre variable échoue à la conversion, vous pouvez essayer de bourrer la variable dans une table avec d' CHAR(36)abord, qui échouera en raison de la troncature:

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

Résultat:

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