Wie generiere ich eine GUID in Oracle?

88

Ist es möglich, eine GUID automatisch in eine Insert-Anweisung zu generieren?

Welche Art von Feld sollte ich zum Speichern dieser GUID verwenden?

Acibi
quelle

Antworten:

136

Mit der Funktion SYS_GUID () können Sie eine GUID in Ihrer insert-Anweisung generieren:

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

Der bevorzugte Datentyp zum Speichern von GUIDs ist RAW (16).

Als Antwort von Gopinath:

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

Du erhältst

88FDC68C75DDF955E040449808B55601
88FDC68C75DEF955E040449808B55601
88FDC68C75DFF955E040449808B55601

Wie Tony Andrews sagt, unterscheidet sich nur bei einem Charakter

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

Vielleicht nützlich: http://feuerehowts.blogspot.com/2006/02/watch-out-for-sequential-oracle-guids.html

Tony Andrews
quelle
Seltsam, die sys_guid () gibt mir immer die gleiche GUID. Muss ich der Funktion einen Startwert geben oder?
Acibi
10
Sind Sie sicher, dass sie genau gleich sind? Es gibt tendenziell sehr ähnliche (aber unterschiedliche) Werte zurück - z. B. als ich es gerade versuchte, bekam ich 88FDC68C75DEF955E040449808B55601 und 88FDC68C75DFF955E040449808B55601, die sich nur beim 12. Zeichen unterscheiden!
Tony Andrews
Versuchen Sie, sys_guid () aus dual auszuwählen und Werte zu vergleichen. Ändern Sie die Antwort dazu.
Kiquenet
26

Sie können die Guid auch standardmäßig in die create-Anweisung der Tabelle aufnehmen, zum Beispiel:

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

Siehe hier: http://rwijk.blogspot.com/2009/12/sysguid.html

TTT
quelle
Vielen Dank, dass Sie mich auf eine nützliche Oracle-Funktion aufmerksam gemacht haben, von der ich nichts wusste.
SteveT
7

Es ist nicht klar, was Sie unter automatischer Generierung einer Guid in eine Insert-Anweisung verstehen, aber ich denke, Sie versuchen, Folgendes zu tun:

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

In diesem Fall sollte die ID-Spalte meines Erachtens als RAW (16) deklariert werden.

Ich mache das auf Anhieb. Ich habe keine Oracle-Instanz zum Testen, aber ich denke, das ist es, was Sie wollen.

Kenneth Baltrinic
quelle
4

sys_guid () ist eine schlechte Option, wie andere Antworten erwähnt haben. Eine Möglichkeit, UUIDs zu generieren und sequentielle Werte zu vermeiden, besteht darin, zufällige Hex-Zeichenfolgen selbst zu generieren:

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
quelle
3
Diese sind garantiert nicht einzigartig. Sie müssten es mit so etwas wie einer einzigartigen Einschränkung koppeln, wo immer Sie es speichern, wenn Sie es speichern. (und Generieren einer neuen Nummer, wenn Sie auf einen wiederholten Wert stoßen und die eindeutige Einschränkung verletzen, wie unwahrscheinlich dies auch sein mag)
James Daily
2

Sie können die folgende Abfrage ausführen

 select sys_guid() from dual
 union all
 select sys_guid() from dual
 union all 
 select sys_guid() from dual
Gopinath Kotla
quelle
2

Sie können die folgende Funktion verwenden, um Ihre UUID zu generieren

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;

Beispiel einer GUID, die durch die obige Funktion erzeugt wurde:
8EA4-196D-BC48-9793-8AE8-5500-03DC-9D04

BERGUIGA Mohamed Amine
quelle
SYS_GUID war nicht zufällig genug für unsere Bedürfnisse, aber dies scheint GUIDs zu pumpen, die viel zufälliger sind.
ThePeter
1

Wenn Sie nicht sequentielle Hilfslinien benötigen, können Sie die sys_guid()Ergebnisse über eine Hashing-Funktion senden (siehe https://stackoverflow.com/a/22534843/1462295 ). Die Idee ist, die Einzigartigkeit der ursprünglichen Kreation beizubehalten und etwas mit mehr gemischten Teilen zu erhalten.

Zum Beispiel:

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

Beispiel für die standardmäßige sequentielle Anleitung im Vergleich zum Senden über einen 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  

Ausgabe

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

Ich würde empfehlen, die Oracle-Funktion "dbms_crypto.randombytes" zu verwenden.

Warum? Diese Funktion gibt einen RAW-Wert zurück, der eine kryptografisch sichere pseudozufällige Folge von Bytes enthält, mit der zufälliges Material für Verschlüsselungsschlüssel generiert werden kann.

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

Sie sollten die Funktion "sys_guid" nicht verwenden, wenn sich nur ein Zeichen ändert.

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
quelle