1

[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でテーブル変数を使用するとこのエラーが発生する理由を誰かが知っていますか?

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の後に結果を取り戻そうとするため、VBAを個々のコマンド(実行)に分割し、必要なデータをクエリしているときにのみレコードセットを開くとうまくいくようです。

これの副次的な問題は、変数テーブルが2回目の電話をかけたとき。

その他の注意事項

  • すべてを実行した後でのみ接続を閉じるようにしてください(最初は、各コマンドを別々の関数から呼び出し、毎回接続を考えずに開いたり閉じたりしていました)
  • 最後に一時テーブルを削除してください

これが他の誰かに役立つことを願っています!

于 2014-10-24T08:58:48.490 に答える