3

我们有一个旧应用程序读取 SQL 文本文件并将它们发送到 Sybase ASE 12.51。我们的旧应用程序是用 Delphi 5 编写的,并且在此过程中使用 BDE TQuery 组件,并使用 BDE SQLinks for Sybase 访问 Sybase。

伪代码:

SQLText=readSQLFile;
aTQuery.SQL.add(SQLText);
aTQuery.ExecSQL;

最近,我们使用 Sybase 提供的 ADO 提供程序将 DB 访问层移至 Delphi XE 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

4

1 回答 1

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”选项,来自文档(总是 RTFM!),在 12.5.1 中,它被扩展为不允许使用 '= NULL' 语法(当设置为 ON 以使其符合 SQL 标准时)。当设置为 OFF 时,'= NULL' 作为 'IS NULL' 工作。

也许 SQL 链接或 ADO 提供程序将其设置为一个值或另一个。

于 2011-12-12T22:51:43.090 回答