2011-04-03 91 views
0

我目前正在编写基于Jet数据库后端的基于VBA的Excel加载项(我使用Office 2003套件 - 问题会无论如何,与最新版本的Office一样)。Jet引擎(访问):将值列表传递给存储过程

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

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

表tblOrders:订单LONG,订购日期DATE,(其它领域)

最终用户可以选择一个或多个OrderIDs,在表单中显示的 - 他/她刚必须勾选相关OrderID的复选框,以了解其详细信息(OrderDate等)。

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

因为我事先不知道有多少的OrderID他/她会选择做什么,我可以动态地通过级联基于表单上做出的选择WHERE子句创建的VBA代码的SQL查询

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

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

现在,如果我把这个简单的查询到存储过程中,这样我可以动态传递OrderIDs我想要显示的列表中,我应该怎么办?我已经尝试过的东西,如:

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代码处理这个问题(即动态地将值列表分配给在我的应用程序中硬编码的查询)。我会理解,如果这是不可能的。

任何线索?

+0

只是一个额外的精度:我已经看了以下线索“将一组ID传递给存储过程”以及这里给出的解释:“http://www.sommarskog.se/arrays-in-sql.html”,但这些仅适用于SQL Server。 – VBAFred 2011-04-03 13:38:29

回答

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