我在MS Access数据库中有几个查询。其中一些使用参数。我在VBA中使用以下代码为查询提供以下参数:
VBA
Dim startDate As Date
Dim endDate As Date
Dim dbs As DAO.Database
Dim qdf As DAO.QueryDef
Dim rst As DAO.Recordset
If IsNull(Me.dpFrom) Or IsNull(Me.dpTo) Then
MsgBox "Please select a date!"
ElseIf (Me.dpFrom.Value > Me.dpTo.Value) Then
MsgBox "Start date is bigger than the end date!"
Else
startDate = Me.dpFrom.Value
endDate = Me.dpTo.Value
Set dbs = CurrentDb
'Get the parameter query
Set qdf = dbs.QueryDefs("60 Dec")
'Supply the parameter value
qdf.Parameters("startDate") = startDate
qdf.Parameters("endDate") = endDate
'Open a Recordset based on the parameter query
Set rst = qdf.OpenRecordset()
'Check to see if the recordset actually contains rows
If Not (rst.EOF And rst.BOF) Then
rst.MoveFirst 'Unnecessary in this case, but still a good habit
Do Until rst.EOF = True
'Save contact name into a variable
Me.tbBUDdec.Value = rst!Som
rst.MoveNext
Me.tbLEYdec.Value = rst!Som
rst.MoveNext
Me.tbMDRdec.Value = rst!Som
rst.MoveNext
Me.tbODCdec.Value = rst!Som
rst.MoveNext
Loop
Else
MsgBox "There are no records in the recordset."
End If
rst.Close 'Close the recordset
Set rst = Nothing 'Clean up
访问查询
PARAMETERS startDate DateTime, endDate DateTime;
SELECT WarehouseCode, COUNT(DeliveryPoint) AS Som
FROM [50 resultaat]
WHERE EntryDate between [startDate] and [endDate]
GROUP BY WarehouseCode;
这很好用。但是,我现在尝试使用相同的代码来调用SQL服务器的直通查询。此查询使用不同的语法来声明和设置参数:
SQL Server查询
DECLARE @InvLineEntryDateBegin AS date
DECLARE @InvLineEntryDateEnd AS date
SET @InvLineEntryDateBegin = '2017-01-01'
SET @InvLineEntryDateEnd = '2017-05-31'
Select WarehouseCode, Count(PickOrderNr) as Som
FROM ( bla bla bla ...
我无法让我的VBA代码使用不同的SQL语法。我已经阅读了几个选项,但找不到具体的东西。有没有人有这种查询结构的经验?
换句话说:在VBA中,如何在SQL服务器上查询的存储过程中插入参数?
答案 0 :(得分:3)
考虑构建一个驻留在SQL Server中的命名存储过程,并让MS Access调用它使用ADO传递参数,而不是当前的DAO方法,因为您需要参数化。然后将结果绑定到记录集:
SQL Server存储过程
CREATE PROCEDURE myStoredProc
@InvLineEntryDateBegin DATE = '2017-01-01',
@InvLineEntryDateEnd DATE = '2017-05-31'
AS
BEGIN
SET NOCOUNT ON;
SELECT WarehouseCode, Count(PickOrderNr) as Som
FROM ( bla bla bla ... ;
END
<强> VBA 强>
' SET REFERENCE TO Microsoft ActiveX Data Object #.# Library
Dim conn As ADODB.Connection, cmd As ADODB.Command, rst As ADODB.Recordset
Dim startDate As Date, endDate As Date
If IsNull(Me.dpFrom) Or IsNull(Me.dpTo) Then
MsgBox "Please select a date!", vbCritical, "MISSING DATE"
Exit Sub
End if
If (Me.dpFrom.Value > Me.dpTo.Value) Then
MsgBox "Start date is bigger than the end date!", vbCritical, "INCORRECT RANGE"
Exit Sub
End if
startDate = Me.dpFrom.Value: endDate = Me.dpTo.Value
' OPEN CONNECTION
Set conn = New ADODB.Connection
conn.Open "DRIVER={SQL Server};server=servername;database=databasename;UID=username;PWD=password;"
' OPEN/DEFINE COMMAND OBJECT
Set cmd = New ADODB.Command
With cmd
.ActiveConnection = conn
.CommandText = "myStoredProc"
.CommandType = adCmdStoredProc
' BIND PARAMETERS
.Parameters.Append .CreateParameter("@InvLineEntryDateBegin", adDate, adParamInput, 0, startDate)
.Parameters.Append .CreateParameter("@InvLineEntryDateEnd", adDate, adParamInput, 0, endDate)
En With
' BIND RESULTS TO RECORDSET
Set rst = cmd.Execute
...
答案 1 :(得分:2)
只需在Access中创建pass-through查询并保存即可。
确保PT查询有效。它可能看起来像:
Exec MySpName'2017-01-01','2017-05-31'
再次:100%确保在Access中单击它时查询有效。此时您没有编写任何VBA代码。
一旦您完成了以上查询工作,那么在VBA中您可以执行此操作:
Dim strStartDate As String
Dim strEndDate As String
Dim strSQL As String
strStartDate = "'" & Format(Me.dpFrom, "yyyy-mm-dd") & "'"
strEndDate = "'" & Format(Me.dpTo, "yyyy-mm-dd") & "'"
strSQL = "exec MyStoreProc " & strStartDate & "," & strEndDate
With CurrentDb.QueryDefs("QryMyPass")
.SQL = strSQL
Set rst = .OpenRecordset
End With
答案 2 :(得分:0)
如果我没记错,在传递查询中,您将查询定义直接传递给将要运行的引擎。因此,您必须使用SQL Server语法来代替Access VBA语法。试一试。
此外,存储过程也是如此。使用您通过SSMS执行的语法。
“exec sp_mysp var1 var2”等等。
答案 3 :(得分:0)
Albert Kallal的回复是现场。谢谢Albert。我在注册后试图发表评论,但是......没有足够的评论来评论......希望这可以通过....
我唯一改变的是....
我替换了Set rst = .OpenRecordset
与... CurrentDb.QueryDefs("q_PTO_SubmitNewRequest").Execute
再次感谢发布此内容。这真的是一个巨大的帮助。几年前我有很多复杂的.adp项目,我正在与需要类似功能的客户合作。看起来我可以使用传递查询来镜像.adp功能。非常酷:))
使用CurrentDb.QueryDefs("q_PTO_SubmitNewRequest")
.SQL = strSQL
结束
CurrentDb.QueryDefs("q_PTO_SubmitNewRequest").Execute