Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server Excel VBA调用SQL存储过程(日期参数-无结果!)_Sql Server_Excel_Adodb_Vba - Fatal编程技术网

Sql server Excel VBA调用SQL存储过程(日期参数-无结果!)

Sql server Excel VBA调用SQL存储过程(日期参数-无结果!),sql-server,excel,adodb,vba,Sql Server,Excel,Adodb,Vba,通过在存储过程中添加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

通过在存储过程中添加
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
正如我所说,仅使用第一个参数本身,我就可以按预期将结果粘贴到工作表中。当我注释掉这一行并尝试使用两个日期参数运行时,我什么也得不到

代码运行时没有错误,但显示一个空工作表。我有一种感觉,这与日期格式有关,但我不确定如何将日期输入到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()
这似乎以正确的格式传递日期值,但仍然返回一个空记录集。与之前一样,使用单个值VarChar测试相同的字符串也可以。只是当我使用2个日期参数时

在菜单中单击“执行”时由SSMS生成的工作SQL查询-

从VBA复制的工作查询(单个批号)

来自VBA的非工作查询(尝试在此日期之后提取所有批次)

将CreateParameter中的
范围(“C2”)
替换为
格式(范围(“C2”).值,“yyyymmdd”)

日期格式yyyymmdd是sql server始终可以识别的唯一格式,与您的区域设置无关

在不使用参数的情况下构造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()  

设置日期时间数据列的numberformat如下所示

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 WSP1=工作表(“提取”)
使用WSP1
如果rs.EOF=False,则.Cells(1,1).CopyFromRecordset rs

.Columns(“c”).NumberFormat=“yyyy-mm-dd”'您是否在SSMS中测试了带有参数的SP?是的。输入参数作为yyyy mm dd返回结果。我只是不确定如何强制VBA在ADODB中以这种格式传递日期值(我认为这就是问题所在)。您可以通过传递硬编码参数来测试理论。如果修复了此问题,请使用VBA确保以YYYY-MM-DD的形式传递。不确定如何硬编码此问题。已尝试#2017-07-17#但它只是自动更正为vba格式。和工作表(“摘录”)。UsedRange.clearcontents比工作表(“摘录”)。UsedRange.DeleteHi@Dy.Lee更有效。这似乎没有什么区别。我真的很困惑为什么我的VBA不能工作。对不起,它不会产生错误。但我仍然没有得到任何返回值。当我单步执行代码并将鼠标移到其中一个参数上时,它仍然以原始excel格式而不是此格式显示日期。另一种方法是(我总是这样做)构造整个查询字符串,用VBA执行,然后将其分配给
。CommandText
我与前面的查询做过类似的操作,但从来没有使用带参数的存储过程。再多的搜索也没有给我展示过一个例子,有人在一个字符串内做这件事,你认为这可行吗?我将研究在SP中将参数设置为字符串并在SQL中进行转换。当然是这样,exec DB.MyStoredProc'parm1'、'parm2'、'parmN'
就可以了
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