4

SQLストアドプロシージャのパラメータ値を取得できないという奇妙な問題に遭遇しました。私はこの問題に2時間近く悩まされました。

コードはとてもシンプルです

    using (var con = new SqlConnection(connectionString))
        {
            con.Open();
            SqlCommand cmd = new SqlCommand("sp_mgsearach", con);
            cmd.CommandType = CommandType.StoredProcedure;
            SqlParameter param1 = new SqlParameter("@SearchTerm", SqlDbType.VarChar);
            param1.Value = searchTerm;
            param1.Direction = ParameterDirection.Input;
            cmd.Parameters.Add(param1);
            SqlParameter param2 = new SqlParameter("@start", SqlDbType.Int);
            param2.Value = start;
            param2.Direction = ParameterDirection.Input;
            cmd.Parameters.Add(param2);
            SqlParameter param3 = new SqlParameter("@end", SqlDbType.Int);
            param3.Value = end;
            param3.Direction = ParameterDirection.Input;
            cmd.Parameters.Add(param3);
            SqlParameter param4 = new SqlParameter("@total", SqlDbType.Int);
            param4.Direction = ParameterDirection.InputOutput;
            param4.Value = 0;
            cmd.Parameters.Add(param4);


            var reader = cmd.ExecuteReader();
            LoadHits(reader);           
            if (lstHits.Count > 0)
                total = Convert.ToInt32(cmd.Parameters["@total"].Value);
            else
                total = 0;

        }

@total 値は常に null です。しかし、クエリ アナライザーでプロファイラーを介して生成されたクエリを実行すると、正常に返されます。

最後に、これは SQL 接続が原因であることがわかりました。

out パラメータを読み取る前に接続を閉じると正常に動作します

            LoadHits(reader);           
            con.close()
            if (lstHits.Count > 0)
                total = Convert.ToInt32(cmd.Parameters["@total"].Value);
            else
                total = 0;

WT ..、なぜこのように動作するのかわかりません..誰かアイデアがありますか?

4

2 に答える 2

7

パラメーター値は、TDS ストリームの最後に返されます (データを選択した後、クエリの最後で変更できるため)。更新されたパラメーター値を取得するには、必ずすべての TDS データを消費する (または、少なくともバッファーをフラッシュする必要があります) 必要があります。次に例を示します。Close()

do { while(reader.Read() {} }
while (reader.NextResult());

同じことが、クエリの後半で発生した SQL エラーにも当てはまります。using;を追加することもできます。これで十分な場合もあります。

using(var reader = cmd.ExecuteReader()) {
    LoadHits(reader);  
}
于 2010-09-27T11:15:53.590 に答える
5

Marc の回答に追加するには、(接続ではなく) リーダーを閉じるだけで結果を取得できます。

これは十分に文書化されています (「DataReader を閉じる」): http://msdn.microsoft.com/en-us/library/haa3afyz(v=VS.100).aspx

于 2010-09-27T11:20:35.730 に答える