【问题标题】:Sybase 12.5-BDE-ADO "where myColumn=null" failureSybase 12.5-BDE-ADO “where myColumn=null”失败
【发布时间】:2011-12-12 15:44:59
【问题描述】:

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

伪代码:

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

最近我们将 DB 访问层移至 Delphi XE ADO 实现 - TADOQuery,使用 Sybase 提供的 ADO 提供程序,仍然使用相同的模型:

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

【问题讨论】:

    标签: delphi ado delphi-xe sap-ase delphi-5


    【解决方案1】:

    “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 提供程序将其设置为一个值。

    【讨论】:

    • 谢谢,但这不是问题 - 请参阅编辑。顺便说一句,我还在某些方面将 Null 与 Infinity 进行了比较——它不是一个值——也许更好地描述为“状态”(没有状态的状态......)但这可能会变得非常学术,我不认为这是一个学术论坛——它是为有“真正工作”的人准备的 LOL
    • 我在解释为​​什么正确的语法有效,而另一种应该始终避免使用。无论如何,您是否从 BDE 切换到 ADO?或者你改变了什么?两个访问层根本不应该解析查询,但可以设置不同的客户端选项。数据库是一样的吗?客户是一样的吗?驱动程序可以有不同的“兼容性”设置。你检查 SQL 链接参数了吗?
    • 例如,检查“set ansinull”选项...猜这是“RTFM!”的情况:) 也许一个设置为关闭,另一个设置为默认打开。
    • 同意 - 我永远不会写 '=null',它应该是 BANNED。我的新代码在同一个数据库上运行,但完全在 ADO 下 - 旧代码运行 SQLinks 但我不确定它是如何配置的 - 必须与更了解旧代码的人协调 - 我多年来一直在使用 ADO 并且多年来,从未在任何产品环境中实际使用过 SQLinks。
    • “也许 SQL 链接或 ADO 提供程序将其设置为一个值或另一个” - 更可能的是旧代码将“set ansinull”设置为“OFF”,但我通过 ADO 连接的方式没有完成 - 可以在每个会话的基础上设置该选项。我给你分数是因为你花时间为我们指明了正确的方向。无论如何,解决方案当然是不使用'=null',这在语义上是不正确的。当我浏览我们的文件时,这个结构将被立即删除。
    猜你喜欢
    • 2010-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多