Excel VBA 调用 SQL 存储过程(日期参数 - 无结果!)
Excel VBA To Call SQL Stored Procedure (Date parameter - No results!)
我终于通过在我的存储过程中添加 Set NOCOUNT ON
使这段代码工作。不过,当我使用日期作为参数时,我无法获得结果。
代码如下-
Sub Button1_Click()
Dim con As ADODB.Connection
Dim cmd As ADODB.Command
Dim rs As ADODB.RecordSet
Dim WSP1 As Worksheet
Set con = New ADODB.Connection
Set cmd = New ADODB.Command
Set rs = New ADODB.RecordSet
'''Clear extract area'''
Worksheets("Extract").UsedRange.Delete
'''Log into SQL Server'''
con.Open "Provider = SQLOLEDB;" & _
"Data Source = MySource;" & _
"Initial Catalog = MyDatabase;" & _
"User ID = MyUser;" & _
"Password = MyPassword;"
cmd.ActiveConnection = con
'''Set up parameters for stored procedure'''
'cmd.Parameters.Append cmd.CreateParameter("lot", adVarChar, adParamInput, 7, Range("C4"))
cmd.Parameters.Append cmd.CreateParameter("startDate", adDBTimeStamp, adParamInput, Range("C2"))
cmd.Parameters.Append cmd.CreateParameter("endDate", adDBTimeStamp, adParamInput, Range("C3"))
'adDBTimeStamp
cmd.CommandText = "DB.MyStoredProc"
Set rs = cmd.Execute(, , adCmdStoredProc)
Set WSP1 = Worksheets("Extract")
WSP1.Activate
If rs.EOF = False Then WSP1.Cells(1, 1).CopyFromRecordset rs
rs.Close
Set rs = Nothing
Set cmd = Nothing
con.Close
Set con = Nothing
End Sub
正如我所说,仅使用第一个参数本身,我就可以按预期将结果粘贴到我的工作表中。当我评论该行并尝试使用两个日期参数 运行 时,我什么也没得到。
代码 运行s 没有错误,但显示一个空工作表。我觉得这与日期格式有关,但我不确定如何根据需要将日期输入 SQL。
有人可以帮忙吗?
---更新---
我试过像这样设置我的参数 -
Set prm = cmd.CreateParameter("startDate", adDate, adParamInput)
cmd.Parameters.Append prm
cmd.Parameters("startDate").Value = "2017-07-17"
Set prm = cmd.CreateParameter("endDate", adDate, adParamInput)
cmd.Parameters.Append prm
cmd.Parameters("endDate").Value = "2017-07-19"
但是 Excel VBA 似乎仍在以 dd/mm/yyyy 格式发送日期!
---更新2---
根据@avb 的回答,我更改了我的代码以包含以下内容 -
Dim sql As String
sql = "exec DB.myStoredProc '__dateParameter1__', '__dateParameter2__' ;"
sql = Replace(sql, "__dateParameter1__", Format(Range("C2").Value, "yyyy-mm-dd"))
sql = Replace(sql, "__dateParameter2__", Format(Range("C3").Value, "yyyy-mm-dd"))
cmd.CommandText = sql
Set rs = cmd.Execute()
这似乎以正确的格式传递了日期值,但仍然是 returns 一个空记录集。和以前一样,使用单个值 VarChar 测试相同的字符串工作正常。就是我用2个日期参数的时候。
单击菜单中的 'Execute' 时由 SSMS 生成的工作 SQL 查询 -
DECLARE @return_value int
EXEC @return_value = [DB].[myStoredProc]
@startDate = N'2017-07-20'
SELECT 'Return Value' = @return_value
GO
从 VBA 复制的工作查询(提取单个批号)
exec DB.myStoredProc '4238176' ;
来自 VBA 的非工作查询(试图提取此日期之后的所有批次)
exec DB.myStoredProc '2017-07-20' ;
将CreateParameter中的Range("C2")
替换为
Format(Range("C2").Value, "yyyymmdd")
日期格式 yyyymmdd 是唯一一种 sql 服务器始终可以识别的格式,无论您的语言环境如何。
在不使用参数的情况下构造 sql 语句:
Dim sql As String
sql = "exec DB.MyStoredProc '__dateParameter__' ;"
sql = Replace(sql, "__dateParameter__", Format(Range("C2").Value, "yyyymmdd"))
cmd.CommandText = sql
Set rs = cmd.Execute()
最后看来存储过程有第一个可选参数是日期以外的其他值,所以正确答案是:
Dim sql As String
sql = "exec DB.MyStoredProc null, '__dateParameter__' ;"
sql = Replace(sql, "__dateParameter__", Format(Range("C2").Value, "yyyymmdd"))
cmd.CommandText = sql
Set rs = cmd.Execute()
像这样设置日期时间数据列的数字格式。
Set WSP1 = Worksheets("Extract")
With WSP1
If rs.EOF = False Then .Cells(1, 1).CopyFromRecordset rs
.Columns("c").NumberFormat = "yyyy-mm-dd" '<~~~ datetime data column c
End With
我终于通过在我的存储过程中添加 Set NOCOUNT ON
使这段代码工作。不过,当我使用日期作为参数时,我无法获得结果。
代码如下-
Sub Button1_Click()
Dim con As ADODB.Connection
Dim cmd As ADODB.Command
Dim rs As ADODB.RecordSet
Dim WSP1 As Worksheet
Set con = New ADODB.Connection
Set cmd = New ADODB.Command
Set rs = New ADODB.RecordSet
'''Clear extract area'''
Worksheets("Extract").UsedRange.Delete
'''Log into SQL Server'''
con.Open "Provider = SQLOLEDB;" & _
"Data Source = MySource;" & _
"Initial Catalog = MyDatabase;" & _
"User ID = MyUser;" & _
"Password = MyPassword;"
cmd.ActiveConnection = con
'''Set up parameters for stored procedure'''
'cmd.Parameters.Append cmd.CreateParameter("lot", adVarChar, adParamInput, 7, Range("C4"))
cmd.Parameters.Append cmd.CreateParameter("startDate", adDBTimeStamp, adParamInput, Range("C2"))
cmd.Parameters.Append cmd.CreateParameter("endDate", adDBTimeStamp, adParamInput, Range("C3"))
'adDBTimeStamp
cmd.CommandText = "DB.MyStoredProc"
Set rs = cmd.Execute(, , adCmdStoredProc)
Set WSP1 = Worksheets("Extract")
WSP1.Activate
If rs.EOF = False Then WSP1.Cells(1, 1).CopyFromRecordset rs
rs.Close
Set rs = Nothing
Set cmd = Nothing
con.Close
Set con = Nothing
End Sub
正如我所说,仅使用第一个参数本身,我就可以按预期将结果粘贴到我的工作表中。当我评论该行并尝试使用两个日期参数 运行 时,我什么也没得到。
代码 运行s 没有错误,但显示一个空工作表。我觉得这与日期格式有关,但我不确定如何根据需要将日期输入 SQL。
有人可以帮忙吗?
---更新--- 我试过像这样设置我的参数 -
Set prm = cmd.CreateParameter("startDate", adDate, adParamInput)
cmd.Parameters.Append prm
cmd.Parameters("startDate").Value = "2017-07-17"
Set prm = cmd.CreateParameter("endDate", adDate, adParamInput)
cmd.Parameters.Append prm
cmd.Parameters("endDate").Value = "2017-07-19"
但是 Excel VBA 似乎仍在以 dd/mm/yyyy 格式发送日期!
---更新2---
根据@avb 的回答,我更改了我的代码以包含以下内容 -
Dim sql As String
sql = "exec DB.myStoredProc '__dateParameter1__', '__dateParameter2__' ;"
sql = Replace(sql, "__dateParameter1__", Format(Range("C2").Value, "yyyy-mm-dd"))
sql = Replace(sql, "__dateParameter2__", Format(Range("C3").Value, "yyyy-mm-dd"))
cmd.CommandText = sql
Set rs = cmd.Execute()
这似乎以正确的格式传递了日期值,但仍然是 returns 一个空记录集。和以前一样,使用单个值 VarChar 测试相同的字符串工作正常。就是我用2个日期参数的时候。
单击菜单中的 'Execute' 时由 SSMS 生成的工作 SQL 查询 -
DECLARE @return_value int
EXEC @return_value = [DB].[myStoredProc]
@startDate = N'2017-07-20'
SELECT 'Return Value' = @return_value
GO
从 VBA 复制的工作查询(提取单个批号)
exec DB.myStoredProc '4238176' ;
来自 VBA 的非工作查询(试图提取此日期之后的所有批次)
exec DB.myStoredProc '2017-07-20' ;
将CreateParameter中的Range("C2")
替换为
Format(Range("C2").Value, "yyyymmdd")
日期格式 yyyymmdd 是唯一一种 sql 服务器始终可以识别的格式,无论您的语言环境如何。
在不使用参数的情况下构造 sql 语句:
Dim sql As String
sql = "exec DB.MyStoredProc '__dateParameter__' ;"
sql = Replace(sql, "__dateParameter__", Format(Range("C2").Value, "yyyymmdd"))
cmd.CommandText = sql
Set rs = cmd.Execute()
最后看来存储过程有第一个可选参数是日期以外的其他值,所以正确答案是:
Dim sql As String
sql = "exec DB.MyStoredProc null, '__dateParameter__' ;"
sql = Replace(sql, "__dateParameter__", Format(Range("C2").Value, "yyyymmdd"))
cmd.CommandText = sql
Set rs = cmd.Execute()
像这样设置日期时间数据列的数字格式。
Set WSP1 = Worksheets("Extract")
With WSP1
If rs.EOF = False Then .Cells(1, 1).CopyFromRecordset rs
.Columns("c").NumberFormat = "yyyy-mm-dd" '<~~~ datetime data column c
End With