web-dev-qa-db-de.com

Wie prüfe ich, ob eine Zeichenfolge ein eindeutiger Bezeichner ist?

Gibt es eine Entsprechung zu IsDate oder IsNumeric für uniqueidentifier (SQL Server)? Oder gibt es eine Entsprechung zu (C #) TryParse?

Ansonsten muss ich meine eigene Funktion schreiben, aber ich möchte sicherstellen, dass ich das Rad nicht neu erfinde.

Das Szenario, das ich zu behandeln versuche, ist folgendes:

SELECT something FROM table WHERE IsUniqueidentifier(column) = 1
48
Benoittr

SQL Server 2012 macht dies mit TRY_CONVERT(UNIQUEIDENTIFIER, expression) viel einfacher.

SELECT something
FROM   your_table
WHERE  TRY_CONVERT(UNIQUEIDENTIFIER, your_column) IS NOT NULL;

Bei früheren Versionen von SQL Server fehlen bei den vorhandenen Antworten einige Punkte, was bedeutet, dass sie entweder nicht mit Zeichenfolgen übereinstimmen, die SQL Server ohne Beanstandung in UNIQUEIDENTIFIER konvertiert, oder möglicherweise noch ungültige Besetzungsfehler verursachen.

SQL Server akzeptiert GUIDs, die entweder in {} oder ohne diese eingeschlossen sind.

Darüber hinaus werden überflüssige Zeichen am Ende der Zeichenfolge ignoriert. Sowohl SELECT CAST('{5D944516-98E6-44C5-849F-9C277833C01B}ssssssssss' as uniqueidentifier) als auch SELECT CAST('5D944516-98E6-44C5-849F-9C277833C01BXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' as uniqueidentifier) sind beispielsweise erfolgreich.

Bei den meisten Standardkollatierungen endet der LIKE '[a-zA-Z0-9]' mit Zeichen wie À oder Ë.

Wenn Sie Zeilen in einem Ergebnis zu uniqueidentifier umwandeln, ist es wichtig, den Cast-Versuch in einen Fallausdruck zu setzen, da die Cast möglicherweise vor dem Filtern der Zeilen durch die Variable WHERE auftritt. 

Also (leihweise @ r0d30b0ys Idee ) könnte eine etwas robustere Version sein

;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 + '}%' 
55
Martin Smith

Nicht meins, fand das online ... ich dachte, ich würde es teilen.

SELECT 1 WHERE @StringToCompare LIKE 
       REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]');
54
r0d30b0y
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]';

AKTUALISIEREN:

... aber ich bevorzuge den Ansatz in der Antwort von @ r0d30b0y:

SELECT something 
  FROM table1 
 WHERE column1 LIKE REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]');
21
onedaywhen

Mir ist nichts bekannt, was Sie "out of the box" verwenden könnten - Sie müssen dies selbst schreiben, ich habe Angst.

Wenn Sie können: Versuchen Sie, dies in eine C # -Bibliothek zu schreiben und als SQL-CLR-Assembly in SQL Server bereitzustellen - dann könnten Sie Dinge wie Guid.TryParse() verwenden, die sicherlich viel einfacher zu verwenden sind als alles in T-SQL ....

4
marc_s

Eine Variante der Antwort von r0d30b0y ist die Verwendung von PATINDEX zum Suchen innerhalb eines Strings ...

PATINDEX('%'+REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]')+'%',@StringToCompare) > 0

Musste verwendet werden, um Guids in einer URL-Zeichenfolge zu finden.

HTH

Dave

2
Dave

Um es einfach zu halten. Ein GUID hat vier - sogar wenn es nur eine Zeichenkette ist

WHERE-Spalte wie '% -% -% -% -%'

1
Mike

Obwohl ein älterer Beitrag, nur ein Gedanke für einen schnellen Test ...

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
1
Geary M. McIver

Diese Funktion basiert auf dem Konzept einiger früherer Kommentare. Diese Funktion ist sehr schnell.

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!

*/
1
Ansonmus

Ich benutze :

ISNULL(convert(nvarchar(50), userID), 'NULL') = 'NULL'
0
Villie

Sie können Ihre eigene UDF schreiben. Dies ist eine einfache Annäherung, um die Verwendung einer SQL-CLR-Assembly zu vermeiden.

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

Sie können es dann verbessern, um zu prüfen, ob es sich nur um HEX-Werte handelt.

0
pcofre

Ich hatte einige Testbenutzer, die mit AutoFixture generiert wurden, das standardmäßig GUIDs für generierte Felder verwendet. Meine Vorname-Felder für die Benutzer, die ich löschen muss, sind GUIDs oder eindeutige Bezeichner. So bin ich hier gelandet.

Ich konnte einige Ihrer Antworten zusammenfassen.

SELECT UserId FROM [Membership].[UserInfo] Where TRY_CONVERT(uniqueidentifier, FirstName) is not null

0
Don Rolling

Verwenden Sie RLIKE für MySQL

SELECT 1 WHERE @StringToCompare
RLIKE REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]');
0
Pyotr Alexeev