为什么使用@Table变量导致应用程序中出现Adodb问题?

时间:2012-06-12 05:31:49

标签: sql sql-server tsql asp-classic adodb

我有[MySp],一个存储过程。

所以请检查一下..当我运行它时,它可以工作:

 SELECT ID,Name FROM Table

但是,当我这样做时,我在应用程序端(Adodb)出现错误

 Declare @Table TABLE(ID int,Name varchar(10))

 --- Inserts into table variable ---
 INSERT INTO @Table
 SELECT ID,Name FROM Table

 --- Returns data from table variable ---
 SELECT ID,Name FROM @Table

请记住,在SQL控制台中,我得到[MySp]相同的结果,但在application / adodb代码中我收到错误。

ASP代码:

Set oRS = Server.CreateObject("Adodb.Recordset")
oRS.Open "[MySp]", Conn
If oRS.EOF Then...  <--Gives an error

 ADODB.Recordset error '800a0e78'
 Operation is not allowed when the object is closed. 

当我在SQL中使用Table变量时,有谁知道为什么我会收到此错误?

2 个答案:

答案 0 :(得分:7)

尝试在存储过程的顶部添加SET NOCOUNT ON

我有一个模糊的回忆,ADO过去常常对插入/更新/删除的结果数量感到困惑。

E.g:

CREATE PROCEDURE MySP
AS

SET NOCOUNT ON

Declare @Table TABLE(ID int,Name varchar(10))

 --- Inserts into table variable ---
 INSERT INTO @Table
 SELECT ID,Name FROM Table

 --- Returns data from table variable ---
 SELECT ID,Name FROM @Table

答案 1 :(得分:0)

我有一个稍微复杂(但相似)的问题,不涉及存储过程。

以为如果有人发现自己处于类似的位置,我会分享。

<强> 问题

<强> SQL:

DECLARE @a (
Alpha VARCHAR(10),
Beta INT
);
INSERT @a VALUES
('A', 1)

DECLARE @b (
Gamma DATE,
Delta INT
);
INSERT @b VALUES
('2014-01-01', 1)

SELECT *
FROM @a a
JOIN @b b ON a.Beta = b.Delta

<强> VBA:

Sub GetData()
    Dim sSql
    Dim oConnection As New ADODB.Connection
    Dim oRecordSet As New ADODB.Recordset

    Call oRecordSet.Open(sSqlQuery, oConnection, adOpenStatic, adLockReadOnly)
    Call oConnection.Open("Provider=SQLOLEDB.1;Server=MyServer;Database=MyDB;Trusted_Connection=Yes;")

    sSql = <as Above>

    Call oRecordSet.Open(sSql, oConnection, adOpenStatic, adLockReadOnly)

    If oRecordSet.RecordCount > 0 Then
        ' DO STUFF WITH DATA
    End If

    ' Close objects
    oConnection.Close
    oRecordSet.Close
End Sub

<强>

<强> SQL_1

CREATE TABLE #a (
Alpha VARCHAR(10),
Beta INT
);
INSERT #a VALUES
('A', 1)

<强> SQL_2

CREATE TABLE #b (
Gamma DATE,
Delta INT
);
INSERT #b VALUES
('2014-01-01', 1)

<强> SQL_3

SELECT *
FROM #a a
JOIN #b b ON a.Beta = b.Delta

<强> SQL_4

DROP TABLE #a;

<强> SQL_5

DROP TABLE #b;

<强> VBA

Sub GetData()
    Dim sSql
    Dim oConnection As New ADODB.Connection
    Dim oRecordSet As New ADODB.Recordset

    Call oConnection.Open("Provider=SQLOLEDB.1;Server=MyServer;Database=MyDB;Trusted_Connection=Yes;")

    sSql = <SQL_1>
    Call oConnection.Execute(sSql)

    sSql = <SQL_2>
    Call oConnection.Execute(sSql)

    sSql = <SQL_3>
    Call oRecordSet.Open(sSql, oConnection, adOpenStatic, adLockReadOnly)
    If oRecordSet.RecordCount > 0 Then
        ' DO STUFF WITH DATA
    End If

    sSql = <SQL_4>
    Call oConnection.Execute(sSql)

    sSql = <SQL_5>
    Call oConnection.Execute(sSql)

    oConnection.Close
    oRecordSet.Close
End Sub

<强> 解释

基本上我的理解是VBA尝试在初始INSERT之后返回结果,因此将它分成单独的命令(Executes)并且只在查询我们想要的数据时打开记录集似乎可以解决问题。 / p>

这方面的另一个问题是我需要使用临时表(我实际上并没有意识到我有权这样做,因为它是一个实时数据库而我之前从未使用过这些表)因为我相信变量表会我打第二次电话时已经消失了。

其他需要注意的事项

  • 确保您在完成所有操作后才关闭连接(最初我从每个单独的函数调用每个命令,并且每次都打开/关闭连接而不考虑它)。
  • 确保删除末尾的临时表

希望这有助于其他人!