知识卡片
SQL的EXISTS不是真正的三值逻辑存在量词
内容
[[NULL与三值逻辑逻辑正确与现实正确的分离]]里已知SQL基于三值逻辑(3VL),
存在量词理论上应该能返回TRUE、FALSE、UNKNOWN三种结果之一。但SQL的EXISTS
运算符实际上永远只返回TRUE或FALSE,从不返回UNKNOWN——这个不一致有其结构性
原因:SQL的EXISTS根本不包含任何约束变元,它不是真正意义上的量词,而是一个
普通的、类型为BOOLEAN的一元运算符:EXISTS(tx)先计算表表达式tx得到表t,
再简单判断t是否为空,t非空则TRUE、否则FALSE,这个判定过程完全绕过了3VL
本该介入的判断路径。书中给出一个不太严谨但直观的反例:如果tx是一个”只包含
NULL的表”,逻辑正确的答案应该是UNKNOWN(连”存在满足条件的行”这件事本身都
不确定),但SQL的EXISTS(tx)却会直接返回TRUE——这说明SQL的EXISTS并不是
三值逻辑存在量词的可信实现,这也解释了为什么某些SQL查询在存在NULL的情况下
可能给出错误结果(第11章会有更具体的例证)。这个不一致同时揭示了SQL为什么
没有对应的FORALL:一个假设的FORALL(tx)运算符同样无法表达真正的全称量化
语义,因为它处理的参数只是”tx这个表表达式代表的那些行”,而不是某个无限或
未指定论域上的”所有可能取值”,这条限制会在[[FORALL和EXISTS可以互相定义SQL
缺FORALL导致双重否定困境]]中进一步展开。
参考来源
- 位置:《SQL与关系数据库理论——如何编写健壮的SQL代码》第10章"SQL与逻辑"
10.5节"关系演算"脚注(源文件:OEBPS/text00113.html)
- 结论依据:原文明确"因为SQL支持null,所以SQL基于的是所谓的三值逻辑
(3VL)……在三值逻辑中,存在量词可以返回3种不同的结果:TRUE、FALSE和
UNKNOWN……然而SQL的EXISTS运算符总是返回TRUE或FALSE,从来不返回UNKNOWN
……如果tx为只包含null的表,那么EXISTS(tx)就会返回TRUE而不是返回逻辑上
正确的UNKNOWN……SQL的EXISTS并不是三值逻辑存在量词的可信实现"。
- 原始内容:SQL的EXISTS运算符总是返回TRUE或FALSE,从来不返回UNKNOWN……
如果tx为只包含null的表,那么EXISTS(tx)就会返回TRUE而不是返回逻辑上
正确的UNKNOWN……SQL的EXISTS并不是三值逻辑存在量词的可信实现。