我正在尝试让ADO识别SQL Sever上存储过程的参数。如果我使用普通的存储过程执行此操作,它可以正常工作:
conn.Execute "create proc NormalSP (@i int output) as set @i = 3"
cmd.CommandType = adCmdStoredProc
cmd.ActiveConnection = conn
cmd.CommandText = "NormalSP"
cmd.Parameters.Refresh 'parameters list now has @RETURN_VALUE and @i
cmd.Execute
Debug.Print cmd("@i")
但是,如果我使用临时存储过程尝试相同的操作,则无法获取参数:
conn.Execute "create proc #TempSP (@i int output) as set @i = 3"
cmd.CommandType = adCmdStoredProc
cmd.ActiveConnection = conn
cmd.CommandText = "#TempSP"
cmd.Parameters.Refresh 'parameters list remains empty
cmd.Execute 'error: command expects parameter '@i', which was not supplied
Debug.Print cmd("@i") 'error: item cannot be found in the collection
我需要获得Parameters.Refresh
使用临时SP,还需要使用普通SP?
答案 0 :(得分:1)
问两个黑盒子(传统的ADO,OLEDB / ODBC提供商)为什么他们不喜欢你对上下文应该暴露的解释不太可能提供一个非常令人满意的答案,但由于最初的意图不清楚。 ..
假设您可以接受一个短暂的全局临时存储过程来询问它的临时参数(并且与上面的推文相反),只需首先连接到正确的数据库:
完整,重复安全的示例(使用SQL 2012本机客户端):
Public Sub DoITemporarilyHaveParametersForADO()
Dim conn As ADODB.Connection
Dim cmd As ADODB.Command
Dim prm As ADODB.Parameter
Set conn = New ADODB.Connection
Set cmd = New ADODB.Command
conn.ConnectionString = "Driver={SQL Server Native Client 11.0};Server=(local);Database=tempdb;Trusted_Connection=yes;"
conn.CursorLocation = adUseServer
conn.Open
conn.Execute "IF OBJECT_ID('TempSP') IS NOT NULL DROP PROC TempSP"
conn.Execute "create proc TempSP (@i int output) as set @i = 3;"
cmd.ActiveConnection = conn
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "TempSP"
cmd.Parameters.Refresh
For Each prm In cmd.Parameters
Debug.Print prm.Name & ": " & prm.Value
Next prm
Debug.Print "cmd.Parameters.Count: " & cmd.Parameters.Count
cmd.Execute
Debug.Print cmd("@i")
conn.Execute "IF OBJECT_ID('TempSP') IS NOT NULL DROP PROC TempSP"
conn.Close
Set prm = Nothing
Set cmd = Nothing
Set conn = Nothing
End Sub
立即窗口输出:
@RETURN_VALUE:
@i:
cmd.Parameters.Count: 2
3
一些有用的clarification from MSFT :
临时存储过程在连接到早期版本时很有用 不支持重用执行的SQL Server版本 Transact-SQL语句或批处理的计划。应用连接 SQL Server 2000及更高版本应该使用sp_executesql系统 存储过程而不是临时存储过程。
....
如果直接在中创建没有#或##前缀的存储过程 在tempdb数据库中,存储过程会自动删除 当SQL Server关闭时,因为每次都会重新创建tempdb SQL Server已启动。存在直接在tempdb中创建的过程 即使在创建连接终止后也是如此。
当然,如果你在第27行的VBA示例中抛出一个断点,请翻转到SSMS,连接到(local)
,切换到tempdb
和EXEC TempSP
,你将被告知
程序或功能' TempSP'期望参数' @ i',但不是 提供。
而不是
无法找到存储过程' TempSP'。
在样本执行之前和之后。
答案 1 :(得分:0)
尝试将其设为全局临时SP:
conn.Execute "create proc ##TempSP (@i int output) as set @i = 3"
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "##TempSP"
cmd.Parameters.Refresh 'parameters list remains empty
cmd.Execute
Debug.Print cmd("@i")
答案 2 :(得分:0)
放cmd.Parameters(1).Value = intYourValue
在cmd.Execute
之前