25

StackOverflow 上有几个问题似乎在 ADO/OleDB、delphi TADOQuery/TADOCommand 和参数主题上的答案相互矛盾。

可以通过两种方式引入参数,在 ADO 组件的 CommandText 或 SQL 属性中。对我来说大部分时间都有效的命名参数是用冒号介绍的:

  select a, b, c from bar where bat = :baz

这对我来说 99% 的时间都有效,很好。我时不时地发现 ADO 或 Delphi 的包装器不接受 ":baz" 并要求我改写这个:

  select f, g, h from bar where bat = ?

这会产生一个未命名的参数,而不是一个命名的参数。当 ADO 查询或 ADO 命令只包含一个参数时,这没什么大不了的。但那不是 ADO 对我起作用的时候。昨天它以一种方式行事,而今天,在一个 TADOCommand 对象中使用双命令的另一种方式,就像这样,在一个 CommandText 字符串中有两个命令:

delete from bar where id = :id1
delete from bat where id = :id2

我不得不将其更改为:

delete from bar where id = ?
delete from bat where id = ?

昨天一整天都在工作。今天,我不得不把它改回第一个版本,让它工作。症状是 ADO 参数消失了,再也回不来了,当我尝试执行命令时出现错误,索引超出范围,当我尝试访问Parameters[0]. 没有给我任何关于参数正在消失的警告。似乎在设计时与 ADO 数据集的一些连接慢跑了TADOCommand组件,特别是,它“只是打破了我”。当您尝试编写查询或命令时尤其令人抓狂,并且您知道它有效,但 ADO 组件已决定不接受“?”。或“:x”现在。您可以通过从一个切换到另一个来解决它完全无法运行的问题。但这让我感到沮丧,并且可能实际上完全阻止了其他人。我知道有些人总是在代码中动态构建他们的 SQL,并且避免使用Parameters.,也许这就是为什么.

我期待的问题的可能答案是:

  1. ADO 不支持多个命令,或者至少 Delphi 的包装器不支持。或者也许TADOCommand只是在这里不能可靠地工作。

  2. 参数是所有 ADO 或所有 Delphi 的 ADO 包装器中的一个错误区域?

  3. 你这样做是错的。

我正在使用 Delphi XE2,但我在 2007、2009、2010 和 XE 中看到了类似的狡猾行为。我使用 Microsoft OLEDB Provider for SQL Server 作为我的 OLEDB Provider。

4

3 回答 3

1

:带有?的命名参数 我一直使用它@,即使在 Visual Studio (ADO.NET) 上也是如此。并且在 T-SQL 参数和变量中以 . 为前缀@

不记得有问题...您确定您没有选择 Native Client(安装了 SQL Server 客户端安装)而不是 OLEDB Provider for SQL Server(Windows 附带)?

于 2012-10-04T21:53:05.900 回答
0

不幸的是,我有一段时间没有使用 Delphi,所以,我没有办法从 Delphi 的角度验证这个答案。

这是我第一次看到以冒号 ( :) 为前缀的命名参数。通常,在 ADODB 中,命名参数以 at ( @) 为前缀,是的,未命名参数以问号 ( ?) 给出。

命名参数的一个显着优势是它们能够被重用,即

INSERT INTO TABLE T VALUES (@id, @id, 'Hello World');

在 ADODB 级别。一旦您使用了参数,无论是命名的还是未命名的,您都可以将CommandText.Parameters.Refresh其用作创建参数的快速方法。

于 2012-10-04T21:08:46.843 回答
0

是的,在某些情况下参数?失败。我发现有时我需要使用:named参数。命名参数对于使用 DB Parameter 值具有优势,因为设置 Name 属性也可以更轻松地调试 ADO 查询或数据集或表。

我不明白为什么。如果您遇到此问题,请首先检查您使用的是正确的 OLEDB 提供程序,并检查是什么版本。还要检查由您生成的错误 SQL 引起的潜在解析错误。

我怀疑 OLEDB 提供程序内部的代码中我没有源代码的内部行为是这个怪癖的罪魁祸首。Delphi ADO 类包装器是从 Delphi 的数据库组件层架构到 ADO 的核心查询/表/数据集 API 的转换器,所有这些 API 都是围绕一组处理ADO RecordSets的 COM 对象的底层包装器。

于 2015-12-14T17:38:16.907 回答