“成员”集合的 PL/SQL 否定不否定
Posted
技术标签:
【中文标题】“成员”集合的 PL/SQL 否定不否定【英文标题】:PL/SQL negation of "member of" collection does not negate 【发布时间】:2015-07-16 17:24:25 【问题描述】:我有一个 PL/SQL 集合,其中包含一个空元素(在最小的工作示例中仅此而已,但附加元素的行为是相同的)。当我现在查询此集合是否具有特定数字作为元素时,它按预期返回false
。但奇怪的是,否定查询也会产生false
的答案。
任何人都可以确认这种行为或指导我在这里失败的假设吗?
DECLARE
TYPE number_t IS TABLE OF NUMBER;
nt1 number_t := number_t();
BEGIN
nt1.extend();
dbms_output.put_line('Start'); -- prints 'Start'
IF 1 member of nt1 THEN
dbms_output.put_line('Member'); -- does not execute
END IF;
IF not 1 member of nt1 THEN
dbms_output.put_line('Not member'); -- does not execute
END IF;
IF not (1 member of nt1) THEN
dbms_output.put_line('Not member'); -- does not execute
END IF;
END;
观察时间:Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit
尚未在其他安装上进行测试。
【问题讨论】:
【参考方案1】:根据 Oracle 文档,“EXTEND
将一个空元素附加到集合”和“如果 expr
等于指定的成员,则 [MEMBER
运算符] 的返回值是 TRUE
嵌套表”
将任何内容与 null 进行比较都会得到 UNKNOWN
结果,因此条件既不是 TRUE
也不是 FALSE
,因此永远不会执行 THEN
块。
参考资料:
http://docs.oracle.com/cd/B12037_01/appdev.101/b10807/13_elems006.htm
http://docs.oracle.com/cd/B19306_01/server.102/b14200/conditions006.htm
【讨论】:
有什么方法可以检查UNKNOWN
结果的样子吗?例如,通过将 MEMBER
的结果分配给变量,而不像 CASE
那样实际分配/转换为布尔值?
不确定UNKNOWN
的“外观”是什么意思。它属于BOOLEAN
之类,但既不是TRUE
也不是FALSE
,因此如果将其分配给布尔变量,其值也将变为UNKNOWN
。
谢谢,我不知道 BOOLEAN
的 UNKNOWN
值实际上是 IS NULL
。因此,检查not MEMBER
的正确方法是同时检查NULL
。【参考方案2】:
为了完整起见,考虑到可能的NULL
值,我检查not MEMBER
的最终方法是:
IF not 1 member of nt1 OR (1 member of nt1) IS NULL THEN
dbms_output.put_line('NULL'); -- prints 'NULL'
END IF;
【讨论】:
以上是关于“成员”集合的 PL/SQL 否定不否定的主要内容,如果未能解决你的问题,请参考以下文章
PL/SQL ORA-01422 SELECT INTO 错误,Oracle 匿名块(NOVA 环境)
Windows 64位 安装Oracle instantclient 官方绿色版和PL/SQL Developer 总结
在使用 Entity Framework 数据库优先在表上插入行之前,如何从 PL/SQL 执行触发器?
如何在选择语句的“NOT IN”子句中使用逗号分隔的字符串列表作为 pl/sql 存储的函数参数
PL/SQL developer连接oracle出现“ORA-12154:TNS:could not resolve the connect identifier specified”问题的解决(代码