我们有一个旧的应用程序,它读入SQL文本文件并将它们发送到Sybase ASE 12.51。我们的遗留应用程序是用Delphi 5编写的,它使用BDE TQuery组件进行此过程,并使用BDE SQLinks for Sybase访问Sybase。
伪代码:
SQLText=readSQLFile;
aTQuery.SQL.add(SQLText);
aTQuery.ExecSQL;
最近我们将数据库访问层移到了Delphi XE ADO实现 - 使用Sybase提供的ADO提供程序的TADOQuery,仍然使用相同的模型:
SQLText=readSQLFile;
aTADOQuery.SQL.add(SQLText)
aTADOQuery.ExecSQL;
迁移到ADO后,我们发现某些数据丢失了。我们跟踪了这个SQL构造的失败:
Select myColumn from myTable
Where tranID = null
知道这个构造在最好的情况下是有问题的,当我看到这段代码时,我做了一个“双重考虑”,但是Sybase 12.5接受了它 - 但是使用ADO,这个段失败了。
我们决定改变:
Where tranID = null
到
Where tranID is null
然后加载了缺失的数据 - 问题已解决,对于此细分市场和其他几个细分市场也是如此。
有没有人对此行为有解释?在哪里/为什么ADO明显拦截并拒绝这个序列,而BDE通过它?
TIA
答案 0 :(得分:3)
“NULL”具有非常特殊的含义,SQL需要特殊处理。您无法将值与“NULL”进行比较,这就是为什么有特殊运算符IS(NOT)NULL来检查它的原因。详尽的解释需要一些空间,这里有一个简单的解释。
从“数学”的角度来看,NULL可以被认为是“无穷大”。您无法轻松比较两个无限值,例如考虑整数和偶数的集合。两者都是无限的,但前者比后者更大似乎是合乎逻辑的。你只能说两套都是无限的。
这也有助于解释为什么1 + NULL返回NULL等等(通常只有像SUM()ecc。这样的聚合函数可以忽略NULL值 - 忽略,而不是将NULL转换成零)。
这个比喻在排序中可能不成立,因为有些数据库选择将NULL视为小于任何值(某种类型的-infinity,从而以递增顺序首先返回它们),反之亦然。有些人可以选择设置返回NULL的位置。
检查有关NULL算术和NULL比较的数据库文档。 field = NULL应该从未使用过,不知道Sybase是否接受它,但大多数SQL实现都没有,我猜它不符合SQL标准。习惯IS(NOT)NULL语法要好得多。
更新:Sybase有一个“set ansinull”选项,来自documentation(总是RTFM!),在12.5.1中它被扩展为禁止'= NULL'语法(设置为ON时使其符合SQL标准)。设置为OFF时'= NULL'作为'IS NULL'。
可能SQL链接或ADO提供程序将其设置为一个值或另一个值。