1

I have [MySp], A stored procedure.

So check this out.. when I run this it works:

 SELECT ID,Name FROM Table

But, When I do this, I get an error on the application side (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

Keep in mind, in SQL Console i get the same results for [MySp], but in the application/adodb code i get errors.

ASP Code:

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. 

Does anyone know why I'm getting this error when I use Table variables in SQL?

4

2 回答 2

8

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

我有一个模糊的回忆,ADO 曾经对插入/更新/删除返回的结果计数感到困惑。

例如:

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
于 2012-06-12T06:33:25.677 回答
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 之后取回结果,因此将其分成单独的命令(执行)并仅在我们查询所需数据时打开记录集似乎可以解决问题。

一个附带问题是我需要使用临时表(我实际上并没有意识到我有权限这样做,因为它是一个实时数据库而且我以前从未使用过这些),因为我相信变量表会消失我打第二个电话的时间。

其他需要注意的事项

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

希望这对其他人有帮助!

于 2014-10-24T08:58:48.490 回答