使用VBA和SQL Server 2012使用RollbackTrans执行存储过程

时间:2016-09-10 03:58:14

标签: sql-server excel-vba tsql transactions vba

我想使用VBA Excel执行插入存储过程,但是我遇到了一些问题。基本上,我希望通过执行存储过程10次并插入事务来插入100行相同的数据。

  • 如果我执行VBA运行我的VBA代码没有For循环那么我的VBA代码运行正常,没有错误
  • 当我插入For循环时,我收到错误表明我有太多协议。我试图移动For循环,但问题无法解决。
  

过程或函数示例指定了太多参数   -2147217900关闭对象时不允许操作。 3704

我的问题:如何运行具有回滚事务功能的插入存储过程?或者我是否必须编辑SQL Server存储过程中的Rollback Trans ~~>如果是这样,我如何重写我的代码来执行新的SQL?

我有一张表Test.Sample

Create Table Test.Sample
(
    ID int identity(1,1) primary key,
    Col1 varchar(10),
    Col2 varchar(10)
)

使用以下存储过程来插入数据

CREATE PROCEDURE Sample
    @Col1 varchar(10),
    @Col2 varchar(10)
AS
   SET NOCOUNT ON

    INSERT INTO [Test].[Sample] (Col1, Col2)
    VALUES (@Col1, @Col2)

当我运行单个插入时,以下代码可以正常工作

Private Sub Test()
                    Dim con As ADODB.Connection
                    Dim cm As ADODB.Command
                    Set con = New ADODB.Connection
                    Set cm = New ADODB.Command
                    Dim pm As ADODB.Parameter
                    Dim i As Integer
On Error GoTo 1
                    con.Open connString
                    con.BeginTrans
'For i = 1 To 10 ~~~~ code will return an error if this is active
                    With cm
                    .ActiveConnection = con
                    .CommandType = adCmdStoredProc
                    .CommandText = "sales.spInsertSalesRequestPart"
                        .Parameters.Append .CreateParameter("@Col1", adVarChar, adParamInput, 10, "TEST")
                        .Parameters.Append .CreateParameter("@Col2", adVarChar, adParamInput, 10, "TEST")
                        .Execute
                   End With

'Next i
                   con.CommitTrans
                   con.Close
                   Exit Sub

1:
        With con
            con.RollbackTrans
            con.Close
        End With
    End If
End Sub

2 个答案:

答案 0 :(得分:0)

如果您要使用相同的参数,那么您可以在sql过程中使用该事务并进行循环

CREATE PROCEDURE Sample
@Col1 varchar(10),
@Col2 varchar(10)
AS
SET NOCOUNT ON

begin tran
declare @i int = 1
while @i <= 10 
begin
INSERT INTO [Test].[Sample] (Col1, Col2)
VALUES (@Col1, @Col2)
set @i=@i+1
end
commit tran

但是我相信你可能会为你的vb或c#中的每个循环传递不同的变量,在这种情况下你可以将all打包成一个表变量并将其作为单个表变量传递,你可以在sproc中执行事务< / p>

答案 1 :(得分:0)

考虑在每次迭代时重置命令对象cmd。正如@ YowE3K评论,你越来越多地为每个调用添加参数,因此错误太多参数

...
con.BeginTrans

For i = 1 To 10
    Set cm = New ADODB.Command

    With cm
       .ActiveConnection = con
       .CommandType = adCmdStoredProc
       .CommandText = "sales.spInsertSalesRequestPart"
       .Parameters.Append .CreateParameter("@Col1", adVarChar, adParamInput, 10, "TEST")
       .Parameters.Append .CreateParameter("@Col2", adVarChar, adParamInput, 10, "TEST")
       .Execute
    End With

Next i

con.CommitTrans
...