sql >> Databáze >  >> RDS >> Oracle

Jak vygenerovat verzi 4 (náhodné) UUID na Oracle?

Zde je úplný příklad založený na odpovědi @Pablo Santa Cruz a kódu, který jste zveřejnili.

Nejsem si jistý, proč se vám zobrazila chybová zpráva. Pravděpodobně je to problém s SQL Developerem. Všechno funguje dobře, když to spustíte v SQL*Plus a přidáte funkci:

   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 zůstal bych u SYS_GUID Pokud možno. Podívejte se na ID 1371805.1 na My Oracle Support – tato chyba je údajně opravena v 11.2.0.3.

UPRAVIT

Která z nich je rychlejší, závisí na způsobu použití funkcí.

Zdá se, že verze Java je při použití v SQL o něco rychlejší. Pokud však budete tuto funkci používat v kontextu PL/SQL, funkce PL/SQL je přibližně dvakrát rychlejší. (Pravděpodobně proto, že se vyhne režii přepínání mezi motory.)

Zde je rychlý příklad:

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

Identifikátory GUID verze 4 nejsou úplně náhodný. Některé bajty mají být opraveny. Nejsem si jistý, proč se to stalo, nebo jestli na tom záleží, ale podle https://www.cryptosys.net/pki/uuid-rfc4122.html:

Postup pro vygenerování UUID verze 4 je následující:

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"

Zdá se, že hodnoty z verze Java odpovídají standardu.



  1. Použití PIVOT v SQL Server 2008

  2. desetinné (s,p) nebo číslo (s,p)?

  3. GROUP BY bez agregační funkce

  4. SQL Server Náhodné řazení