This blog explains, that the output of sys_guid()
is not random for every system:
http://feuerthoughts.blogspot.de/2006/02/watch-out-for-sequential-oracle-guids.html
Unfortunately I have to use such a system.
How to ensure to get a random UUID? Is it possible with sys_guid()
? If not how to reliably get a random UUID on Oracle?
Here's a complete example, based on @Pablo Santa Cruz's answer and the code you posted.
I'm not sure why you got an error message. It's probably an issue with SQL Developer. Everything works fine when you run it in SQL*Plus, and add a function:
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
But I would stick with SYS_GUID
if possible. Look at ID 1371805.1 on My Oracle Support - this bug is supposedly fixed in 11.2.0.3.
EDIT
Which one is faster depends on how the functions are used.
It looks like the Java version is slightly faster when used in SQL. However, if you're going to use this function in a PL/SQL context, the PL/SQL function is about twice as fast. (Probably because it avoids overhead of switching between engines.)
Here's a quick example:
--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; /
Version 4 GUIDs are not completely random. Some of the bytes are supposed to be fixed. I'm not sure why this was done, or if it matters, but according to https://www.cryptosys.net/pki/uuid-rfc4122.html:
The procedure to generate a version 4 UUID is as follows:
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"
The values from the Java version appear to conform to the standard.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With