29

我想知道 Oracle 的 SYS_GUID() 函数是否返回符合 RFC 4122 的 UUID。例如:

SQL> select sys_guid() from dual;

SYS_GUID()
--------------------------------
A6C1BD5167C366C6E04400144FD25BA0

我知道,SYS_GUID() 返回一个 16 字节的 RAW 数据类型。Oracle 使用 RAWTOHEX() 和可能的 TO_CHAR() 打印出上述 ID。将其解释为符合 UUID 的字符串格式是否正确,例如:

A6C1BD51-67C3-66C6-E044-00144FD25BA0

我认为它不符合 RFC 4122 标准,因为定义说,有效的 UUID 必须在 UUID 本身内命名 UUID-Version。

符合 RFC 4122 的 UUID(版本 3)的语法:

xxxxxxxx-xxxx-3xxx-xxxx-xxxxxxxxxxxx
4

4 回答 4

26

如果你想要那种格式试试这个:

select regexp_replace(rawtohex(sys_guid())
       , '([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') 
         as FORMATTED_GUID 
 from dual

示例结果:

 FORMATTED_GUID                                                                  
 ------------------------------------
 F680233E-0FDD-00C4-E043-0A4059C654C9  
于 2012-06-05T14:35:23.177 回答
23

SYS_GUID 是 Oracle 的UUID等价物。它是全球独一无二的。但是,它不符合 RFC 4122;我从文档中(在 Java XML 文档之外)中没有对 UUID 的引用来推断缺乏合规性。

我怀疑 Oracle 没有原生实现 RFC 4122,因为他们认为它无法扩展。我无法想象为什么他们会发明自己的东西而不是遵守标准。

于 2011-06-29T03:19:20.360 回答
3

有了足够的权限,就可以让 Oracle 生成兼容的 UUID。

1.通过定义一个SQL函数

https://stackoverflow.com/a/13956771,您可以执行以下操作:

创建或替换函数 random_uuid 返回 RAW 是
  v_uuid RAW(16);
开始
  v_uuid := sys.dbms_crypto.randombytes(16);
  返回 (utl_raw.overlay(utl_raw.bit_or(utl_raw.bit_and(utl_raw.substr(v_uuid, 7, 1), '0F'), '40'), v_uuid, 7));
结束random_uuid;

该功能需要dbms_cryptoutl_raw。两者都需要执行授权。

grant execute on sys.dbms_crypto to uuid_user;

2. 使用 Java 过程

要创建用于创建兼容 UUID 的 Java 过程,请参阅https://stackoverflow.com/a/13951615

于 2016-02-08T16:40:34.617 回答
0

RFC 4122 § 3. 命名空间注册模板(第 5 页)

验证机制:
除了确定 UUID 的时间戳部分是否
在未来并因此无法分配之外,没有
确定 UUID 是否“有效”的机制。

生成过程决定了是否符合 RFC 4122,UUID本身只是一个 128 位的ID实体。

因此答案是肯定的,为什么不合规?UUID只是一个 128 位的通用唯一ID实体,规范的其余部分只是推荐的方法,以帮助您/Oracle 生成不与生成 UU ID 实体的其他系统冲突标识符。如果您或 Oracle 不想遵循他们的建议,他们可以自由地这样做。无论如何,您提供的 uuid 是“符合”RFC 4122 的,因为变量字段以位序列开头111这是“保留以供将来定义。”。该规范是过去编写的,并不限制谁可以指定“未来定义”,它当然不会阻止 Oracle 定义自己的变体……因此它是“合规的”……哈哈。

ps 我喜欢原作者对您的问题的预期,并在“有效”周围添加了讽刺引用。

于 2021-06-05T20:45:38.817 回答