MSDNがAddWithValueメソッドを非推奨にしている理由

nqyuta 80 評価のポイント
2025-02-07T07:49:53.26+00:00

C#で作成したプログラムでSQL Serverのテーブルにアクセスし、データの更新や登録を行おうとしています。

SQLインジェクション対策ができ、Nプレフィクスの対応もできるプログラムを作成するため、SqlCommandオブジェクトのParametersプロパティに属するメソッドであるAddWithValueメソッドを使用しようと考えています。

しかし、AddWithVaueメソッドがMSDNでは非推奨とされています。

AddWithValueメソッドを用いると、どのような問題が生じるのでしょうか。

Visual Studio
Visual Studio
Windows、Web、モバイル デバイス用のアプリケーションを構築するための統合開発ツールの Microsoft スイートのファミリ。
128 件の質問
SQL Server
SQL Server
Microsoft リレーショナル データベース管理分析システムのファミリで、電子商取引、基幹業務、データ ウェアハウジングなどのソリューションで使用されています。
47 件の質問
C#
C#
C 言語ファミリをルーツとし、コンポーネント指向プログラミングのサポートを含む、オブジェクト指向およびタイプセーフのプログラミング言語。
42 件の質問
{count} 件の投票

承認済みの回答
  1. Jack J Jun 24,881 評価のポイント Microsoft 外部スタッフ
    2025-02-07T13:23:40.5766667+00:00

    @那由多, Microsoft Q&A フォーラムへようこそ。 最新の公式ドキュメントによると、AddwithValue は現在非推奨ではありません。 ただし、String と Object を使用する SqlParameterCollection.Add メソッドに置き換えられています。 以下に示す理由はAddwithValueによるものです:

    AddWithValue は、String と Objectを受け取る SqlParameterCollection.Add メソッドを置き換えます。 文字列を受け取り、オブジェクトを受け取る Add のオーバーロードは、String を受け取る SqlParameterCollection.Add オーバーロードと SqlDbType 列挙値とのあいまいさが考えられるため非推奨となりました。

    上記の説明がお役に立てば幸いです。


    回答が正しい解決策である場合は、「回答を受け入れる」をクリックして、賛成票を投じてください。この回答について追加の質問がある場合は、「コメント」をクリックしてください。 注: このスレッドに関連する電子メール通知を受信したい場合は、ドキュメントの手順に従って電子メール通知を有効にしてください。

    1 人がこの回答が役に立ったと思いました。
    0 件のコメント コメントはありません

4 件の追加の回答

並べ替え方法: 最も役に立つ
  1. gekka 11,456 評価のポイント MVP
    2025-02-07T09:53:05.3+00:00

    SqlParameterCollectionのAddWidthValue(string,object)は内部的には

    SqlParameterCollection.Add(new SqlParameter(string,object))
    

    を呼び出しています。

    このとき、 SqlParameterの引数が2個で第2引数がobject型のコンストラクタでは、渡した値が数値なのか列挙型のSqlDbTypeなのかが曖昧になります。
    コンストラクタの注釈に説明があります

    //整数0と渡したつもり
    new SqlParameter("name", 0);
    
    //列挙型は整数に相互変換可能なので誤認する
    new SqlParameter("name", SqlDBType.BigInt);
    

    このような曖昧さがあるために非推奨になっています。

    # System.Data.SqlClientのほうのSqlParameterCollectionのAdd(string,object)でも同じ問題がある。


  2. SurferOnWww 3,906 評価のポイント
    2025-02-08T01:17:15.6866667+00:00

    AddWithVaueメソッドがMSDNでは非推奨とされています。

    そう書いてあった Microsoft ドキュメントの URL を教えてください。

    AddWithValue メソッドを説明する Microsoft ドキュメント(URL 下記)には、

    "AddWithValue は、String と Objectを受け取る SqlParameterCollection.Add メソッドを置き換えます。 文字列を受け取り、オブジェクトを受け取る Add のオーバーロードは、String を受け取る SqlParameterCollection.Add オーバーロードと SqlDbType 列挙値とのあいまいさが考えられるため非推奨となりました。 この場合、文字列を使用して整数を渡すことは、パラメーター値または対応する SqlDbType 値のいずれかと解釈できます。 パラメーターの名前と値を指定してパラメーターを追加する場合は常に、AddWithValue を使用します。 "

    ・・・と書いてあって、非推奨になっているのは SqlParameterCollection.Add(String, Object) メソッドであって、代わりに AddWithValue メソッドを使えということです。

    SqlParameterCollection.Add(String, Object) メソッドと思い違いしていませんか?

    SqlParameterCollection.AddWithValue(String, Object) メソッド - System.Data.SqlClient (.NET Framework 4.8.1)

    SqlParameterCollection.AddWithValue(String, Object) メソッド - System.Data.SqlClient (.NET 9.0)

    SqlParameterCollection.AddWithValue(String, Object) メソッド - Microsoft.Data.SqlClient

    0 件のコメント コメントはありません

  3. Deleted

    この回答は当社の行動規範に違反したため削除されました。 アクションを実行する前にこの回答を手動で報告したか、自動検出機能により特定しました。 詳細については、当社の行動規範を参照してください。


    コメントはオフになっています。 詳細情報

  4. SurferOnWww 3,906 評価のポイント
    2025-02-08T03:19:06.39+00:00

    質問者さんが AddWithValue メソッドを使いたいというそもそもの目的は、

    SQLインジェクション対策ができ、Nプレフィクスの対応もできるプログラムを作成するため

    ということだそうですが、それは誤解です (AddWithValue メソッドを使えばその目的が果たせるということはない)。

    SQL インジェクション対策は SQL 文をパラメータ化するのが基本です。 クエリをパラメータ化するというのはリテラルの部分をプレースホルダを使って記述することです。

    例えば以下の SELECT クエリの場合、'server' というリテラル部分を、

    SELECT id, 製品 FROM TableA WHERE カテゴリ='サーバー'

    以下のように @Category というプレースホルダを使って記述することです。

    SELECT id, Product FROM TableA WHERE Category=@Category

    詳しくは以下の記事を見てください。

    パラメータ化クエリ

    加えて、SqlParameter クラスを利用してクエリをパラメータ化すると sp_executesql に変換されて SQL Server で実行されるのですが、その際に N プレフィックスが付与されます。

    例えば、以下のコードを実行すると、

    query ="INSERT INTO [Table] ([Name]) VALUES (@Name)";
    using(SqlCommand cmd = new SqlCommand(query, conn))
    {
        cmd.Parameters.Add(new SqlParameter("@Name", SqlDbType.NVarChar, 50));
        cmd.Parameters["@Name"].Value = "かきくけこ";
        cmd.ExecuteNonQuery();
    }
    

    SQL Server では以下のように sp_executesql に変換されて実行され N プレフィックスが付与されます。

    exec sp_executesql 
        N'INSERT INTO [Table] ([Name]) VALUES (@Name)',
        N'@Name nvarchar(5)',
        @Name=N'かきくけこ'
    

    詳しくは以下の記事を見てください。

    パラメータ化の副次的な効用


お客様の回答

回答は、質問作成者が [承諾された回答] としてマークできます。これは、ユーザーが回答が作成者の問題を解決したことを知るのに役立ちます。