我想知道Oracle的SYS_GUID()函数是否返回a RFC 4122 compliant 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
答案 0 :(得分:22)
如果您想要这种格式,请尝试以下方法:
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
答案 1 :(得分:19)
SYS_GUID是Oracle的等效的UUID。它是全球独一无二的。但是,它不符合RFC 4122;由于文档中没有对UUID的引用(Java XML文档之外),我推断缺乏合规性。
我怀疑Oracle本身没有实现RFC 4122,因为他们认为它不会扩展。我无法想象为什么他们会发明自己的东西,而不是遵守标准。
答案 2 :(得分:2)
如果拥有足够的权限,Oracle可以生成符合规范的UUID。
<强> 1。通过定义SQL函数
从https://stackoverflow.com/a/13956771,您可以执行以下操作:
create or replace function random_uuid return RAW is v_uuid RAW(16); begin v_uuid := sys.dbms_crypto.randombytes(16); return (utl_raw.overlay(utl_raw.bit_or(utl_raw.bit_and(utl_raw.substr(v_uuid, 7, 1), '0F'), '40'), v_uuid, 7)); end random_uuid;
该功能需要dbms_crypto
和utl_raw
。两者都需要执行授权。
grant execute on sys.dbms_crypto to uuid_user;
<强> 2。使用Java过程
要创建用于创建合规UUID的Java过程,请参阅https://stackoverflow.com/a/13951615。
答案 3 :(得分:0)
RFC 4122 § 3. Namespace Registration Template (Page 5)
<块引用>验证机制:
除了判断UUID的时间戳部分是否
是在未来,因此尚未分配,没有
确定 UUID 是否“有效”的机制。
生成过程决定了是否符合 RFC 4122,UUID 本身只是一个 128 位的ID标识符。
所以答案是肯定的,为什么不合规呢? UUID 只是一个 128 位的U普遍U独特的ID标识符,规范的其余部分只是推荐帮助您/Oracle 生成不与生成UU 的其他系统冲突的标识符的方法ID标识符。如果您或 Oracle 不想遵循他们的建议,他们可以随意执行。无论如何,您提供的 uuid 是“符合”RFC 4122 的,因为变体字段以位序列 111
开头,它是“保留以供将来定义。”。该规范是在过去编写的,并没有限制谁可以指定“未来定义”,它当然不会阻止 Oracle 定义他们自己的变体......因此它是“合规的”......哈哈。
附言我喜欢原作者如何预料到您的问题,并在“有效”周围添加了讽刺引号。