Oracle
 sql >> Base de données >  >> RDS >> Oracle

Comment générer un UUID version 4 (aléatoire) sur Oracle ?

Voici un exemple complet, basé sur la réponse de @Pablo Santa Cruz et le code que vous avez posté.

Je ne sais pas pourquoi vous avez reçu un message d'erreur. C'est probablement un problème avec SQL Developer. Tout fonctionne correctement lorsque vous l'exécutez dans SQL*Plus et que vous ajoutez une fonction :

   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

Mais je m'en tiendrais à SYS_GUID si possible. Regardez l'ID 1371805.1 sur My Oracle Support - ce bogue est censé être corrigé dans 11.2.0.3.

MODIFIER

Lequel est le plus rapide dépend de la façon dont les fonctions sont utilisées.

Il semble que la version Java soit légèrement plus rapide lorsqu'elle est utilisée dans SQL. Cependant, si vous comptez utiliser cette fonction dans un contexte PL/SQL, la fonction PL/SQL est environ deux fois plus rapide. (Probablement parce qu'il évite les frais généraux de commutation entre les moteurs.)

Voici un exemple rapide :

--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;
/

Les GUID de la version 4 ne sont pas complètement Aléatoire. Certains octets sont censés être fixes. Je ne sais pas pourquoi cela a été fait, ou si c'est important, mais selon https://www.cryptosys.net/pki/uuid-rfc4122.html :

La procédure pour générer un UUID version 4 est la suivante :

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"

Les valeurs de la version Java semblent conformes à la norme.