1

私はこの単純化した例と同様に、ストアドプロシージャを作成しました:C#で出力パラメータと結果セットを使用してSPを読み取りますか?

CREATE PROCEDURE dbo.sp_MyStoredProcedure 
    @Var1 INT OUTPUT, 
    @Var2 DECIMAL(10,2) OUTPUT 
AS 
BEGIN 
    SET NOCOUNT ON; 

    SELECT 
     @Var1 = COUNT(*), 
     @Var2 = SUM(TranAmount) 
    FROM 
     MyTable 

    SELECT * FROM MyTable 
END 

私はSqlCommandオブジェクトのExecuteReader()メソッドを呼び出した後、出力変数から値を読み取るしようとすると、値はnullです。

string MyConnString = string.Empty; 
SqlConnection MyConn = new SqlConnection(MyConnString); 
SqlCommand MyCmd = new SqlCommand("sp_MyStoredProcedure", MyConn); 
MyCmd.CommandType = CommandType.StoredProcedure; 
MyCmd.Parameters.Add(new SqlParameter("@Var1", SqlDbType.Int)); 
MyCmd.Parameters.Add(new SqlParameter("@Var2", SqlDbType.Decimal); 
MyCmd.Parameters[0].Direction = ParameterDirection.Output; 
MyCmd.Parameters[1].Direction = ParameterDirection.Output; 
SqlDataReader dr = MyCmd.ExecuteReader(CommandBehavior.CloseConnection); 
int Var1 = Convert.ToInt32(MyCmd.Parameters[0].Value); 
decimal Var1 = Convert.ToDecimal(MyCmd.Parameters[1].Value); 

私は間違っていますか?

答えて

10

最後までリーダーを読み取る必要があります。出力パラメータはTDSストリームの最後にあり、クライアントは結果セットが使用されなくなるまでそれらを表示しません。

結果セットを読み取る前にカウントと合計を設定する必要がある場合は、OUTPUTパラメータをディッチする必要があります。あなたが興味を持っている2つの値を持つ通常の結果セットを作成して、SELECT *結果セットを購入してください。次に、SqlDataReader.NextResult()を使用してクライアントで両方の結果セットを読み取ります。

CREATE PROCEDURE dbo.sp_MyStoredProcedure  
AS 
BEGIN  
    SET NOCOUNT ON;  
    SELECT COUNT(*) as cnt, SUM(TranAmount) as sum_ta 
    FROM MyTable 
    SELECT * FROM MyTable 
END 

とクライアント:

string MyConnString = string.Empty; 
SqlConnection MyConn = new SqlConnection(MyConnString); 
SqlCommand MyCmd = new SqlCommand("sp_MyStoredProcedure", MyConn); 
MyCmd.CommandType = CommandType.StoredProcedure; 
using(SqlDataReader dr = MyCmd.ExecuteReader(CommandBehavior.CloseConnection)) 
{ 
    while(dr.Read()) 
    { 
    count = dr["cnt"]; 
    sum = dr["sum_ta"]; 
    } 
    dr.NextResult(); 
    while(dr.Read()) 
    { 
    // process MyTable row here 
    } 
} 

注意あなたがないは何をする必要があります

ここで更新

は、設定された2つの結果を持つことで私が何を意味するかですこれはあなたのC#コードは、データを消費する前に出力パラメータの値を必要としない場合der。あなたは単に末尾までSqlDataReaderを読むことができ、、次にの出力パラメータをチェックすると、それらが設定されます。

1

Remusが言ったように、まずそれが必要な場合は、あなたがどのように問い合わせを行うかをreaddressする必要があります。なぜ2つの別々の手順がないのですか?それが抽象的な最善の解決策になるでしょう。

そうでない場合は、次の2つのSQL文が次にあなたが

SqlDataReader dr = MyCmd.ExecuteReader(CommandBehavior.CloseConnection); 
while (dr.read()) 
{ 
    var1 = dr["Var1"]; 
    var2 = dr["Var2"]; 
} 

dr.NextResult(); 

while (dr.read()) 
{ 
    // blah blah blah code 
} 
のExecuteReaderを呼び出したとき、彼は同じバッチ

SELECT COUNT(*) AS VAR1, SUM(TranAmount) AS VAR2 FROM MyTable 
SELECT * FROM MyTable 

をint型行うことができます

関連する問題