介绍下两个函数的作用:
hextoraw():十六进制字符串转换为raw;
rawtohex():将raw串转换为十六进制;
先来看下hextoraw()函数,当出现比f大的字母时(以a最小z最大)就会报错:
正确结果:
sys@ORCL> select hextoraw('abcdef') from dual;
HEXTOR
------
ABCDEF
错误结果:
sys@ORCL> select hextoraw('abcdeg') from dual;
select hextoraw('abcdeg') from dual
*
ERROR at line 1:
ORA-01465: invalid hex number
再来看看rawtohex()函数:
sys@ORCL> select rawtohex('AA') from dual;
RAWT
----
4141
结果之所以是4141是因为A的ASCII为65,65转换为十六进制就是41。
下面再看一个较有疑惑的问题:
sys@ORCL> declare
2 a varchar2(100);
3 begin
4 select rawtohex('aaaa') into a from dual;
5 dbms_output.put_line(a);
6 end;
7 /
61616161
PL/SQL procedure successfully completed.
sys@ORCL> declare
2 a varchar2(100);
3 begin
4 a:=rawtohex('aaaa');
5 dbms_output.put_line(a);
6 end;
7 /
AAAA
PL/SQL procedure successfully completed.
为什么会出现这种情况?
原因在于:SELECT方法用的是SQL 引擎,而:=是用PL/SQL 引擎。
本例两个调用中给的参数都是CHAR类型,这时ORACLE要进行缺省的类型转换,把'aaaa'由CHAR转到RAW。
但是SQL引擎和PL/SQL引擎的这个类型转换却不一样,SQL引擎使用了utl_raw.cast_to_raw,所以最后结果是'61616161',PL/SQL使用了HEXTORAW,而手册上的说法应该是用HEXTORAW,不知道为什么。
因此在用到rawtohex()函数时,不应该给它自动类型转换的机会,因为这是最容易出错的。
如果你期待的结果是'61616161'就该这样写:rawtohex(utl_raw.cast_to_raw('aaaa'))
如果你期待的结果是'AAAA'就该这样写:rawtohex(hextoraw('aaaa'))
不管哪个引擎都不会错了。
在使用SQL*Plus将RAW类型获取为一个串时,会隐士的调用rawtohex函数,而插入串时会隐式的调用hextoraw函数,应该避免隐式转换,而在编写代码时总是使用显示转换,这是一个很好的实践做法!