Domanda

Sto cercando di comporre una funzione per ottenere hash MD5 da bit che ho raccolto qua e là. Voglio ottenere la rappresentazione esadecimale minuscola dell'hash. Ho questo finora:

CREATE OR REPLACE FUNCTION MD5 (
    CADENA IN VARCHAR2
) RETURN DBMS_OBFUSCATION_TOOLKIT.VARCHAR2_CHECKSUM
AS
BEGIN
    RETURN LOWER(
        RAWTOHEX(
            UTL_RAW.CAST_TO_RAW(
                DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT_STRING => CADENA)
            )
        )
    );
END;

Non sono sicuro del tipo di ritorno della funzione. DBMS_OBFUSCATION_TOOLKIT.VARCHAR2_CHECKSUM Sembra la scelta appropriata e per quanto posso dire funziona come previsto ma la definizione del pacchetto per dbms_obfuscation_toolkit Come visualizzato dallo sviluppatore SQL mostra questo:

SUBTYPE varchar2_checksum IS VARCHAR2(16);

L'output ha 32 caratteri, quindi devo fare qualcosa di sbagliato. Le mie domande:

  • Qual è il tipo corretto per il RETURN dichiarazione?
  • Sto facendo conversioni inutili per calcolare l'hash?
È stato utile?

Soluzione

È una peculiarità di Oracle PL/SQL che i parametri di procedura memorizzati e i tipi di ritorno della funzione non possono essere limitati. Cioè, non possiamo avere una procedura con una firma come questa:

SQL> create or replace procedure my_proc (p1 in varchar2(30))
  2  is
  3  begin
  4      null;
  5  end;
  6  /

Warning: Procedure created with compilation errors.

SQL> show error
Errors for PROCEDURE MY_PROC:

LINE/COL ERROR
-------- -----------------------------------------------------------------
1/34     PLS-00103: Encountered the symbol "(" when expecting one of the
         following:
         := . ) , @ % default character
         The symbol ":=" was substituted for "(" to continue.

SQL> create or replace procedure my_proc (p1 in varchar2)
  2  is
  3  begin
  4      null;
  5  end;
  6  /

Procedure created.

SQL>

Sicuramente possiamo definire il parametro della procedura usando un sottotipo ma Oracle lo ignorerà. Lo stesso vale per i tipi di ritorno della funzione ...

SQL> create or replace package my_subtypes as
  2      subtype ltd_string is varchar2(30);
  3  end;
  4  /

Package created.

SQL> create or replace function my_func return my_subtypes.ltd_string
  2  is
  3  begin
  4      return lpad('a', 4000, 'a');
  5  end;
  6  /

Function created.

SQL> select length(my_func) from dual
  2  /

LENGTH(MY_FUNC)
---------------
           4000

SQL>

L'unico modo per limitare i parametri e i tipi di restituzione è dichiarare variabili usando i sottotipi nella procedura memorizzata. Utilizzare le variabili all'interno del pacchetto e assegnarle ai parametri di uscita (o restituire la variabile per le funzioni).

Che è un modo di dire lungo di dire, puoi usare DBMS_OBFUSCATION_TOOLKIT.VARCHAR2_CHECKSUM Nel tuo codice è fiducioso che non impedirà alla tua funzione di restituire 32 caratteri.

Tuttavia, confonderà gli sviluppatori che cercheranno la dichiarazione del sottotipo. Nel peggiore dei casi queste persone useranno il sottotipo per dichiarare le proprie variabili di lavoro con il seguente tragico risultato:

SQL> declare
  2      v my_subtypes.ltd_string;
  3  begin
  4      v := my_func;
  5  end;
  6  /
declare
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 4


SQL>

Quindi, è meglio non usare un sottotipo inappropriato. Invece dichiara il tuo.

Altri suggerimenti

Ecco qui:

create or replace function getMD5(
  in_string in varchar2)
return varchar2
as
  cln_md5raw raw(2000);
  out_raw raw(16);
begin
  cln_md5raw := utl_raw.cast_to_raw(in_string);
  dbms_obfuscation_toolkit.md5(input=>cln_md5raw,checksum=>out_raw);
  -- return hex version (32 length)
  return rawtohex(out_raw);
end;

La lunghezza di 32 è perché è una rappresentazione esadecimale del valore grezzo (16). Oppure, modifica sopra per produrre la versione grezza e archiviare il RAW in una colonna RAW (meno spazio utilizzato, ma farai conversioni future Rawtohex e Hextoraw, credimi).

Saluti

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top