Bagaimana cara menghasilkan GUID di Oracle?

91

Apakah mungkin untuk membuat GUID secara otomatis ke dalam pernyataan Sisipkan?

Selain itu, jenis bidang apa yang harus saya gunakan untuk menyimpan GUID ini?

Acibi
sumber

Jawaban:

140

Anda dapat menggunakan fungsi SYS_GUID () untuk menghasilkan GUID dalam pernyataan penyisipan Anda:

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

Jenis data yang disukai untuk menyimpan GUID adalah RAW (16).

Seperti jawaban Gopinath:

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

Anda mendapatkan

88FDC68C75DDF955E040449808B55601
88FDC68C75DEF955E040449808B55601
88FDC68C75DFF955E040449808B55601

Seperti yang dikatakan Tony Andrews, hanya berbeda pada satu karakter

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

Mungkin berguna: http://feuerthoughts.blogspot.com/2006/02/watch-out-for-sequential-oracle-guids.html

Tony Andrews
sumber
Anehnya, sys_guid () selalu memberi saya GUID yang sama .. Apakah saya perlu memberi seed pada fungsi tersebut atau?
Acibi
11
Apakah Anda yakin mereka persis sama? Itu cenderung mengembalikan nilai yang sangat mirip (tetapi berbeda) - misalnya ketika saya baru mencoba, saya mendapat 88FDC68C75DEF955E040449808B55601 dan 88FDC68C75DFF955E040449808B55601, yang hanya berbeda pada karakter ke-12!
Tony Andrews
Coba pilih sys_guid () dari ganda dan bandingkan nilainya. Ubah jawaban tentang itu.
Kiquenet
26

Anda juga bisa memasukkan guid dalam pernyataan create dari tabel sebagai default, misalnya:

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

Lihat di sini: http://rwijk.blogspot.com/2009/12/sysguid.html

TTT
sumber
Terima kasih telah memberi tahu saya tentang fitur Oracle berguna yang tidak saya ketahui.
SteveT
7

Tidak jelas apa yang Anda maksud dengan menghasilkan panduan secara otomatis ke dalam pernyataan penyisipan tetapi dengan tebakan, saya pikir Anda mencoba melakukan sesuatu seperti berikut:

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

Dalam hal ini saya yakin kolom ID harus dinyatakan sebagai RAW (16);

Saya melakukan ini di luar kepala saya. Saya tidak memiliki contoh Oracle yang dapat digunakan untuk diuji, tetapi saya pikir itulah yang Anda inginkan.

Kenneth Baltrinic
sumber
5

sys_guid () adalah opsi yang buruk, seperti yang disebutkan oleh jawaban lain. Salah satu cara untuk menghasilkan UUID dan menghindari nilai berurutan adalah dengan membuat sendiri string hex acak:

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
sumber
4
Itu tidak dijamin unik. Anda perlu memasangkannya dengan sesuatu seperti batasan unik di mana pun Anda menyimpannya, jika Anda menyimpannya. (dan menghasilkan angka baru jika Anda menemukan nilai berulang dan melanggar batasan unik, betapapun kecil kemungkinannya)
James Daily
2

Anda dapat menjalankan kueri berikut

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

Anda dapat menggunakan fungsi di bawah untuk menghasilkan UUID Anda

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;

Contoh GUID yang dihasilkan oleh fungsi di atas:
8EA4-196D-BC48-9793-8AE8-5500-03DC-9D04

BERGUIGA Mohamed Amine
sumber
SYS_GUID tidak cukup acak untuk kebutuhan kita, tetapi ini tampaknya memompa GUID yang jauh lebih acak.
ThePeter
1

Jika Anda membutuhkan panduan yang tidak berurutan, Anda dapat mengirimkan sys_guid()hasilnya melalui fungsi hashing (lihat https://stackoverflow.com/a/22534843/1462295 ). Idenya adalah untuk menjaga keunikan apa pun yang digunakan dari kreasi asli, dan mendapatkan sesuatu dengan lebih banyak bit yang diacak.

Contohnya:

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

Contoh yang menampilkan panduan berurutan default vs mengirimkannya melalui 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  

keluaran

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

Saya akan merekomendasikan menggunakan fungsi "dbms_crypto.randombytes" Oracle.

Mengapa? Fungsi ini mengembalikan nilai RAW yang berisi urutan byte acak-semu yang aman secara kriptografis, yang dapat digunakan untuk menghasilkan materi acak untuk kunci enkripsi.

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

Anda sebaiknya tidak menggunakan fungsi "sys_guid" jika hanya satu karakter yang berubah.

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
sumber