Converti varchar in uniqueidentifier in SQL Server


104

Una tabella per la quale non ho il controllo dello schema, contiene una colonna definita come varchar (50) che memorizza identificatori univoci nel formato "a89b1acd95016ae6b9c8aabb07da2010" (senza trattini)

Voglio convertirli in identificatori univoci in SQL per passare a un .Net Guid. Tuttavia, le seguenti righe di query non funzionano per me:

select cast('a89b1acd95016ae6b9c8aabb07da2010' as uniqueidentifier)
select convert(uniqueidentifier, 'a89b1acd95016ae6b9c8aabb07da2010')

e risultato in:

Msg 8169, livello 16, stato 2, riga 1
Conversione non riuscita durante la conversione da una stringa di caratteri a uniqueidentifier.

Le stesse query che utilizzano un identificatore univoco con trattino funzionano bene ma i dati non vengono memorizzati in quel formato.

Esiste un altro modo (efficiente) per convertire queste stringhe in identificatori univoci in SQL. - Non voglio farlo nel codice .Net.


solo una riga di caratteri e numeri non è davvero una rappresentazione GUID valida: dovrai ricorrere alla magia di analisi delle stringhe come Quassnoi ha mostrato nella sua risposta.
marc_s

Risposte:


126
DECLARE @uuid VARCHAR(50)
SET @uuid = 'a89b1acd95016ae6b9c8aabb07da2010'
SELECT  CAST(
        SUBSTRING(@uuid, 1, 8) + '-' + SUBSTRING(@uuid, 9, 4) + '-' + SUBSTRING(@uuid, 13, 4) + '-' +
        SUBSTRING(@uuid, 17, 4) + '-' + SUBSTRING(@uuid, 21, 12)
        AS UNIQUEIDENTIFIER)

10
Speravo davvero che questa non fosse la soluzione, ma immagino che lo scopriremo presto ...
granata

22
DECLARE @u uniqueidentifier SELECT @u = CONVERT (uniqueidentifier, 'c029f8be-29dc-41c1-8b38-737b4cc5a4df') *** Sarebbe sufficiente. L'ho appena provato.
Fabio Milheiro

Oh si! Allora devo essere d'accordo. La cosa ovvia è mettere i trattini al posto giusto e sei pronto per partire! Scusa!
Fabio Milheiro

Posizionare questo frammento in una funzione è una bella aggiunta al tuo toolkit, soprattutto perché alcuni serializzatori JSON rimuovono i trattini dai GUID durante la serializzazione, rendendo più difficile copiare incolla in SQL per il debug.
David Cumps

27

Sarebbe una funzione utile. Inoltre, nota che sto usando STUFF invece di SUBSTRING.

create function str2uniq(@s varchar(50)) returns uniqueidentifier as begin
    -- just in case it came in with 0x prefix or dashes...
    set @s = replace(replace(@s,'0x',''),'-','')
    -- inject dashes in the right places
    set @s = stuff(stuff(stuff(stuff(@s,21,0,'-'),17,0,'-'),13,0,'-'),9,0,'-')
    return cast(@s as uniqueidentifier)
end

4
Ottimo uso di Stuff (). Devo fare riferimento al mio campo solo una volta in un'istruzione Select utilizzando il tuo metodo. Evito però le funzioni scalari, perché non sempre "scalano" bene, quindi le scrivo. Grazie, questo sta andando nei miei frammenti di codice!
MikeTeeVee

18

il tuo varchar col C:

SELECT CONVERT(uniqueidentifier,LEFT(C, 8)
                                + '-' +RIGHT(LEFT(C, 12), 4)
                                + '-' +RIGHT(LEFT(C, 16), 4)
                                + '-' +RIGHT(LEFT(C, 20), 4)
                                + '-' +RIGHT(C, 12))

10
SELECT CONVERT(uniqueidentifier,STUFF(STUFF(STUFF(STUFF('B33D42A3AC5A4D4C81DD72F3D5C49025',9,0,'-'),14,0,'-'),19,0,'-'),24,0,'-'))

-4

Se la stringa contiene caratteri speciali, è possibile eseguirne l'hashing in md5 e quindi convertirla in un guid / uniqueidentifier.

SELECT CONVERT(UNIQUEIDENTIFIER, HASHBYTES('MD5','~öü߀a89b1acd95016ae6b9c8aabb07da2010'))

8
Questo converte la stringa di input in un GUID completamente diverso
Aaroninus

-6

Il formato GUID fornito non è corretto (.net fornito guid).

begin try
select convert(uniqueidentifier,'a89b1acd95016ae6b9c8aabb07da2010')
end try
begin catch
print '1'
end catch

6
Come risponde questo alla domanda di convertire un varchar senza trattini in un GUID? Tutto ciò che questo codice fa è stampare 1.
Aaroninus
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.