我有这个oracle代码
FUNCTION get_enc_val(p_in IN VARCHAR2,
p_key IN VARCHAR2
)
RETURN raw
IS
p_title_procedure_name VARCHAR2(100) := 'get_enc_val';
l_enc_val RAW(2000);
l_mod PLS_INTEGER := DBMS_CRYPTO.ENCRYPT_AES128 + DBMS_CRYPTO.CHAIN_CBC + DBMS_CRYPTO.PAD_PKCS5;
v_key VARCHAR2(16);
encryption_ex Exception;
BEGIN
v_key := RPAD(SUBSTR(TRIM(p_key), 1, 16), 16, '0');
l_enc_val := DBMS_CRYPTO.encrypt(UTL_RAW.cast_to_raw(p_in), l_mod, UTL_RAW.cast_to_raw(v_key));
RAISE encryption_ex;
RETURN l_enc_val;
EXCEPTION
WHEN OTHERS THEN
service_func.log_error(p_title_package_name || '.' || p_title_procedure_name, 'Proc', NULL, SYSDATE, SQLERRM, p_in || '~' || p_key);
RETURN 'Encryption_ERROR';
END;
当我运行这个时,我得到ORA-06510未处理的用户定义异常,而它应该真正返回字符串'Encryption_ERROR'。这给了什么?它转到Exception块,因为我看到了log_error函数的结果。问题是,是不是异常块应该处理任何异常?
我有点困惑。
答案 0 :(得分:4)
问题是你的第二个RETURN语句在声明函数返回RAW时返回VARCHAR2。您可以通过调用UTL_RAW.CAST_TO_RAW来解决这个问题,即
EXCEPTION
WHEN OTHERS THEN
service_func.log_error(p_title_package_name || '.' ||
p_title_procedure_name,
'Proc',
NULL,
SYSDATE,
SQLERRM,
p_in || '~' || p_key);
RETURN utl_raw.cast_to_raw( 'Encryption_ERROR' );
END;
如果我声明两个函数,一个返回硬编码字符串,另一个返回RAW,你会看到差异(我正在删除DBMS_CRYPTO调用和LOG_ERROR调用)。如果我声明一个返回RAW的函数,你会得到一个结果(尽管人类必须将原始数据转换为字符串才能理解结果)
SQL> ed
Wrote file afiedt.buf
1 create or replace function throw_exception
2 return raw
3 is
4 my_exception exception;
5 begin
6 raise my_exception;
7 exception
8 when others then
9 return utl_raw.cast_to_raw( 'Foo' );
10* end;
SQL> /
Function created.
SQL> select throw_exception
2 from dual;
THROW_EXCEPTION
-----------------------------------------------------------------------------
466F6F
如果我只是返回一个字符串,我会得到你得到的同样的异常
SQL> ed
Wrote file afiedt.buf
1 create or replace function throw_exception2
2 return raw
3 is
4 my_exception exception;
5 begin
6 raise my_exception;
7 exception
8 when others then
9 return 'Foo';
10* end;
SQL> /
Function created.
SQL> select throw_exception2
2 from dual;
select throw_exception2
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: hex to raw conversion error
ORA-06512: at "SCOTT.THROW_EXCEPTION2", line 9
ORA-06510: PL/SQL: unhandled user-defined exception
当然,另一种选择是声明函数返回VARCHAR2。但我宁愿在RAW中使用哈希值和加密数据而不是VARCHAR2,这样你就不必担心字符集转换问题会破坏数据。
答案 1 :(得分:-1)
由于您确定service_func.log_error(...);
没有引发错误,因此调用过程/函数必须抛出该错误。
这是引起同样错误的事情。
create or replace function abc return raw is
begin
return 'Encryption_ERROR';
end;
/
declare
r raw(50);
begin
r := abc;
end;
/