这是一个完整的示例,基于 @Pablo Santa Cruz 的答案和您发布的代码。
我不确定您为什么收到错误消息。这可能是 SQL Developer 的问题。当您在 SQL*Plus 中运行它并添加一个函数时,一切正常:
create or replace and compile
java source named "RandomUUID"
as
public class RandomUUID
{
public static String create()
{
return java.util.UUID.randomUUID().toString();
}
}
/
Java created.
CREATE OR REPLACE FUNCTION RandomUUID
RETURN VARCHAR2
AS LANGUAGE JAVA
NAME 'RandomUUID.create() return java.lang.String';
/
Function created.
select randomUUID() from dual;
RANDOMUUID()
--------------------------------------------------------------
4d3c8bdd-5379-4aeb-bc56-fcb01eb7cc33
但我会坚持SYS_GUID
如果可能的话。查看 My Oracle Support 上的 ID 1371805.1 - 该错误据说已在 11.2.0.3 中修复。
EDIT
哪一个更快取决于函数的使用方式。
看起来 Java 版本在 SQL 中使用时速度稍快一些。但是,如果您要在 PL/SQL 上下文中使用此函数,则 PL/SQL 函数大约是
速度快两倍。 (可能是因为它避免了引擎之间切换的开销。)
这是一个简单的例子:
--Create simple table
create table test1(a number);
insert into test1 select level from dual connect by level <= 100000;
commit;
--SQL Context: Java function is slightly faster
--
--PL/SQL: 2.979, 2.979, 2.964 seconds
--Java: 2.48, 2.465, 2.481 seconds
select count(*)
from test1
--where to_char(a) > random_uuid() --PL/SQL
where to_char(a) > RandomUUID() --Java
;
--PL/SQL Context: PL/SQL function is about twice as fast
--
--PL/SQL: 0.234, 0.218, 0.234
--Java: 0.52, 0.515, 0.53
declare
v_test1 raw(30);
v_test2 varchar2(36);
begin
for i in 1 .. 10000 loop
--v_test1 := random_uuid; --PL/SQL
v_test2 := RandomUUID; --Java
end loop;
end;
/
版本 4 GUID 不是完全地随机的。一些字节应该是固定的。我不确定为什么这样做,或者这是否重要,但根据https://www.cryptosys.net/pki/uuid-rfc4122.html https://www.cryptosys.net/pki/uuid-rfc4122.html:
生成版本 4 UUID 的过程如下:
Generate 16 random bytes (=128 bits)
Adjust certain bits according to RFC 4122 section 4.4 as follows:
set the four most significant bits of the 7th byte to 0100'B, so the high nibble is "4"
set the two most significant bits of the 9th byte to 10'B, so the high nibble will be one of "8", "9", "A", or "B".
Encode the adjusted bytes as 32 hexadecimal digits
Add four hyphen "-" characters to obtain blocks of 8, 4, 4, 4 and 12 hex digits
Output the resulting 36-character string "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
Java 版本的值似乎符合标准。