【问题标题】:How to generate a GUID in Oracle?如何在 Oracle 中生成 GUID?
【发布时间】:2011-03-03 12:31:04
【问题描述】:

是否可以在插入语句中自动生成 GUID?

另外,我应该使用什么类型的字段来存储这个 GUID?

【问题讨论】:

    标签: oracle guid


    【解决方案1】:

    您可以使用 SYS_GUID() 函数在插入语句中生成 GUID:

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

    存储 GUID 的首选数据类型是 RAW(16)。

    作为 Gopinath 的回答:

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

    你得到

    88FDC68C75DDF955E040449808B55601
    88FDC68C75DEF955E040449808B55601
    88FDC68C75DFF955E040449808B55601

    正如托尼·安德鲁斯所说,只有一个角色不同

    88FDC68C75DDF955E040449808B55601
    88FDC68C75DEF955E040449808B55601
    88FDC68C75DFF955E040449808B55601

    也许有用:http://feuerthoughts.blogspot.com/2006/02/watch-out-for-sequential-oracle-guids.html

    【讨论】:

    • 很奇怪,sys_guid() 总是给我相同的 GUID。我需要给这个函数一个种子吗?
    • 你确定它们完全一样吗?它确实倾向于返回非常相似(但不同)的值 - 例如当我刚刚尝试时,我得到了 88FDC68C75DEF955E040449808B55601 和 88FDC68C75DFF955E040449808B55601,它们仅在第 12 个字符处有所不同!
    • 尝试从对偶中选择 sys_guid() 并比较值。修改答案。
    【解决方案2】:

    不清楚您所说的在插入语句中自动生成 guid 是什么意思,但我猜测,我认为您正在尝试执行以下操作:

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

    在这种情况下,我认为应该将 ID 列声明为 RAW(16);

    我正在做这件事。我没有方便测试的 Oracle 实例,但我认为这就是您想要的。

    【讨论】:

      【解决方案3】:

      您也可以在表的create语句中包含guid作为默认值,例如:

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

      请看这里:http://rwijk.blogspot.com/2009/12/sysguid.html

      【讨论】:

      • 感谢您提醒我注意一个我不知道的有用的 Oracle 功能。
      【解决方案4】:

      您可以运行以下查询

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

      【讨论】:

        【解决方案5】:

        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;
        

        【讨论】:

        • 不保证是唯一的。如果要存储它,则需要将其与存储位置的唯一约束之类的东西配对。 (如果遇到重复值并违反唯一约束,则会生成一个新数字,但这种情况不太可能发生)
        【解决方案6】:

        你可以使用下面的函数来生成你的 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。
        【解决方案7】:

        在以下位置找到示例: http://www.orafaq.com/usenet/comp.databases.oracle.server/2006/12/20/0646.htm

        SELECT REGEXP_REPLACE(SYS_GUID(), '(.{8})(.{4})(.{4})(.{4})(.{12})', '\1-\2-\3-\4-\5') MSSQL_GUID  FROM DUAL 
        

        结果:

        6C7C9A50-3514-4E77-E053-B30210AC1082 
        

        【讨论】:

        • 希望我能为此请你喝一杯。 +1
        • 太棒了!谢谢你:)
        【解决方案8】:

        如果您需要非顺序 guid,您可以通过散列函数发送 sys_guid() 结果(请参阅 https://stackoverflow.com/a/22534843/1462295 )。这个想法是保留原始创作中使用的任何唯一性,并获得更多混洗位的东西。

        例如:

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

        显示默认顺序 guid 与通过哈希发送它的示例:

        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
        

        【讨论】:

          【解决方案9】:

          我建议使用 Oracle 的“dbms_crypto.randombytes”函数。

          为什么?
          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;
          

          您应该使用函数“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

          【讨论】:

            【解决方案10】:

            创建一个 350 个字符的 GUID:

            dbms_random.STRING ('a', 350) - 以混合大小写的字母字符返回字符串

            dbms_random.STRING ('x', 350) - 以大写字母数字字符返回字符串

            【讨论】:

              猜你喜欢
              • 2017-10-19
              • 2012-05-16
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-12-25
              • 2012-03-02
              • 1970-01-01
              • 2011-07-26
              相关资源
              最近更新 更多