如何在SQL(Excel)中传递参数进行查询

时间:2011-03-25 15:43:52

标签: sql excel parameter-passing

我将Excel链接到Sql并且工作正常 - 我编写了一些SQL脚本并且效果很好。我想要做的就是将参数传递给查询。就像我每次刷新一样,我希望能够将参数(过滤条件)传递给Sql Query。 在“连接属性”中,“参数”按钮被禁用。所以我不能进行参数查询。 任何人都可以帮助我吗?

2 个答案:

答案 0 :(得分:27)

这篇文章已经足够老了,这个答案可能对OP没什么用处,但我花了很多时间试图回答同样的问题,所以我想我会用我的发现更新它。

此答案假定您已在Excel文档中具有有效的SQL查询。有很多教程可以向您展示如何在Web上完成此操作,还有很多教程可以解释如何将参数化查询添加到一个,除了似乎没有一个对于现有的OLE DB 查询有效。

所以,如果你和我一样,提交了一份带有工作查询的遗留Excel文档,但是用户希望能够根据其中一个数据库字段过滤结果,如果你像我一样,既不是一个Excel或一个SQL大师,这可能会帮助你。

对此问题的大多数网络回复似乎都表示您应该在查询中添加“?”以使Excel提示您输入自定义参数,或者将提示或单元格引用放在[括号]中参数应该在哪里是。这可能适用于ODBC查询,但它似乎不适用于OLE DB,在前一个实例中返回“没有给出一个或多个必需参数的值”,“无效列名'xxxx'”或“未知对象” 'xxxx'“在后两者中。同样,使用神秘的“参数...”或“编辑查询...”按钮也不是一个选项,因为在这种情况下它们似乎永久变灰。 (供参考,我使用的是Excel 2010,但使用的是Excel 97-2003工作簿(* .xls))

然而,我们可以做的是添加一个参数单元格和一个带有简单例程的按钮,以编程方式更新我们的查询文本。

首先,在外部数据表(或任何地方)上方添加一行,您可以在空单元格和按钮旁边放置参数提示(Developer-> Insert-> Button(Form Control)) - 您可能需要启用“开发人员”选项卡,但您可以在其他地方找到如何执行此操作),如下所示:

[Picture of a cell of prompt (label) text, an empty cell, then a button.]

接下来,在外部数据(蓝色)区域中选择一个单元格,然后打开数据 - >全部刷新(下拉列表) - >连接属性...以查看您的查询。下一节中的代码假定您的查询中已有参数(连接属性 - >定义 - >命令文本),格式为“WHERE(DB_TABLE_NAME.Field_Name ='默认查询参数')”(包括括号) )。显然,“DB_TABLE_NAME.Field_Name”和“默认查询参数”在您的代码中需要根据数据库表名,数据库值字段(列)名称以及在文档打开时搜索的一些默认值(如果你有自动刷新设置)。请记下您在下一节中需要的“DB_TABLE_NAME.Field_Name”值,以及查询的“连接名称”,可在对话框的顶部找到。

关闭“连接属性”,然后按Alt + F11打开VBA编辑器。如果您尚未使用它,请在“项目”窗口中右键单击包含按钮的工作表名称,然后选择“查看代码”。将以下代码粘贴到代码窗口中(建议复制,因为单引号或双引号很有必要)。

Sub RefreshQuery()
 Dim queryPreText As String
 Dim queryPostText As String
 Dim valueToFilter As String
 Dim paramPosition As Integer
 valueToFilter = "DB_TABLE_NAME.Field_Name ="

 With ActiveWorkbook.Connections("Connection name").OLEDBConnection
     queryPreText = .CommandText
     paramPosition = InStr(queryPreText, valueToFilter) + Len(valueToFilter) - 1
     queryPreText = Left(queryPreText, paramPosition)
     queryPostText = .CommandText
     queryPostText = Right(queryPostText, Len(queryPostText) - paramPosition)
     queryPostText = Right(queryPostText, Len(queryPostText) - InStr(queryPostText, ")") + 1)
     .CommandText = queryPreText & " '" & Range("Cell reference").Value & "'" & queryPostText
 End With
 ActiveWorkbook.Connections("Connection name").Refresh
End Sub

将“DB_TABLE_NAME.Field_Name”和“连接名称”(在两个位置)替换为您的值(需要包含双引号和空格以及等号)。

将“Cell reference”替换为参数所在的单元格(从头开始的空单元格) - mine是第一行中的第二个单元格,所以我输入“B1”(再次,双引号是必要的)

保存并关闭VBA编辑器。

在相应的单元格中输入您的参数。

右键单击按钮,将RefreshQuery子目录指定为宏,然后单击按钮。查询应该更新并显示正确的数据!

注意: 只有在查询中有连接或其他出现的等号时,才需要使用整个过滤器参数名称(“DB_TABLE_NAME.Field_Name =”),否则只需等号即可,Len()计算将是多余的。 如果您的参数包含在也用于连接表的字段中,则需要将代码中的“paramPosition = InStr(queryPreText,valueToFilter)+ Len(valueToFilter) - 1”行更改为“paramPosition = InStr”(右(.CommandText,Len(.CommandText) - InStrRev(.CommandText,“WHERE”)),valueToFilter)+ Len(valueToFilter) - 1 + InStr(.CommandText,“WHERE”)“以便它只查找valueToFilter 之后的“WHERE”。

这个答案是在datapig的“BaconBits”的帮助下创建的,我找到了查询更新的基本代码。

答案 1 :(得分:9)

这取决于您尝试连接的数据库,创建连接的方法以及您正在使用的Excel版本。 (另外,很可能是您计算机上相关ODBC驱动程序的版本。)

以下示例在我的本地计算机上使用SQL Server 2008和Excel 2007。

当我使用数据连接向导时(在功能区的“数据”选项卡上,在“获取外部数据”部分的“来自其他来源”下),我看到了您所做的相同事情:“参数”按钮被禁用,并添加了查询的参数,如select field from table where field2 = ?,导致Excel抱怨未指定参数的值,并且未保存更改。

当我使用Microsoft Query(与数据连接向导相同的位置)时,我能够创建参数,为它们指定显示名称,并在每次运行查询时输入值。启用该连接的“连接属性”,启用“参数...”按钮,可以根据需要修改和使用参数。

我还可以使用Access数据库执行此操作。使用Microsoft Query创建参与其他类型数据库的参数化查询似乎是合理的,但我现在无法轻易测试它。