Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Jak wygenerować UUID wersji 4 (losowy) na Oracle?

Oto kompletny przykład, oparty na odpowiedzi @Pablo Santa Cruz i przesłanym przez Ciebie kodzie.

Nie wiem, dlaczego pojawił się komunikat o błędzie. Jest to prawdopodobnie problem z SQL Developerem. Wszystko działa dobrze, gdy uruchomisz go w SQL*Plus i dodasz funkcję:

   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

Ale trzymałbym się SYS_GUID Jeśli to możliwe. Spójrz na ID 1371805.1 w My Oracle Support — ten błąd został prawdopodobnie naprawiony w 11.2.0.3.

EDYTUJ

To, który z nich jest szybszy, zależy od sposobu użycia funkcji.

Wygląda na to, że wersja Java jest nieco szybsza, gdy jest używana w SQL. Jeśli jednak zamierzasz używać tej funkcji w kontekście PL/SQL, funkcja PL/SQL jest około dwa razy szybsza. (Prawdopodobnie dlatego, że pozwala uniknąć narzutów związanych z przełączaniem między silnikami.)

Oto krótki przykład:

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

Identyfikatory GUID w wersji 4 nie są w pełni losowy. Niektóre bajty powinny zostać naprawione. Nie jestem pewien, dlaczego tak się stało, ani czy ma to znaczenie, ale zgodnie z https://www.cryptosys.net/pki/uuid-rfc4122.html:

Procedura generowania UUID wersji 4 jest następująca:

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"

Wartości z wersji Java wydają się być zgodne ze standardem.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Błąd 404 nie został znaleziony w EM 12c

  2. Różnica między użytkownikiem a schematem w Oracle?

  3. Znajdowanie luk w sekwencji w tabeli w Oracle

  4. Wybierz pierwszy wiersz każdej grupy w sql

  5. java.lang.ClassCastException:oracle.sql.TIMESTAMP nie może być rzutowany na java.sql.Timestamp