Jet引擎(Access):将值列表传递给存储过程

时间:2011-04-03 13:24:43

标签: vba stored-procedures parameter-passing jet

我目前正在编写基于VBA的Excel加载项,该加载项主要基于Jet数据库后端(我使用的是Office 2003套件 - 问题与最新版本的Office无关)。

在我的应用程序初始化期间,我创建了在文本文件中定义的存储过程。这些程序在需要时由我的应用程序调用。

让我举一个简单的例子来描述我的问题:假设我的应用允许最终用户选择他们想要详细信息的订单的标识符。这是表格定义:

  

表tblOrders:OrderID LONG,OrderDate DATE,(其他字段)

最终用户可以选择一个或多个订单ID,以表格形式显示 - 他/她只需勾选相关订单ID的复选框,其中包含他/她喜欢的详细信息(OrderDate等)。

因为我事先并不知道他/她将选择多少OrderID,所以我可以根据表单上的选择级联WHERE子句,在VBA代码中动态创建SQL查询:

SELECT * FROM tblOrders WHERE OrderID = 1 OR OrderID = 2 OR OrderID = 3

或更简单,使用IN关键字:

SELECT * FROM tblOrders WHERE OrderID IN (1,2,3)

现在,如果我将这个简单的查询转换为存储过程,以便我可以动态传递我想要显示的OrderID列表,我该怎么办?我已经尝试过这样的事情:

CREATE PROCEDURE spTest (@OrderList varchar) AS
  SELECT * FROM tblOrders WHERE OrderID IN (@OrderList)

但这不起作用(我期待那样),因为@OrderList被解释为字符串(例如“1,2,3”)而不是长值列表。 (我改编自这里的代码:Passing a list/array to SQL Server stored procedure

我希望尽可能避免通过纯VBA代码处理此问题(即动态地将值列表分配给我的应用程序中硬编码的查询)。我知道如果这是不可能的。

有任何线索吗?

1 个答案:

答案 0 :(得分:1)

您可以动态创建查询语句字符串。在SQL Server中,您可以拥有一个返回值为TABLE的函数,并将该函数内联调用,就像它是一个表一样。或者在JET中,您还可以创建一个kludge - 一个临时表(或提供临时表功能的持久表),它包含列表中的值,每行一个,并在该表上连接。因此,查询将分为两步:1)使用INLIST值填充临时表,然后2)执行临时表上的查询连接。

       MYTEMPTABLE
       autoincrementing id
       QueryID  [some value to identify the current query, perhaps a GUID]
       myvalue  one of the values in your in-list, string


      select * from foo
      inner join MYTEMPTABLE on foo.column = MYTEMPTABLE.myvalue and MYTEMPTABLE.QueryId = ?

      [cannot recall if JET allows ANDs in INNER JOIN as SQL Server does -- 
      if not, adjust syntax accordingly]

而不是

      select * from foo where foo.column IN (... )       

通过这种方式,您可以使同一个表同时处理多个查询,因为每个查询都有一个唯一的标识符。您可以在完成后删除列表中的行:

      DELETE FROM MYTEMPTABLE where QueryID = ?

P.S。有几种方法可以处理连接的数据类型问题。您可以根据需要在MYTEMPTABLE中转换字符串值,或者您可以在MYTEMPTABLE中有多个不同数据类型的列,插入并连接到正确的列:

       MYTEMPTABLE
       id
       queryid
       mytextvalue
       myintvalue
       mymoneyvalue
       etc