How to generate a GUID in Oracle?

前端 未结 9 582
悲哀的现实
悲哀的现实 2020-12-04 10:49

Is it possible to auto-generate a GUID into an Insert statement?

Also, what type of field should I use to store this GUID?

相关标签:
9条回答
  • 2020-12-04 11:03

    sys_guid() is a poor option, as other answers have mentioned. One way to generate UUIDs and avoid sequential values is to generate random hex strings yourself:

    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;
    
    0 讨论(0)
  • 2020-12-04 11:11

    You can use the SYS_GUID() function to generate a GUID in your insert statement:

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

    The preferred datatype for storing GUIDs is RAW(16).

    As Gopinath answer:

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

    You get

    88FDC68C75DDF955E040449808B55601
    88FDC68C75DEF955E040449808B55601
    88FDC68C75DFF955E040449808B55601

    As Tony Andrews says, differs only at one character

    88FDC68C75DDF955E040449808B55601
    88FDC68C75DEF955E040449808B55601
    88FDC68C75DFF955E040449808B55601

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

    0 讨论(0)
  • 2020-12-04 11:15

    If you need non-sequential guids you can send the sys_guid() results through a hashing function (see https://stackoverflow.com/a/22534843/1462295 ). The idea is to keep whatever uniqueness is used from the original creation, and get something with more shuffled bits.

    For instance:

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

    Example showing default sequential guid vs sending it through a 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  
    

    output

    80c32a4fbe405707e0531e18980a1bbb
    80c32a4fbe415707e0531e18980a1bbb
    80c32a4fbe425707e0531e18980a1bbb
    80c32a4fbe435707e0531e18980a1bbb
    c0f2ff2d3ef7b422c302bd87a4588490
    d1886a8f3b4c547c28b0805d70b384f3
    a0c565f3008622dde3148cfce9353ba7
    1c375f3311faab15dc6a7503ce08182c
    
    0 讨论(0)
  • 2020-12-04 11:17

    you can use function bellow in order to generate your 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;
    

    Example of GUID genedrated by the function above:
    8EA4-196D-BC48-9793-8AE8-5500-03DC-9D04

    0 讨论(0)
  • 2020-12-04 11:18

    I would recommend using Oracle's "dbms_crypto.randombytes" function.

    Why? This function returns a RAW value containing a cryptographically secure pseudo-random sequence of bytes, which can be used to generate random material for encryption keys.

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

    You shold not use the function "sys_guid" if only one character changes.

    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

    0 讨论(0)
  • 2020-12-04 11:20

    You can also include the guid in the create statement of the table as default, for example:

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

    See here: http://rwijk.blogspot.com/2009/12/sysguid.html

    0 讨论(0)
提交回复
热议问题