代码之家  ›  专栏  ›  技术社区  ›  Span

使用表变量的SQL Server 2005存储过程未将结果集返回到VB6应用程序

  •  1
  • Span  · 技术社区  · 16 年前

    无论是从managementstudio还是从testc应用程序调用,该过程都能正常工作。但是,从我的VB6应用程序调用时,不会返回结果集。但是,仍将执行所有数据库更新。

    我曾经尝试过用事务和不带事务、用TRY…CATCH和不带事务来编写存储过程,并且两者都是。我尝试过事务隔离的各种组合。不会引发异常,事务将始终提交。我还在select语句中使用了WITH(NOLOCK)提示。如果我不更新表,它就会工作。如果我省略了对局部变量的赋值,而改为硬编码一个值,它就会工作。如果我只是简单地使用select,我将把变量放在哪里,它将不起作用。

    有趣的是,如果我向过程中添加一些随机选择语句,它将返回结果集。我甚至可以从分配给变量的同一条记录中选择相同的字段,而没有任何问题。但它仍然不会返回我想要的结果集。

    我试过重新启动我的SQL Server(2005版本9.0.4053),重新启动我的机器,我试过打开和关闭NOCOUNT,我基本上没有主意了。

    编辑-VB调用和存储过程签名的详细信息:
    我会尽量给出一个好的描述,我可以不公布实际的代码。我实际上是发布了另一个开发谁与我一起工作,所以请与我忍受这个。

    VB6调用:

     With cmdCommand
            .ActiveConnection = cnnConn
            .CommandType = adCmdStoredProc
            .CommandText = "uspMyStoredProcedure"
            .Parameters("@strParam1") = strFunctionParameter1
            .Parameters("@bolParam2") = bolFunctionParameter2
            .Execute
     End With
    
    MyResultSet.CursorLocation = adUseClient
    MyResultSet.Open cmdCommand, , adOpenStatic, adLockReadOnly
    

    CREATE PROCEDURE uspMyStoredProcedure
        @strParam1 NVARCHAR(XX),
        @bolParam2 BIT
    
    AS
    BEGIN
        SET NO COUNT ON
    
        DECLARE @var1 NVARCHAR(XX),
        @var2 NVARCHAR(XX),
        @var3 NVARCHAR(XX),
        @var4 INT,
        @var5 BIT
        --DECLARATION OF OTHER VARIABLES
    
    
        DECLARE  @varTableVariable TABLE
        (
          strTblVar1 NVARCHAR(XX) ,
          intTblVar2 INT ,
          strTblVar3 NVARCHAR(XX) ,
          bolTblVar4 BIT ,
          datTblVar5 DATETIME
        )
    
        SELECT @var1 = t.Field1, @var2 = t.Field2
        FROM Table1 t
        WHERE t.ID = @strParam1
    
        SELECT @var3 = t2.Field1
        FROM Table2 t2
    
        IF (Condition)
        BEGIN
            SET @var4 = 1
            IF (Condition)
            BEGIN
                --SET SOME VARIABLES
            END
            ELSE
            BEGIN
                UPDATE TABLE1
                SET Field3 = @var4
                WHERE Field1 = @strParam1
            END
        END
        ELSE
        BEGIN
            IF(Condition)
            BEGIN
                SELECT @var5 = ISNULL(Condition)
                FROM Table3 t3
                WHERE t3.Field = @strParam1
    
                --SET SOME MORE VARIABLES
            END
        END
    
        IF(Condition)
        BEGIN
            UPDATE Table1
            SET Field5 = @SomeVariable
            WHERE Field1 = @strParam1
        END
    
        INSERT INTO Table4 (Field1, Field2, Field3)
        SELECT @SomeVar1, @someVar2, @SomeVar3
        FROM SomeOtherTable
        WHERE Field3 = @someVariable
    
        IF(Condition)
        BEGIN
            INSERT INTO @varTableVariable (strTblVar1, intTblVar2, 
            strTblVar3, bolTblVar4,  datTblVar5 )
            VALUES (@SomeVar1, @SomeVar2, @SomeVar3, @SomeVar4, @SomeVar5)
        END
    
    SELECT *
    FROM @varTableVariable
    
    END
    

    所以,基本上,这个过程需要两个参数。它执行许多简单的操作—从两个不同的表中插入和选择数据、更新表以及将行插入表变量。

    在VB6应用程序中,我们只得到一个空记录集。

    我们刚刚发现,如果我们创建一个任意表来保存最终select语句返回的数据,而不是使用表变量,那么这个过程就可以工作了。。。

    1 回复  |  直到 16 年前
        1
  •  0
  •   Span    16 年前

    我们发现,由于从VB6调用存储过程的方式,存储过程实际上执行了两次:

    With cmdCommand
            .ActiveConnection = cnnConn
            .CommandType = adCmdStoredProc
            .CommandText = "uspMyStoredProcedure"
            .Parameters("@strParam1") = strFunctionParameter1
            .Parameters("@bolParam2") = bolFunctionParameter2
            .Execute 
     End With
    
    MyResultSet.CursorLocation = adUseClient
    MyResultSet.Open cmdCommand, , adOpenStatic, adLockReadOnly 
    

    我们发现最后一行:“MyResultSet.Open cmdCommand…”也是 再次执行存储过程。

    由于存储过程的功能本质上是激活和停用一个警报,通过执行两次,我们得到的激活和停用是同时发生的,因此没有返回结果集。

    希望这能帮助避免其他人陷入这样的困境。