Come generare un GUID in Oracle?


89

È possibile generare automaticamente un GUID in un'istruzione Insert?

Inoltre, che tipo di campo dovrei usare per memorizzare questo GUID?

Risposte:


138

È possibile utilizzare la funzione SYS_GUID () per generare un GUID nell'istruzione di inserimento:

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

Il tipo di dati preferito per la memorizzazione dei GUID è RAW (16).

Come risponde Gopinath:

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

Ottieni

88FDC68C75DDF955E040449808B55601
88FDC68C75DEF955E040449808B55601
88FDC68C75DFF955E040449808B55601

Come dice Tony Andrews, differisce solo per un personaggio

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

Forse utile: http : //feuer Thoughts.blogspot.com/2006/02/watch-out-for-sequential-oracle-guids.html


Strano, sys_guid () mi dà sempre lo stesso GUID .. Devo dare un seme alla funzione o?
Acibi

10
Sei sicuro che siano esattamente gli stessi? Tende a restituire valori molto simili (ma diversi) - ad esempio, quando ho appena provato ho ottenuto 88FDC68C75DEF955E040449808B55601 e 88FDC68C75DFF955E040449808B55601, che differiscono solo al 12 ° carattere!
Tony Andrews

Prova a selezionare sys_guid () da dual e confronta i valori. Modifica la risposta a riguardo.
Kiquenet

26

Puoi anche includere il guid nell'istruzione create della tabella come predefinito, ad esempio:

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

Vedi qui: http://rwijk.blogspot.com/2009/12/sysguid.html


Grazie per avermi avvisato di un'utile funzione Oracle di cui non ero a conoscenza.
SteveT

7

Non è chiaro cosa intendi per generazione automatica di una GUID in un'istruzione di inserimento, ma a prima vista, penso che tu stia cercando di fare qualcosa di simile:

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

In tal caso credo che la colonna ID debba essere dichiarata RAW (16);

Lo sto facendo dalla parte superiore della mia testa. Non ho un'istanza Oracle a portata di mano su cui testare, ma penso che sia quello che vuoi.



4

sys_guid () è un'opzione scadente, come hanno menzionato altre risposte. Un modo per generare UUID ed evitare valori sequenziali è generare da soli stringhe esadecimali casuali:

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;

3
Non è garantito che siano unici. Dovresti accoppiarlo con qualcosa come un vincolo unico su dove lo stai memorizzando, se lo stai memorizzando. (e generare un nuovo numero se incontri un valore ripetuto e violi il vincolo univoco, per quanto improbabile possa essere)
James Daily

2

È possibile eseguire la seguente query

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

2

puoi usare la funzione qui sotto per generare il tuo 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;

Esempio di GUID generato dalla funzione sopra:
8EA4-196D-BC48-9793-8AE8-5500-03DC-9D04


SYS_GUID non era abbastanza casuale per le nostre esigenze, ma questo sembra pompare GUID che sono molto più casuali.
ThePeter

1

Se hai bisogno di guide non sequenziali puoi inviare i sys_guid()risultati tramite una funzione di hashing (vedi https://stackoverflow.com/a/22534843/1462295 ). L'idea è di mantenere qualsiasi unicità venga utilizzata dalla creazione originale e ottenere qualcosa con più pezzi mescolati.

Per esempio:

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

Esempio che mostra il guid sequenziale predefinito rispetto all'invio tramite un hash:

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  

produzione

80c32a4fbe405707e0531e18980a1bbb
80c32a4fbe415707e0531e18980a1bbb
80c32a4fbe425707e0531e18980a1bbb
80c32a4fbe435707e0531e18980a1bbb
c0f2ff2d3ef7b422c302bd87a4588490
d1886a8f3b4c547c28b0805d70b384f3
a0c565f3008622dde3148cfce9353ba7
1c375f3311faab15dc6a7503ce08182c

0

Suggerirei di utilizzare la funzione "dbms_crypto.randombytes" di Oracle.

Perché? Questa funzione restituisce un valore RAW contenente una sequenza di byte pseudo-casuale crittograficamente sicura, che può essere utilizzata per generare materiale casuale per le chiavi di crittografia.

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

È necessario non utilizzare la funzione "sys_guid" se cambia solo un carattere.

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

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.