2011-01-10 12 views
41

Czy istnieje odpowiednik IsDate lub IsNumeric dla uniqueidentifier (SQL Server)? Czy istnieje coś podobnego do (C#) TryParse?Jak sprawdzić, czy ciąg znaków jest unikalnym identyfikatorem?

W przeciwnym razie będę musiał napisać własną funkcję, ale chcę się upewnić, że nie odkrywam koła.

Scenariusz Próbuję pokrycie jest następujący:

SELECT something FROM table WHERE IsUniqueidentifier(column) = 1 
+1

Nie rozumiem co masz próbując osiągnąć. Chcesz zaznaczyć wszystkie wiersze, w których wartość dla konkretnej kolumny jest unikalnym identyfikatorem? Jaki scenariusz biznesowy? A jeśli kolumna ma zawierać unikatowy identyfikator, czy jego wartość nie będzie miała wartości zerowej, czy też będzie unikalnym identyfikatorem? Cóż innego mogło być? –

+0

Tworzę bazy danych przy użyciu identyfikatorów dla nazw (testy integracyjne na serwerze kompilacji). Chciałem wymienić te bazy danych (wybierz * z sys.databases gdzie IsUniqueidentifier (name)) – Benoittr

+0

Ach, rozumiem - nie masz na myśli unikalnego typu danych, tylko ciąg znaków. –

Odpowiedz

38

SQL Server 2012 sprawia, że ​​to wszystko o wiele łatwiej z TRY_CONVERT(UNIQUEIDENTIFIER, expression)

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

Na wcześniejszych wersjach SQL Server, istniejące odpowiedzi przegap kilka punktów, które oznaczają mogą albo nie pasuje do ciągów SQL Server w rzeczywistości odlewane do UNIQUEIDENTIFIER bez reklamacji lub nadal mogą skutkować nieprawidłowymi błędami rzutu.

Serwer SQL akceptuje identyfikatory GUID zapakowane w {} lub bez tego.

Dodatkowo ignoruje nieistotne znaki na końcu łańcucha. Zarówno SELECT CAST('{5D944516-98E6-44C5-849F-9C277833C01B}ssssssssss' as uniqueidentifier), jak i SELECT CAST('5D944516-98E6-44C5-849F-9C277833C01BXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' as uniqueidentifier) odnoszą sukces na przykład.

W większości domyślnych ustawień sortowania LIKE '[a-zA-Z0-9]' skończy się pasujące znaki takie jak À lub Ë

Wreszcie jeśli odlewania wierszy w rezultacie do uniqueidentifier ważne jest, aby umieścić próbę rzucania w sprawie wyrażenia, jakie mogą pojawić się obsada zanim wiersze zostaną przefiltrowane przez WHERE.

Tak (pożyczanie @r0d30b0y's idea) nieco bardziej wytrzymała wersja może być

;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 + '}%' 
+0

Oznaczono tę odpowiedź jako przyjęte, ponieważ SQL Server 2012 adresu mojego pierwotnego pytania całkiem dobrze. – Benoittr

+4

miał tylko jeden z momentów Były widząc odpowiedź na StackOverflow made my day. Jakoś nie widziałem TRY_CONVERT który istniał. –

+2

Jest też [ 'TRY_CAST'] (https://msdn.microsoft.com/en-us/library/hh974669.aspx), jeśli nie trzeba argumentu styl. [ 'TRY_PARSE'] (https://msdn.microsoft.com/en-us/library/hh213126.aspx) nie support' uniqueidentifier' wiedzą, że nie muszą być brane pod uwagę. – Trisped

4

nie jestem świadomy wszystkiego, co można wykorzystać „out of the box” - musisz napisać to na własną rękę , Obawiam się.

Jeśli możesz: spróbuj napisać to wewnątrz biblioteki C# i wdrożyć ją na serwerze SQL jako zespół SQL-CLR - możesz użyć rzeczy takich jak Guid.TryParse(), która jest z pewnością znacznie łatwiejsza w użyciu niż cokolwiek w T-SQL. ...

0

Możesz napisać własny UDF. Jest to prosta aproksymacja, aby uniknąć użycia zestawu 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 

Następnie można go poprawić, aby sprawdzić, czy chodzi tylko o wartości HEX.

+8

Twoja funkcja uważa, że ​​'------------------------------------' jest unikalnym identyfikatorem;) – onedaywhen

+0

Ty mogłyby połączyć to z odpowiedzią onedaywhen za:. 'Tworzenie FUNCTION [dbo] [IsAGuid] (@Data varchar (50)) zwraca nieco z SCHEMABINDING AS \t \t BEGIN \t \t \t przypadek powrotu \t \t \t \t gdy jest @Data jak ' [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]” \t \t \t \t następnie 1 \t \t \t \t else 0 end \t \t END' – andes

21
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]'; 

UPDATE:

... ale wolę podejście w odpowiedzi przez @ r0d30b0y:

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

Można przekształcić funkcji, jak pcofre proponuje:' Tworzenie FUNKCJA [dbo].[IsAGuid] (@Data VARCHAR (50)) powraca z SCHEMABINDING wiertła, POCZĄTEK \t \t \t \t \t powrót do domu \t \t \t \t Gdy @Data jak „[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 -to-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] „ \t \t \t \t następnie \t \t \t indziej 0 końca \t \t END' – andes

51

nie moja, znalazł Online ... myślałem, że dzielić .

SELECT 1 WHERE @StringToCompare LIKE 
     REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]'); 
+3

Nice one, jednak te wszystkie zera może doprowadzić do typo że trudno wyśledzić :). IMHO, jest tu niewielka poprawa na pomysł ubezpieczającego format pustym uniqueidentifier jest poprawna: 'SELECT 1, gdzie @StringToCompare LIKE Wymienić (wylewane (wylewane (0 binarne), jak uniqueidentifier), '0',„[ 0-9a-fA-F] „); –

+4

' Jak dokładnie to działa? – MAW74656

2

Wariant r0d30b0y odpowiedź jest użycie PATINDEX znaleźć w ciąg ...

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

musiałem użyć, aby znaleźć GUID ciągu znaków URL ..

HTH

Dave

0

używam:

ISNULL(convert(nvarchar(50), userID), 'NULL') = 'NULL' 
1

Jest to funkcja opiera się na koncepcja niektórych wcześniejszych komentarzy. Ta funkcja jest bardzo szybka.

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! 

*/ 
2

Lubisz to proste. Identyfikator GUID ma cztery - w tym nawet, jeśli to tylko ciąg

WHERE kolumna like „% -% -% -% -%”

+0

„Ja siałem 100-200 niezapominajka niezapominajki Zamiejscowy” jest moim ulubionym GUID – buckminst

0

miałem pewne użytkowników testów, które zostały wygenerowane z AutoFixture, który wykorzystuje GUID domyślnie dla wygenerowanych pól. Moje pola FirstName dla użytkowników, których muszę usunąć, to GUID lub uniqueidentifiers. Tak tu trafiłem.

Udało mi się połączyć niektóre z twoich odpowiedzi w to.

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

1

Choć starszego postu, tylko myśl o szybkim teście ...

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 
0

Zastosowanie RLIKE MySQL

SELECT 1 WHERE @StringToCompare 
RLIKE REPLACE('00000000-0000-0000-0000-000000000000', '0', '[0-9a-fA-F]'); 
Powiązane problemy