我正在尝试组成一个函数,从我收集到的数据中获取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_OBFUSCATION_TOOLKIT.VARCHAR2_CHECKSUM看起来是合适的选择,据我所知,它可以正常工作,但是SQL显示的dbms_obfuscation_toolkit包定义显示如下:
SUBTYPE varchar2_checksum IS VARCHAR2(16);输出有32个字符,所以我肯定做错了什么。我的问题:
RETURN语句的正确类型是什么?发布于 2011-05-05 12:58:12
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_OBFUSCATION_TOOLKIT.VARCHAR2_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>因此,最好不要使用不适当的子类型。而是宣布你自己的。
发布于 2011-05-05 17:17:41
给你:
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)值的十六进制表示。或者,修改上面的内容以输出原始版本,并将其存储在一个原始列中(使用的空间较少,但相信我,您将进行未来的rawtohex和十六进制转换)。
干杯
https://stackoverflow.com/questions/5897438
复制相似问题