sql >> Database >  >> RDS >> Oracle

Hoe een versie 4 (willekeurige) UUID op Oracle te genereren?

Hier is een compleet voorbeeld, gebaseerd op het antwoord van @Pablo Santa Cruz en de code die je hebt gepost.

Ik weet niet zeker waarom je een foutmelding hebt gekregen. Het is waarschijnlijk een probleem met SQL Developer. Alles werkt prima als je het uitvoert in SQL*Plus, en een functie toevoegt:

   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

Maar ik blijf bij SYS_GUID zo mogelijk. Kijk naar ID 1371805.1 op My Oracle Support - deze bug is vermoedelijk opgelost in 11.2.0.3.

BEWERKEN

Welke sneller is, hangt af van hoe de functies worden gebruikt.

Het lijkt erop dat de Java-versie iets sneller is bij gebruik in SQL. Als je deze functie echter in een PL/SQL-context gaat gebruiken, is de PL/SQL-functie ongeveer twee keer zo snel. (Waarschijnlijk omdat het de overhead van het schakelen tussen motoren vermijdt.)

Hier is een snel voorbeeld:

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

Versie 4 GUID's zijn niet volledig willekeurig. Sommige bytes zouden moeten worden gerepareerd. Ik weet niet zeker waarom dit is gedaan, of dat het ertoe doet, maar volgens https://www.cryptosys.net/pki/uuid-rfc4122.html:

De procedure om een ​​versie 4 UUID te genereren is als volgt:

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"

De waarden uit de Java-versie lijken te voldoen aan de standaard.



  1. Hoe zie ik alle externe sleutels van een tabel of kolom?

  2. Laravel-migratiefout:syntaxisfout of toegangsfout:1071 Opgegeven sleutel was te lang; maximale sleutellengte is 767 bytes

  3. Hoe een uitzondering binnen een trigger te verhogen? Is er een manier om dit te doen?

  4. Hoe sys.dm_exec_describe_first_result_set_for_object werkt in SQL Server