4

あちこちで集めたビットから MD5 ハッシュを取得する関数を作成しようとしています。ハッシュの小文字の 16 進数表現を取得したいと考えています。私はこれまでのところこれを持っています:

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;

関数の戻り値の型がわかりません。DBMS_OBFUSCATION_TOOLKIT.VARCHAR2_CHECKSUM適切な選択のように見え、私が知る限り、期待どおりに動作しますがdbms_obfuscation_toolkit、SQL Developer によって表示されるパッケージ定義は次のように表示されます。

SUBTYPE varchar2_checksum IS VARCHAR2(16);

出力には 32 文字あるので、何か間違ったことをしているに違いありません。私の質問:

  • RETURNステートメントの正しいタイプは何ですか?
  • ハッシュを計算するために不要な変換を行っていますか?
4

2 に答える 2

10

どうぞ:

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;

32 の長さは、raw(16) 値の 16 進数表現であるためです。または、上記を変更して raw バージョンを出力し、raw を RAW 列に保存します (使用するスペースは少なくなりますが、将来 ra​​wtohex および hextoraw 変換を行うことになると思います)。

乾杯

于 2011-05-05T17:17:41.143 に答える
5

ストアド プロシージャのパラメータと関数の戻り値の型を制限できないのは、Oracle PL/SQL の特性です。つまり、次のような署名を持つプロシージャを作成することはできません。

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>

確かに、SUBTYPE を使用してプロシージャのパラメータを定義できますが、Oracle はそれを無視します。関数の戻り値の型についても同じことが言えます...

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>

パラメーターと戻り値の型を制限する唯一の方法は、ストアド プロシージャ内でサブタイプを使用して変数を宣言することです。パッケージ内の変数を使用し、それらを OUT パラメーターに割り当てます (または、関数の変数を RETURN します)。

これは長い言い方ですが DBMS_OBFUSCATION_TOOLKIT.VARCHAR2_CHECKSUM、関数が 32 文字を返すのを妨げないことを確信して、コードで使用できます。

ただし、SUBTYPE 宣言を検索する開発者は混乱します。最悪の場合、これらの人々はサブタイプを使用して独自の作業変数を宣言し、次の悲劇的な結果をもたらします。

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>

したがって、不適切なサブタイプは使用しない方がよいでしょう。代わりに、独自に宣言してください。

于 2011-05-05T12:58:12.773 に答える