2017-08-21 19 views
0

SQL Serverに渡されたSQLコマンドの結果をADOオブジェクトを使用してExcelに戻そうとしていますが、Recordsetは閉じたままになります。私の推測では、私のSQLステートメントは何も返されない - 私はそれが単一のレコードを返さなければならないと思いますが。ADO Connection.Executeは閉鎖されたレコードセットを返し続けます。

私が実行しているSQLは530行の獣ですが、結果はテーブルvarにダンプしてそこから選択することになっているMERGEのステートメントになっています。このselectステートメントは、私がADOレコードセットに戻したいものです。ここで

は、私が使用している一般的なSQL文です:

 MERGE ldw_plan_working AS target 
USING source 
ON target.DT_Code = source.DT_Code 
    AND target.Country = source.Country 
    AND target.Channel = source.Channel 
    AND target.HierarchyID = source.HierarchyID 
    AND target.lifecycle = source.lifecycle 
    WHEN MATCHED 
    THEN UPDATE SET 
        [Sales_TOT_Local] = source.[Sales_TOT_Local], 
        [Sales_TOT_USD] = source.[Sales_TOT_USD], 
        [Sales_TOT_CAD] = source.[Sales_TOT_CAD], 
        [Sales_CLR_Local] = source.[Sales_CLR_Local], 
        [Sales_CLR_USD] = source.[Sales_CLR_USD], 
        [Sales_CLR_CAD] = source.[Sales_CLR_CAD], 
        [PM_TOT_Local] = source.[PM_TOT_Local], 
        [PM_TOT_USD] = source.[PM_TOT_USD], 
        [PM_TOT_CAD] = source.[PM_TOT_CAD], 
        [PM_CLR_Local] = source.[PM_CLR_Local], 
        [PM_CLR_USD] = source.[PM_CLR_USD], 
        [PM_CLR_CAD] = source.[PM_CLR_CAD], 
        [Sales_TOT_U] = source.[Sales_TOT_U], 
        [Sales_CLR_U] = source.[Sales_CLR_U], 
        [Receipt_USD] = source.[Receipt_USD], 
        [Receipt_U] = source.[Receipt_U] 
    WHEN NOT MATCHED 
    THEN 
     INSERT([DT_Code], 
       [Country], 
       [Channel], 
       [HierarchyID], 
       [Lifecycle], 
       [Sales_TOT_Local], 
       [Sales_TOT_USD], 
       [Sales_TOT_CAD], 
       [Sales_CLR_Local], 
       [Sales_CLR_USD], 
       [Sales_CLR_CAD], 
       [PM_TOT_Local], 
       [PM_TOT_USD], 
       [PM_TOT_CAD], 
       [PM_CLR_Local], 
       [PM_CLR_USD], 
       [PM_CLR_CAD], 
       [Sales_TOT_U], 
       [Sales_CLR_U], 
       [Receipt_USD], 
       [Receipt_U]) 
     VALUES 
(source.[DT_Code], 
    source.[Country], 
    source.[Channel], 
    source.[HierarchyID], 
    source.[Lifecycle], 
    source.[Sales_TOT_Local], 
    source.[Sales_TOT_USD], 
    source.[Sales_TOT_CAD], 
    source.[Sales_CLR_Local], 
    source.[Sales_CLR_USD], 
    source.[Sales_CLR_CAD], 
    source.[PM_TOT_Local], 
    source.[PM_TOT_USD], 
    source.[PM_TOT_CAD], 
    source.[PM_CLR_Local], 
    source.[PM_CLR_USD], 
    source.[PM_CLR_CAD], 
    source.[Sales_TOT_U], 
    source.[Sales_CLR_U], 
    source.[Receipt_USD], 
    source.[Receipt_U] 
) 
OUTPUT $action 
     INTO @tableVar; 
INSERT INTO @tableVar(MergeAction) 
VALUES('nothing'); 
SELECT [UPDATE], 
     [INSERT], 
     [DELETE] 
FROM @tableVar PIVOT(COUNT(MergeAction) FOR MergeAction IN([UPDATE], 
                 [INSERT], 
                 [DELETE], 
                 [nothing])) AS piv; 

とVBA機能次のようになります。

Public Function Run_SQL_Cmd(sql As String) 
Dim cnn As Object 
Dim cmd As Object 
Dim rs As Object 
Dim recordsAffected As Integer 

Set cnn = CreateObject("ADODB.Connection") 
Set cmd = CreateObject("ADODB.Command") 
Set rs = CreateObject("ADODB.Recordset") 

cnn.Open strBEConnection 
cnn.CommandTimeout = 0 

With cmd 
    .ActiveConnection = cnn 
    .CommandText = sql 
    .CommandType = 1 
    Set rs = .Execute 
End With 

'... do stuff with the recordset 

rs.Close 
cnn.Close 
Set cnn = Nothing 
Set rs = Nothing 

End Function 

rsは常に0フィールドカウントとして戻ってくる、レコードセットを閉じました私は何もすることができません。しかし、私はSQL Serverで直接同じSQLを実行すると、明らかにその最終的なselect文の結果が得られます。誰でも私がここで間違っていることを知っていますか?

+0

subの代わりに関数を使用する必要があるようです。 –

+0

strBEConnectionが定義されていません。 –

+0

申し訳ありませんが、それはDB接続文字列に設定されているconstです。これらはDB接続の問題ではありません。 – ArcherBird

答えて

0

よし、事前に

おかげで、私はそれを考え出しました。コマンド・テキストに複数のSQL文がある場合は、その前にSQL文の中に "SET NOCOUNT ON;"を入れる必要があります。これにより、サーバーは最終的なselectステートメントの結果を返します。かなり面倒なシンプルな修正。

関連する問題