让ADO生成临时存储过程的参数?

时间:2014-05-29 17:21:04

标签: sql-server vba vb6 ado

我正在尝试让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?

3 个答案:

答案 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),切换到tempdbEXEC 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 = intYourValuecmd.Execute之前