32

パラメーターがデータ ソースのレコードと一致しているにもかかわらず、アドホック SQL クエリが期待される出力を生成していないコードの一部に、奇妙な問題が見られました。次のテスト式をイミディエイト ウィンドウに入力することにしました。

new SqlParameter("Test", 0).Value

という結果になりnull、頭を悩ませています。SqlParameterコンストラクターはゼロをヌルとして扱うようです。次のコードは正しい結果を生成します。

SqlParameter testParam = new SqlParameter();
testParam.ParameterName = "Test";
testParam.Value = 0;
// subsequent inspection shows that the Value property is still 0

誰でもこの動作を説明できますか? なんとなく意図的?もしそうなら、それはかなり危険な可能性があります...

4

2 に答える 2

37

そのコンストラクターのドキュメントに記載されているように:

value パラメーターでオブジェクトを指定すると、SqlDbType はオブジェクトの Microsoft .NET Framework 型から推測されます。

SqlParameterコンストラクターのこのオーバーロードを使用して整数パラメーター値を指定する場合は注意してください。このオーバーロードはObject型の値を取るため、次の C# の例に示すように、値がゼロの場合は整数値をObject型に変換する必要があります。

Parameter = new SqlParameter("@pname", (object)0);

この変換を実行しない場合、コンパイラは、SqlParameter (文字列、SqlDbType)コンストラクターのオーバーロードを呼び出そうとしていると見なします。

あなたは単にあなたのケースで考えていたものとは異なるコンストラクターを呼び出していました.

この理由は、C# では整数リテラルから列挙型 (その下にある整数型) への暗黙的な変換が許可されており、この暗黙的な変換により、コンストラクターは、変換に必要なボクシング変換よりもオーバーロードの解決により適したものになるためです。コンストラクター用。0(string, SqlDbType)intobject(string, object)

int variableを渡す場合、その変数の値が0(ゼロ リテラルではないため) であっても、型がint. int上記のようにtoを明示的にキャストしてobjectも、一致するオーバーロードが 1 つしかないため、発生しません。

于 2011-12-02T05:50:33.573 に答える
6

パラメータを渡したり追加したりするときに、型指定されたデータを使用することをお勧めします。

以下の方法で、以下のようにタスクを実行できます。

文字列/varcharタイプのデータの場合:

SqlParameter pVarchar = new SqlParameter
                    {
                        ParameterName = "Test",
                        SqlDbType = System.Data.SqlDbType.VarChar,
                        Value = string.Empty,
                    };

int型データの場合:

SqlParameter pInt = new SqlParameter
                    {
                        ParameterName = "Test",
                        SqlDbType = System.Data.SqlDbType.Int,
                        Value = 0,
                    };

SqlDbType使用したデータに応じての値を変更できます。

于 2011-12-02T06:15:06.987 に答える