Convertir varchar en uniqueidentifier dans SQL Server


104

Une table pour laquelle je n'ai aucun contrôle sur le schéma contient une colonne définie comme varchar (50) qui stocke les identificateurs uniques au format 'a89b1acd95016ae6b9c8aabb07da2010' (pas de tirets)

Je veux les convertir en identificateurs uniques en SQL pour les passer à un .Net Guid. Cependant, les lignes de requête suivantes ne fonctionnent pas pour moi:

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

et aboutir à:

Msg 8169, niveau 16, état 2, ligne 1
La conversion a échoué lors de la conversion d'une chaîne de caractères en uniqueidentifier.

Les mêmes requêtes utilisant un identificateur unique avec trait d'union fonctionnent correctement, mais les données ne sont pas stockées dans ce format.

Existe-t-il un autre moyen (efficace) de convertir ces chaînes en identificateurs uniques en SQL. - Je ne veux pas le faire dans le code .Net.


juste une rangée de caractères et de nombres n'est vraiment pas une représentation GUID valide - vous devrez recourir à la magie d'analyse des chaînes comme Quassnoi l'a montré dans sa réponse.
marc_s

Réponses:


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
J'espérais vraiment que ce ne serait pas la solution mais je suppose que nous le saurons bientôt ...
grenade

22
DECLARE @u uniqueidentifier SELECT @u = CONVERT (uniqueidentifier, 'c029f8be-29dc-41c1-8b38-737b4cc5a4df') *** Ce serait suffisant. Juste essayé.
Fabio Milheiro le

Oh oui! Ensuite, je dois être d'accord. La chose évidente est de mettre les tirets aux bons endroits et vous êtes prêt à partir! Désolé!
Fabio Milheiro le

Placer cet extrait de code dans une fonction est un ajout intéressant à votre boîte à outils, d'autant plus que certains sérialiseurs JSON suppriment les tirets des GUID lors de la sérialisation, ce qui rend plus difficile le copier-coller dans SQL pour déboguer.
David Cumps

27

Cela ferait une fonction pratique. Notez également que j'utilise STUFF au lieu de 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
Excellente utilisation de Stuff (). Je n'ai besoin de référencer mon champ qu'une seule fois dans une instruction Select en utilisant votre méthode. J'évite cependant les fonctions scalaires, car elles ne se "mettent pas toujours à l'échelle" bien, alors je l'écris. Merci, cela se passe dans mes extraits de code!
MikeTeeVee

18

votre 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

Si votre chaîne contient des caractères spéciaux, vous pouvez la hacher en md5, puis la convertir en guid / uniqueidentifier.

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

8
Cela convertit la chaîne d'entrée en un GUID complètement différent
Aaroninus

-6

Le guide fourni n'est pas au format correct (.net fourni guid).

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

6
Comment cela répond-il à la question de la conversion d'un varchar sans traits d'union en GUID? Tout ce que ce code fait, c'est imprimer 1.
Aaroninus
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.