我知道,SYS_GUID() 返回 16 字节 RAW 数据类型。但是当它转换为char时,它将是超过32字节的char类型。这与最大长度为 char(16) 的现有数据不兼容。那么是否可以使用Oracle聚合函数或者语句来生成一个16字节的char唯一ID呢?
最佳答案
不确定这种做法是否会导致碰撞(需要从理论上检验),但我认为碰撞的概率还是很低的:
select utl_raw.bit_xor(utl_raw.substr(sys_guid(), 1, 8),
utl_raw.substr(sys_guid(), 9)) id
from dual
connect by level <= 10;
另一种选择是使用最小值为 1000000000000000
的 SEQUENCE
并将其转换为字符数据类型。
该ID
的主要用途是什么?您需要将其用作主键吗?
更新:
经过进一步考虑,我建议坚持使用 SEQUENCE
,因为它是 native PK 生成机制。如果您需要超过 10^16 - 10^15 - 1
个唯一值(即从 1000000000000000 到 9999999999999999 的数字),则可以使用十六进制表示。首先,让我们确定适合十六进制形式的 16 个字符的最小和最大数字(假设没有前导或尾随空格):
select to_char(to_number('1000000000000000', 'XXXXXXXXXXXXXXXX')) min_value,
to_char(to_number('FFFFFFFFFFFFFFFF', 'XXXXXXXXXXXXXXXX')) max_value
from dual;
MIN_VALUE MAX_VALUE
--------------------------------------------
1152921504606846976 18446744073709551615
现在让我们使用确定的值创建SEQUENCE
:
create sequence my_sequence
minvalue 1152921504606846976
maxvalue 18446744073709551615
start with 1152921504606846976
increment by 1;
要生成主键,请将序列号值转换为十六进制形式:
select to_char(my_sequence.nextval, 'XXXXXXXXXXXXXXXX') hexadecimal_pk
from dual
connect by level <= 17;
HEXADECIMAL_PK
-----------------
1000000000000000
1000000000000001
1000000000000002
1000000000000003
1000000000000004
1000000000000005
1000000000000006
1000000000000007
1000000000000008
1000000000000009
100000000000000A
100000000000000B
100000000000000C
100000000000000D
100000000000000E
100000000000000F
1000000000000010
17 rows selected
关于oracle - 使用 PL/SQL 生成 16 字节字符类型唯一 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23127564/