Як створити GUID в Oracle?


89

Чи можна автоматично згенерувати GUID в операторі Insert?

Крім того, який тип поля я повинен використовувати для зберігання цього GUID?

Відповіді:


138

Ви можете використовувати функцію SYS_GUID (), щоб сформувати GUID у своєму операторі вставки:

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

Переважним типом даних для зберігання GUID є RAW (16).

Як відповідь Гопінатх:

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

Ти отримуєш

88FDC68C75DDF955E040449808B55601
88FDC68C75DEF955E040449808B55601
88FDC68C75DFF955E040449808B55601

Як каже Тоні Ендрюс, відрізняється лише одним персонажем

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

Можливо, корисно: http://feueroughts.blogspot.com/2006/02/watch-out-for-sequential-oracle-guids.html


Дивно, sys_guid () завжди надає мені однаковий GUID .. Чи потрібно мені надавати насіння функції або?
Acibi

10
Ви впевнені, що вони абсолютно однакові? Він, як правило, повертає дуже схожі (але різні) значення - наприклад, коли я щойно спробував, я отримав 88FDC68C75DEF955E040449808B55601 та 88FDC68C75DFF955E040449808B55601, які відрізняються лише на 12-му символі!
Тоні Ендрюс

Спробуйте вибрати sys_guid () із подвійного та порівняти значення. Змінити відповідь про це.
Kiquenet

26

Ви також можете включити керівництво в оператор create таблиці за замовчуванням, наприклад:

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

Дивіться тут: http://rwijk.blogspot.com/2009/12/sysguid.html


Дякуємо за попередження про корисну функцію Oracle, про яку я не знав.
SteveT

7

Незрозуміло, що ви маєте на увазі під автоматичним створенням керівництва в операторі вставки, але, на думку, я думаю, ви намагаєтесь зробити щось на зразок наступного:

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

У такому випадку я вважаю, що стовпець ID слід оголосити як RAW (16);

Я роблю це з маківки. У мене немає екземпляра Oracle, який зручно тестувати, але я думаю, що це те, що ви хочете.



4

sys_guid () - поганий варіант, як зазначалося в інших відповідях. Один із способів генерувати UUID і уникати послідовних значень - це генерувати випадкові шістнадцяткові рядки самостійно:

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
Вони не гарантовано будуть унікальними. Вам потрібно буде поєднати його з чимось на зразок унікального обмеження, де б ви його не зберігали, якщо ви його зберігаєте. (і генерування нового числа, якщо ви зіткнетеся з повторюваним значенням і порушите унікальне обмеження, хоч це й малоймовірно)
James Daily

2

Ви можете запустити наступний запит

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

2

Ви можете використовувати наведену нижче функцію для того, щоб створити свій 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;

Приклад GUID, сформований наведеною вище функцією:
8EA4-196D-BC48-9793-8AE8-5500-03DC-9D04


SYS_GUID не був достатньо випадковим для наших потреб, але, схоже, це накачує GUID, які є набагато випадковішими.
ThePeter

1

Якщо вам потрібні не послідовні вказівки, ви можете надіслати sys_guid()результати за допомогою функції хешування (див. Https://stackoverflow.com/a/22534843/1462295 ). Ідея полягає в тому, щоб зберегти будь-яку унікальність, яка використовується в оригінальному творінні, і отримати щось із більшою кількістю перетасованих бітів.

Наприклад:

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

Приклад, що показує послідовне керівництво за замовчуванням проти відправлення його через хеш:

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  

вихід

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

0

Я б рекомендував використовувати функцію Oracle "dbms_crypto.randombytes".

Чому? Ця функція повертає значення RAW, що містить криптографічно захищену псевдовипадкову послідовність байтів, яку можна використовувати для генерації випадкового матеріалу для ключів шифрування.

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

Ви не повинні використовувати функцію "sys_guid", якщо змінюється лише один символ.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.