Existe-t-il un équivalent de IsDate ou IsNumeric pour uniqueidentifier (SQL Server)? Ou existe-t-il un équivalent de (C #) TryParse?
Sinon, je devrais écrire ma propre fonction, mais je veux m'assurer de ne pas réinventer la roue.
Le scénario que j'essaie de couvrir est le suivant:
SELECT something FROM table WHERE IsUniqueidentifier(column) = 1
SQL Server 2012 rend tout cela beaucoup plus facile avec TRY_CONVERT(UNIQUEIDENTIFIER, expression)
SELECT something
FROM your_table
WHERE TRY_CONVERT(UNIQUEIDENTIFIER, your_column) IS NOT NULL;
Pour les versions précédentes de SQL Server, les réponses existantes ne tiennent pas compte de quelques points, ce qui signifie qu'elles risquent de ne pas correspondre aux chaînes que SQL Server transtypera en réalité en UNIQUEIDENTIFIER
sans se plaindre, ou de provoquer des erreurs de conversion non valides.
SQL Server accepte les GUID soit enveloppés dans {}
, soit sans cela.
De plus, il ignore les caractères superflus à la fin de la chaîne. SELECT CAST('{5D944516-98E6-44C5-849F-9C277833C01B}ssssssssss' as uniqueidentifier)
et SELECT CAST('5D944516-98E6-44C5-849F-9C277833C01BXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' as uniqueidentifier)
réussissent tous les deux, par exemple.
Dans la plupart des classements par défaut, le LIKE '[a-zA-Z0-9]'
finira par correspondre aux caractères tels que À
ou Ë
Enfin, si vous convertissez des lignes dans un résultat en uniqueidentifier, il est important de placer la tentative de conversion dans une expression case, car la conversion peut survenir avant que les lignes ne soient filtrées par la variable WHERE
.
Donc (empruntant l’idée de @ r0d30b0y ) une version légèrement plus robuste pourrait être
;WITH T(C)
AS (SELECT '5D944516-98E6-44C5-849F-9C277833C01B'
UNION ALL
SELECT '{5D944516-98E6-44C5-849F-9C277833C01B}'
UNION ALL
SELECT '5D944516-98E6-44C5-849F-9C277833C01BXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
UNION ALL
SELECT '{5D944516-98E6-44C5-849F-9C277833C01B}ssssssssss'
UNION ALL
SELECT 'ÀD944516-98E6-44C5-849F-9C277833C01B'
UNION ALL
SELECT 'fish')
SELECT CASE
WHEN C LIKE expression + '%'
OR C LIKE '{' + expression + '}%' THEN CAST(C AS UNIQUEIDENTIFIER)
END
FROM T
CROSS APPLY (SELECT REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]') COLLATE Latin1_General_BIN) C2(expression)
WHERE C LIKE expression + '%'
OR C LIKE '{' + expression + '}%'
Pas le mien, j'ai trouvé ça en ligne ... je pensais partager.
SELECT 1 WHERE @StringToCompare LIKE
REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]');
SELECT something
FROM table1
WHERE column1 LIKE '[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]';
METTRE À JOUR:
... mais je préfère de loin l'approche dans la réponse de @ r0d30b0y:
SELECT something
FROM table1
WHERE column1 LIKE REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]');
Je ne suis pas au courant de quoi que ce soit que vous pourriez utiliser «hors de la boîte» - vous devrez écrire cela vous-même, j'en ai bien peur.
Si vous le pouvez: essayez d’écrire cela dans une bibliothèque C # et de le déployer dans SQL Server en tant qu’assemblage SQL-CLR - vous pouvez utiliser des fonctions telles que Guid.TryParse()
, qui est certainement beaucoup plus simple à utiliser que dans T-SQL ....
Une variante de la réponse r0d30b0y consiste à utiliser PATINDEX pour rechercher dans une chaîne ...
PATINDEX('%'+REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]')+'%',@StringToCompare) > 0
Doit utiliser pour trouver des Guids dans une chaîne d'URL ..
HTH
Dave
Comme pour garder les choses simples. Un GUID en a quatre - même s'il ne s'agit que d'une chaîne
Où colonne comme '% -% -% -% -%'
Bien qu’il s’agisse d’un message plus ancien, il suffit de penser à un test rapide ...
SELECT [A].[INPUT],
CAST([A].[INPUT] AS [UNIQUEIDENTIFIER])
FROM (
SELECT '5D944516-98E6-44C5-849F-9C277833C01B' Collate Latin1_General_100_BIN AS [INPUT]
UNION ALL
SELECT '{5D944516-98E6-44C5-849F-9C277833C01B}'
UNION ALL
SELECT '5D944516-98E6-44C5-849F-9C277833C01BXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
UNION ALL
SELECT '{5D944516-98E6-44C5-849F-9C277833C01B}ssssssssss'
UNION ALL
SELECT 'ÀD944516-98E6-44C5-849F-9C277833C01B'
UNION ALL
SELECT 'fish'
) [A]
WHERE PATINDEX('[^0-9A-F-{}]%', [A].[INPUT]) = 0
Ceci est une fonction basée sur le concept de certains commentaires précédents. Cette fonction est très rapide.
CREATE FUNCTION [dbo].[IsGuid] (@input varchar(50))
RETURNS bit AS
BEGIN
RETURN
case when @input like '[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]'
then 1 else 0 end
END
GO
/*
Usage:
select [dbo].[IsGuid]('123') -- Returns 0
select [dbo].[IsGuid]('ebd8aebd-7ea3-439d-a7bc-e009dee0eae0') -- Returns 1
select * from SomeTable where dbo.IsGuid(TableField) = 0 -- Returns table with all non convertable items!
*/
J'utilise :
ISNULL(convert(nvarchar(50), userID), 'NULL') = 'NULL'
Vous pouvez écrire votre propre fichier UDF. Il s'agit d'une approximation simple pour éviter l'utilisation d'un assembly SQL-CLR.
CREATE FUNCTION dbo.isuniqueidentifier (@ui varchar(50))
RETURNS bit AS
BEGIN
RETURN case when
substring(@ui,9,1)='-' and
substring(@ui,14,1)='-' and
substring(@ui,19,1)='-' and
substring(@ui,24,1)='-' and
len(@ui) = 36 then 1 else 0 end
END
GO
Vous pouvez ensuite l’améliorer pour vérifier s’il ne s’agit que de valeurs HEX.
Utiliser RLIKE pour MYSQL
SELECT 1 WHERE @StringToCompare
RLIKE REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]');