Comment générer un GUID dans Oracle?

90

Est-il possible de générer automatiquement un GUID dans une instruction Insert?

De plus, quel type de champ dois-je utiliser pour stocker ce GUID?

Acibi
la source

Réponses:

139

Vous pouvez utiliser la fonction SYS_GUID () pour générer un GUID dans votre instruction d'insertion:

insert into mytable (guid_col, data) values (sys_guid(), 'xxx');

Le type de données préféré pour stocker les GUID est RAW (16).

Comme Gopinath répond:

 select sys_guid() from dual
 union all
 select sys_guid() from dual
 union all 
 select sys_guid() from dual

Vous obtenez

88FDC68C75DDF955E040449808B55601
88FDC68C75DEF955E040449808B55601
88FDC68C75DFF955E040449808B55601

Comme le dit Tony Andrews, ne diffère que d'un seul personnage

88FDC68C75D D F955E040449808B55601
88FDC68C75D E F955E040449808B55601
88FDC68C75D F F955E040449808B55601

Peut-être utile: http://feuerthoughts.blogspot.com/2006/02/watch-out-for-sequential-oracle-guids.html

Tony Andrews
la source
Bizarre, le sys_guid () me donne toujours le même GUID .. Dois-je donner une graine à la fonction ou?
Acibi
11
Etes-vous sûr qu'ils sont exactement les mêmes? Il a tendance à renvoyer des valeurs très similaires (mais différentes) - par exemple, lorsque je viens d'essayer, j'ai obtenu 88FDC68C75DEF955E040449808B55601 et 88FDC68C75DFF955E040449808B55601, qui ne diffèrent qu'au 12ème caractère!
Tony Andrews
Essayez de sélectionner sys_guid () à partir de dual et comparez les valeurs. Modifiez la réponse à ce sujet.
Kiquenet
26

Vous pouvez également inclure le guid dans l'instruction create de la table par défaut, par exemple:

create table t_sysguid
( id     raw(16) default sys_guid() primary key
, filler varchar2(1000)
)
/

Voir ici: http://rwijk.blogspot.com/2009/12/sysguid.html

TTT
la source
Merci de m'avoir signalé une fonctionnalité Oracle utile que je ne connaissais pas.
SteveT
7

Ce que vous entendez par générer automatiquement un guid dans une instruction d'insertion n'est pas clair, mais je pense que vous essayez de faire quelque chose comme ce qui suit:

INSERT INTO MY_TAB (ID, NAME) VALUES (SYS_GUID(), 'Adams');
INSERT INTO MY_TAB (ID, NAME) VALUES (SYS_GUID(), 'Baker');

Dans ce cas, je crois que la colonne ID doit être déclarée comme RAW (16);

Je fais ça du haut de ma tête. Je n'ai pas d'instance Oracle à portée de main pour tester, mais je pense que c'est ce que vous voulez.

Kenneth Baltrinic
la source
5

sys_guid () est une mauvaise option, comme l'ont mentionné d'autres réponses. Une façon de générer des UUID et d'éviter les valeurs séquentielles consiste à générer vous-même des chaînes hexadécimales aléatoires:

select regexp_replace(
    to_char(
        DBMS_RANDOM.value(0, power(2, 128)-1),
        'FM0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'),
    '([a-f0-9]{8})([a-f0-9]{4})([a-f0-9]{4})([a-f0-9]{4})([a-f0-9]{12})',
    '\1-\2-\3-\4-\5') from DUAL;
MikeWyatt
la source
4
Ceux-ci ne sont pas garantis pour être uniques. Vous devrez l'associer à quelque chose comme une contrainte unique sur l'endroit où vous le stockez, si vous le stockez. (et générer un nouveau nombre si vous rencontrez une valeur répétée et violez la contrainte d'unicité, aussi improbable que cela puisse être)
James Daily
2

Vous pouvez exécuter la requête suivante

 select sys_guid() from dual
 union all
 select sys_guid() from dual
 union all 
 select sys_guid() from dual
Gopinath Kotla
la source
2

vous pouvez utiliser la fonction ci-dessous pour générer votre UUID

create or replace FUNCTION RANDOM_GUID
    RETURN VARCHAR2 IS

    RNG    NUMBER;
    N      BINARY_INTEGER;
    CCS    VARCHAR2 (128);
    XSTR   VARCHAR2 (4000) := NULL;
  BEGIN
    CCS := '0123456789' || 'ABCDEF';
    RNG := 15;

    FOR I IN 1 .. 32 LOOP
      N := TRUNC (RNG * DBMS_RANDOM.VALUE) + 1;
      XSTR := XSTR || SUBSTR (CCS, N, 1);
    END LOOP;

    RETURN SUBSTR(XSTR, 1, 4) || '-' ||
        SUBSTR(XSTR, 5, 4)        || '-' ||
        SUBSTR(XSTR, 9, 4)        || '-' ||
        SUBSTR(XSTR, 13,4)        || '-' ||
        SUBSTR(XSTR, 17,4)        || '-' ||
        SUBSTR(XSTR, 21,4)        || '-' ||
        SUBSTR(XSTR, 24,4)        || '-' ||
        SUBSTR(XSTR, 28,4);
END RANDOM_GUID;

Exemple de GUID généré par la fonction ci - dessus:
8EA4-196D-BC48-9793-8AE8-5500-03DC-9D04

BERGUIGA Mohamed Amine
la source
SYS_GUID n'était pas assez aléatoire pour nos besoins, mais cela semble pomper des GUID qui sont beaucoup plus aléatoires.
ThePeter
1

Si vous avez besoin de guides non séquentiels, vous pouvez envoyer les sys_guid()résultats via une fonction de hachage (voir https://stackoverflow.com/a/22534843/1462295 ). L'idée est de conserver le caractère unique de la création originale et d'obtenir quelque chose avec plus de bits mélangés.

Par exemple:

LOWER(SUBSTR(STANDARD_HASH(SYS_GUID(), 'SHA1'), 0, 32))  

Exemple montrant le guid séquentiel par défaut vs l'envoyer via un hachage:

SELECT LOWER(SYS_GUID()) AS OGUID FROM DUAL
UNION ALL
SELECT LOWER(SYS_GUID()) AS OGUID FROM DUAL
UNION ALL
SELECT LOWER(SYS_GUID()) AS OGUID FROM DUAL
UNION ALL
SELECT LOWER(SYS_GUID()) AS OGUID FROM DUAL
UNION ALL
SELECT LOWER(SUBSTR(STANDARD_HASH(SYS_GUID(), 'SHA1'), 0, 32)) AS OGUID FROM DUAL
UNION ALL
SELECT LOWER(SUBSTR(STANDARD_HASH(SYS_GUID(), 'SHA1'), 0, 32)) AS OGUID FROM DUAL
UNION ALL
SELECT LOWER(SUBSTR(STANDARD_HASH(SYS_GUID(), 'SHA1'), 0, 32)) AS OGUID FROM DUAL
UNION ALL
SELECT LOWER(SUBSTR(STANDARD_HASH(SYS_GUID(), 'SHA1'), 0, 32)) AS OGUID FROM DUAL  

production

80c32a4fbe405707e0531e18980a1bbb
80c32a4fbe415707e0531e18980a1bbb
80c32a4fbe425707e0531e18980a1bbb
80c32a4fbe435707e0531e18980a1bbb
c0f2ff2d3ef7b422c302bd87a4588490
d1886a8f3b4c547c28b0805d70b384f3
a0c565f3008622dde3148cfce9353ba7
1c375f3311faab15dc6a7503ce08182c
BurnsBA
la source
0

Je recommanderais d'utiliser la fonction "dbms_crypto.randombytes" d'Oracle.

Pourquoi? Cette fonction renvoie une valeur RAW contenant une séquence pseudo-aléatoire d'octets cryptographiquement sécurisée, qui peut être utilisée pour générer du matériel aléatoire pour les clés de chiffrement.

select REGEXP_REPLACE(dbms_crypto.randombytes(16), '(.{8})(.{4})(.{4})(.{4})(.{12})', '\1-\2-\3-\4-\5') from dual;

Vous ne devez pas utiliser la fonction "sys_guid" si un seul caractère change.

ALTER TABLE locations ADD (uid_col RAW(16));

UPDATE locations SET uid_col = SYS_GUID();

SELECT location_id, uid_col FROM locations
   ORDER BY location_id, uid_col;

LOCATION_ID UID_COL
----------- ----------------------------------------------------------------
       1000 09F686761827CF8AE040578CB20B7491
       1100 09F686761828CF8AE040578CB20B7491
       1200 09F686761829CF8AE040578CB20B7491
       1300 09F68676182ACF8AE040578CB20B7491
       1400 09F68676182BCF8AE040578CB20B7491
       1500 09F68676182CCF8AE040578CB20B7491

https://docs.oracle.com/database/121/SQLRF/functions202.htm#SQLRF06120

Alex Fischer
la source