【问题标题】:How to execute a pre-defined query having parameters (i.e. a PARAMETERS declaration) in a Microsoft Access database over ODBC?如何通过 ODBC 在 Microsoft Access 数据库中执行具有参数(即 PARAMETERS 声明)的预定义查询?
【发布时间】:2016-09-20 10:00:33
【问题描述】:

我的简单问题如下:

如果我有一个 Microsoft Access 数据库,其中定义了“查询”(即 MS Access 调用查询的那种数据库对象,只是为了避免任何歧义)定义为采用参数(在其 SQL 中使用 PARAMETERS 声明定义)通过 ODBC 连接调用它的正确 SQL 语法是什么,包括提供参数值?

编辑/添加:

我刚刚注意到可以通过在整个 CALL 命令周围添加花括号来完成,如下所示:

{CALL myAccessQuery ('string1', 'string2', 'string3')}

这实际上正是他们在我在下面提到的其他相关 SO 线程中所做的,但我只是认为这是与他们的准备语句性质相关的一些特定于 C# 的魔法SQL 语句(在其中使用“?”),或者他们的 SQL 库的一些其他特性(我没有使用那种语言),所以我之前忽略了它。

任何人只要解释大括号是什么,以及为什么它们允许执行的 SQL 命令多于下面错误消息中明确声明的支持的命令,都将是这个问题的可接受答案。强>

我的具体案例的更多细节:

我的查询采用三个参数,由查询声明开头的“PARAMETERS”子句定义,如下所示:

PARAMETERS myParam1 Text ( 255 ), myParam2 Text ( 255 ), myParam3 Text ( 255 );
SELECT ... <a bunch of not relevant stuff here> ;

使用(已建立并确认工作的)ODBC 连接,我想使用来自外部应用程序的此查询,包括为其提供所需的三个参数。

在来自外部应用程序的连接上运行 SELECT 等普通查询可以正常工作,但无论我用多少谷歌搜索,我似乎都找不到正确提供参数和运行查询的正确方法?所以,我的问题是,这样做的正确 SQL 语法是什么?

注意:我确实想要针对某些特定库或类似库的任何 API 特定解决方案,因为这仅解决了希望使用不同编程语言执行此操作的所有开发人员中的一小部分的问题,因此,出于这个原因,我什至不会提到我的外部应用程序是用什么语言编写的。我只想要执行此操作的完整 SQL 语法,仅此而已。

Another SO question 表示这应该使用“CALL”关键字来完成,但是当我尝试从我的应用程序中使用它时,我只会收到以下错误消息:

[42000] [Microsoft][ODBC Microsoft Access Driver] SQL 语句无效;预期为“DELETE”、“INSERT”、“PROCEDURE”、“SELECT”或“UPDATE”。

即,这是我在收到此错误时尝试执行的“SQL 命令”(故意避免使用模棱两可的术语“查询”...):

CALL myAccessQuery ('string1', 'string2', 'string3')

错误消息中提到的唯一一个似乎可能有用的 SQL 关键字是“PROCEDURE”关键字,但我在 Google 上也很难找到任何相关文档。 :-(

我怀疑谷歌在整个场景中缺乏结果的大部分原因是关于上下文中或多或少所有中心关键字的许多模糊不清,例如“查询”、“参数”、“执行”、“ call”和“procedure”,所以对于这个 SO 问题,我希望它会为 Google 将来提出的这个问题构成一个更容易识别和索引的答案。

【问题讨论】:

  • 恐怕不可能。通常 ODBC 驱动程序只支持访问 MS Access 表,不支持查询。您是否能够在没有参数的情况下从任何查询中检索数据?您可以在应用程序端使用参数重现查询。
  • 显然是这样。 :-) 请参阅我上面的编辑/添加。
  • 不确定通过 ODBC 调用查询的确切含义。您是在谈论 Access“直通”查询,意思是 CurrentDb.QueryDefs("myAccessQuery").Connect 不是空字符串?
  • @HansUp - 更像是使用 ADODB.Command 对象 (COM) 或 System.Data.Odbc (.NET) 执行保存的参数查询。

标签: sql database ms-access odbc parameter-passing


【解决方案1】:

当您通过 ODBC 进行连接时,请查看驱动程序特定信息以查看它是否支持各种 ODBC 扩展(在 ODBC 调用中由大括号表示):

https://msdn.microsoft.com/en-us/library/ms675326(v=vs.85).aspx

具体来说:

ODBC 为调用存储过程提供了特定的语法。对于 Command 对象的 CommandText 属性,Connection 对象的 Execute 方法的 CommandText 参数,或 Recordset 对象的 Open 方法的 Source 参数,都使用以下语法传入一个字符串:

    "{ [ ? = ] call procedure [ ( ? [, ? [ , … ]] ) ] }"

每个 ?引用参数集合中的对象。首先 ?引用参数(0),下一个?引用参数(1),等等。 参数引用是可选的,取决于存储过程的结构。如果你想调用一个不定义参数的存储过程,你的字符串应该如下所示:

    "{ call procedure }"

Access ODBC 驱动程序将保存的 SELECT 参数查询公开为存储过程,这就是您使用此语法的原因。

【讨论】:

  • 次要更正: (1) 对于 ODBC,它是“驱动程序”,而不是“提供程序”。 (2) 使用 Access ODBC 驱动程序,保存的 SELECT 查询带有参数被公开为存储过程。保存的 SELECT 查询不带参数作为视图公开。
  • 好的,所以这只是一种用于调用存储过程的 SQL 语法,那么看来,谢谢,接受了! (对于任何有任何远程想法的人来说,他们为什么不能跳过花括号并在没有它们的情况下使用“CALL”关键字,WTF?)
  • (cc: @QuestionOverflow ) - 作为记录,{CALL ...} 语法不是“特定于驱动程序”,而是“特定于协议”。这是ODBC Escape Sequences 的示例,大括号是区分原始SQL 文本和ODBC 扩展的一种方式。 FWIW,JDBC 也使用相同的{CALL ...} 语法。
  • 感谢@GordThompson 的额外澄清/信息!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-15
  • 1970-01-01
相关资源
最近更新 更多