Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle中的MD5(DBMS_obfusion_TOOLKIT.MD5)_Oracle_Plsql_Md5_Oracle Xe_Subtype - Fatal编程技术网

Oracle中的MD5(DBMS_obfusion_TOOLKIT.MD5)

Oracle中的MD5(DBMS_obfusion_TOOLKIT.MD5),oracle,plsql,md5,oracle-xe,subtype,Oracle,Plsql,Md5,Oracle Xe,Subtype,我正在尝试编写一个函数,从我收集的数据中获取MD5哈希值。我想获得哈希的小写十六进制表示形式。到目前为止,我有: CREATE OR REPLACE FUNCTION MD5 ( CADENA IN VARCHAR2 ) RETURN DBMS_OBFUSCATION_TOOLKIT.VARCHAR2_CHECKSUM AS BEGIN RETURN LOWER( RAWTOHEX( UTL_RAW.CAST_TO_RAW(

我正在尝试编写一个函数,从我收集的数据中获取MD5哈希值。我想获得哈希的小写十六进制表示形式。到目前为止,我有:

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\u模糊处理工具集。VARCHAR2\u校验和看起来是合适的选择,据我所知,它可以正常工作,但SQL Developer显示的
DBMS\u模糊处理工具集
的包定义显示:

SUBTYPE varchar2_checksum IS VARCHAR2(16);
输出有32个字符,所以我一定是做错了什么。我的问题是:

  • RETURN
    语句的正确类型是什么
  • 我是否在做不必要的转换来计算散列

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>
当然,我们可以使用子类型定义过程的参数,但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参数(或为函数返回变量)

这是一种冗长的说法,您可以在代码中使用
DBMS\u OBFUSCATION\u TOOLKIT.VARCHAR2\u CHECKSUM
,确信它不会阻止函数返回32个字符

但是,它会使查找子类型声明的开发人员感到困惑。在最坏的情况下,这些人将使用子类型声明他们自己的工作变量,结果如下:

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>
因此,最好不要使用不合适的子类型。相反,你要申报你自己的

给你:

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长度是因为它是原始(16)值的十六进制表示形式。或者,修改以上内容以输出原始版本并将原始存储在原始列中(使用的空间更少,但相信我,您将在将来进行rawtohex和hextoraw转换)


干杯

太好了!我终于使用了这个的一个变体。最重要的是,它最终帮助我弄清楚了内部是如何工作的。我使用的
MD5(INPUT_STRING=>CADENA)
实际上返回一个字符串,但它包含
0x5F4D…
字节,而不是一个文本
“5F4D”
表示。因此,我们求助于
RAW
作为中间格式,因此我们可以使用
RAWTOHEX()
。(强制从RAW自动转换为VARCHAR似乎也能起作用。)当我们希望以
CLOB
而不是
VARCHAR2
的形式传递时,会出现什么情况?这是我希望能够接受两个答案的情况之一。。。