SYS_OP_MAP_NONNULL NULL的等值比较

打印 上一主题 下一主题

主题 1026|帖子 1026|积分 3078

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x


无意在数据库中发现了这个操纵SYS_OP_MAP_NONNULL。
 
 
SYS_OP_MAP_NONNULL应该不是数据库中的对象,因为在DBA_OBJECTS中根本找不到它,而在STANDARD和DBMS_STANDARD包中也找不到函数阐明。
SQL> SELECT *
  2  FROM DBA_OBJECTS
  3  WHERE OBJECT_NAME = 'SYS_OP_MAP_NONNULL';
未选定行
SQL> SELECT *
  2  FROM DBA_SOURCE
  3  WHERE UPPER(TEXT) LIKE '%SYS_OP_MAP_NONNULL%';
未选定行
SYS_OP_MAP_NONNULL又可以跟参数,它不符合伪列的特性,因此暂且认为这是一个操纵。不外文档中并没有这个操纵的任何相干记载。
其实这个操纵实现的就是DUMP函数的功能:
SQL> SELECT SYS_OP_MAP_NONNULL(5) FROM DUAL;
SYS_OP
------
C10600
SQL> SELECT SYS_OP_MAP_NONNULL('A') FROM DUAL;
SYS_
----
4100
SQL> SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'), SYS_OP_MAP_NONNULL(SYSDATE) FROM DUAL;
TO_CHAR(SYSDATE,'YY SYS_OP_MAP_NONNU
------------------- ----------------
2010-08-06 02:19:47 786E080603143000
SQL> SELECT SYS_OP_MAP_NONNULL(NULL) FROM DUAL;
SY
--
FF
和DUMP的区别在于NULL的处理上,DUMP的参数假如是NULL,返回结果也是NULL,而SYS_OP_MAP_NONNULL返回的是FF,而这正是NULL存储在数据块中的编码。
SQL> SELECT DUMP(NULL) FROM DUAL;
DUMP
----
NULL
可以认为SYS_OP_MAP_NONNULL返回的就是这个数据范例存储的编码:
SQL> CREATE TABLE T_TEST          
  2  (ID NUMBER,
  3  C1 LONG,
  4  C2 CLOB);
表已创建。
SQL> INSERT INTO T_TEST
  2  VALUES (1, 'ABC', 'DEF');
已创建 1 行。
SQL> SELECT DUMP(C1) FROM T_TEST;
SELECT DUMP(C1) FROM T_TEST
            *
第 1 行出现错误:
ORA-00997: 非法使用 LONG 数据范例

SQL> SELECT DUMP(C2) FROM T_TEST;
SELECT DUMP(C2) FROM T_TEST
            *
第 1 行出现错误:
ORA-00932: 数据范例不一致: 应为 -, 但却获得 CLOB

SQL> SELECT SYS_OP_MAP_NONNULL(C1) FROM T_TEST;
SYS_OP_MAP_NONNULL(C1)
--------------------------------------------------------------------------------------------
01000186000000D104000000820100012A9013002A90130008003F00E83F000000000000000000000000D7D103003200030000000000000060000000909500D1030100000000000000000000000000000000000000000000000000000000000000000000080000005496D7D10301000004002A009E0900004400C0006C0E150

SQL> SELECT SYS_OP_MAP_NONNULL(C2) FROM T_TEST;
SYS_OP_MAP_NONNULL(C2)
-------------------------------------------------------------------------------------------
006A0001020C8800000200000001000000AB8D630013902B0013902A000300030354000100440045004600000000000000000000D1D7965701030004002A0000099E00C000440E6C150000000013902A0100018600000016090000000000000600000000000100440045004600
二者尚有一个很重要的区别就是DUMP不支持LONG以及大对象,而SYS_OP_MAP_NONNULL则支持任意的数据范例。
利用Oracle的这个功能,可以更方便的检查数据的存储格式。




---------------null比较


Oracle的Null真是个麻烦的东西。
不能与其他变量进行比较,甚至不能和NULL进行比较。
仅仅能用IS (NOT) NULL。

来看这个实行,看看能不能知道执行的结果。
先准备数据:


执行一个查询,来猜猜结果



执行结果如下,是你的预期吗?



从结果来看,两行null被合并了。
题目来了,知道null和null是绝对不相称的,为什么会合并掉呢?

经查证,这里ORACLE内部用了个未公开的函数sys_op_map_nonnull

我们来测试一下这个函数
对于NULL


对于非NULL



我们看sys_op_map_nonnull(null)=FF,而FF这正是NULL存储在数据块中的编码。
利用该函数对两个NULL进行比较。



但是不要走火入魔,这种非公开函数不要在项目中使用,因为Oracle不会对它出现的题目负责哦。

项目中假如需要对可为NULL的变量进行比较操纵,还是老老实实前面加是否为NULL的判断,再比较吧。



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

石小疯

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表