2012-06-12 77 views
0

我有[MySp],一個存儲過程。爲什麼使用@Table變量會在應用程序中導致Adodb問題?

於是檢查了這一點。當我運行這個它的工作原理:

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]相同的結果,但在應用程序/ 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中使用表變量爲什麼我得到這個錯誤?

回答

7

嘗試在存儲過程的頂部添加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 
+0

那工作,謝謝!我完全錯過了這一點,我通常會在我的sp中加入這一行。 –

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),並且在查詢我們想要的數據時只打開記錄集似乎可以做到這一點。

這是一個問題,我需要使用臨時表(我沒有實際意識到我有權限做,因爲它是一個活的數據庫,我從來沒有用過這些),因爲我相信變量表在我第二次打電話時會消失。

其他的事情要注意的

  • 確保你只關閉連接,你所做的一切(最初我不得不從單獨的函數調用的每個命令,並打開/每次關閉連接後不假思索地)
  • 確保刪除臨時表末

希望這可以幫助其他人!

相關問題