パラメーターの構成

適用対象: .NET Framework .NET .NET Standard

ADO.NET のダウンロード

コマンド オブジェクトは、パラメーターを使用して SQL ステートメントまたはストアド プロシージャに値を渡すことによって、型チェックと検証の機能を実現します。 コマンド テキストとは異なり、パラメーターの入力は実行可能なコードとしてではなく、リテラル値として扱われます。 この動作により、攻撃者がサーバーのセキュリティを侵害するコマンドを SQL ステートメントに挿入する "SQL インジェクション" 攻撃を防ぐことができます。

パラメーター化コマンドによりクエリ実行パフォーマンスも向上します。これは、データベース サーバーが入力コマンドを適切なキャッシュ済みクエリ プランに正確に一致させるのに役立つためです。 詳細については、「実行プランのキャッシュと再利用」および「パラメーターと実行プランの再利用」を参照してください。 セキュリティおよびパフォーマンス上の利点に加え、パラメーター化コマンドを使用すると、データ ソースに渡す値を簡単に扱うことができます。

DbParameter オブジェクトは、コンストラクターを使って作成できるほか、 DbParameterCollection コレクションの Add メソッドを呼び出し、 DbParameterCollection にオブジェクトを追加することによって作成することもできます。 Add メソッドは、コンストラクター引数または既存のパラメーター オブジェクトを入力として受け取ります。この点はデータ プロバイダーによっても異なります。

ParameterDirection プロパティを指定する

パラメーターを追加する際は、入力パラメーターとは別に、パラメーターの ParameterDirection プロパティを指定する必要があります。 ParameterDirection で使用できる ParameterDirection の値を次の表に示します。

メンバー名 説明
Input このパラメーターは入力パラメーターです。 この値は既定値です。
InputOutput このパラメーターは入力と出力の両方の機能を持っています。
Output このパラメーターは出力パラメーターです。
ReturnValue パラメーターは、ストアド プロシージャ、組み込み関数、ユーザー定義関数などの操作からの戻り値を表します。

パラメーターのプレースホルダーを操作する

パラメーターのプレースホルダーの構文はデータ ソースに依存します。 Microsoft SqlClient Data Provider for SQL Server では、パラメーターおよびパラメーターのプレースホルダーの名前付け方法と指定方法が異なります。 SqlClient データ プロバイダーでは、@parametername 形式の名前付きパラメーターが使用されます。

パラメーターのデータ型を指定する

パラメーターのデータ型は、Microsoft SqlClient Data Provider for SQL Server に固有です。 型を指定すると、Parameter の値が Microsoft SqlClient Data Provider for SQL Server 型に変換されてから、データ ソースに値が渡されます。 Parameter オブジェクトの DbType プロパティを特定の Parameter に設定する一般的な方法で DbTypeの型を指定することもできます。

Parameter オブジェクトの Microsoft SqlClient Data Provider for SQL Server 型は、Parameter オブジェクトの Value の .NET Framework 型から、または Parameter オブジェクトの DbType から推論されます。 Parameter 値として渡されるオブジェクトまたは指定された Parameter に基づいて推論される DbType型を、次の表に示します。

.NET の種類 DbType SqlDbType
Boolean Boolean Bit
Byte Byte TinyInt
byte[] Binary VarBinary. バイト配列が VarBinary の最大サイズ (8,000 バイト) より大きい場合、この暗黙的な変換は失敗します。 8000 バイトを超えるバイト配列の場合は、明示的に SqlDbType を設定してください。
Char char から SqlDbType への推論はサポートされていません。
DateTime DateTime DateTime
DateTimeOffset DateTimeOffset DateTimeOffset (SQL Server 2008)。 DateTimeOffset から SqlDbType への推論は、SQL Server 2008 より前のバージョンの SQL Server ではサポートされていません。
Decimal Decimal Decimal
Double Double Float
Single Single Real
Guid Guid UniqueIdentifier
Int16 Int16 SmallInt
Int32 Int32 Int
Int64 Int64 BigInt
Object Object Variant
String String NVarChar. 文字列が NVarChar の最大サイズ (4,000 文字) より大きい場合、この暗黙的な変換は失敗します。 4000 文字を超える文字列の場合は、明示的に SqlDbTypeを設定してください。
TimeSpan Time Time (SQL Server 2008)。 TimeSpan から SqlDbType への推論は、SQL Server 2008 より前のバージョンの SQL Server ではサポートされていません。
UInt16 UInt16 UInt16 から SqlDbType への推論はサポートされていません。
UInt32 UInt32 UInt32 から SqlDbType への推論はサポートされていません。
UInt64 UInt64 UInt64 から SqlDbType への推論はサポートされていません。
AnsiString VarChar
AnsiStringFixedLength Char
Currency Money
Date Date (SQL Server 2008)。 Date から SqlDbType への推論は、SQL Server 2008 より前のバージョンの SQL Server ではサポートされていません。
SByte SByte から SqlDbType への推論はサポートされていません。
StringFixedLength NChar
Time Time (SQL Server 2008)。 Time から SqlDbType への推論は、SQL Server 2008 より前のバージョンの SQL Server ではサポートされていません。
VarNumeric VarNumeric から SqlDbType への推論はサポートされていません。
ユーザー定義型 ( SqlUserDefinedAggregateAttributeを持つオブジェクト) SqlClient は常に Object を返します SqlUserDefinedTypeAttribute が存在する場合は SqlDbType.Udt。それ以外の場合は Variant

Note

decimal から他の型への変換は縮小変換になるため、decimal 値は最も近い整数値に切り捨てられます。 変換の結果が変換先の型で表現できない場合は、OverflowException がスローされます。

Note

サーバーに NULL パラメーター値を送信する場合は、null (Visual Basic の場合は Nothing) ではなく、DBNull を指定する必要があります。 システムの null 値は、値のない空オブジェクトです。 DBNull は、null 値を表すために使用します。

パラメーター情報を派生させる

DbCommandBuilder クラスを使用してストアド プロシージャからパラメーターを派生させることができます。 SqlCommandBuilder クラスには静的メソッド DeriveParameters が用意されています。これにより、ストアド プロシージャからのパラメーター情報を使用するコマンド オブジェクトのパラメーターのコレクションが自動的に設定されます。 DeriveParameters により、コマンドの既存のパラメーター情報が上書きされます。

Note

パラメーター情報を派生させた場合、情報を取得するためにデータ ソースへのラウンド トリップが 1 つ増えるため、パフォーマンスが低下します。 パラメーター情報がデザイン時にわかっている場合は、パラメーターを明示的に設定することでアプリケーションのパフォーマンスを改善できます。

詳細については、「CommandBuilder でのコマンドの生成」を参照してください。

SqlCommand およびストアド プロシージャでのパラメーターの使用

ストアド プロシージャは、データドリブンのアプリケーションに多くの利点を提供します。 ストアド プロシージャを使用すると、データベース操作を 1 つのコマンドでカプセル化し、最良のパフォーマンスのために最適化し、セキュリティを強化して拡張することができます。 ストアド プロシージャは、ストアド プロシージャ名の後にパラメーター引数を記述して SQL ステートメントとして渡すことで呼び出すことができますが、ADO.NET の DbCommand オブジェクトの Parameters コレクションを使用すると、ストアド プロシージャ パラメーターをより明示的に定義でき、出力パラメーターや戻り値にもアクセスできます。

Note

パラメーター化ステートメントは、 sp_executesql, を使ってサーバー上で実行されるため、クエリ プランの再利用が可能になります。 sp_executesql バッチ内のローカル カーソルまたはローカル変数は、 sp_executesqlを呼び出すバッチでは認識されません。 データベース コンテキストの変更は、 sp_executesql ステートメント終了時まで有効です。 詳細については、「sp_executesql (Transact-SQL)」を参照してください。

SqlCommand でパラメーターを使用して SQL Server のストアド プロシージャを実行する場合は、 Parameters コレクションに追加したパラメーターの名前が、ストアド プロシージャ内のパラメーター マーカーの名前と一致している必要があります。 Microsoft SqlClient Data Provider for SQL Server では、SQL ステートメントまたはストアド プロシージャにパラメーターを渡す際の疑問符 (?) のプレースホルダーはサポートされていません。 ストアド プロシージャ内のパラメーターは名前付きのパラメーターと見なされ、一致するパラメーター マーカーが検索されます。 たとえば、 CustOrderHist ストアド プロシージャが、 @CustomerIDという名前のパラメーターで定義されているとします。 このストアド プロシージャを実行する場合、実行元のコードでも @CustomerIDという名前のパラメーターを使用する必要があります。

CREATE PROCEDURE dbo.CustOrderHist @CustomerID varchar(5)

次の例では、 Northwind サンプル データベースにある SQL Server ストアド プロシージャを呼び出す方法を説明します。 ストアド プロシージャの名前は dbo.SalesByCategory で、 @CategoryName データ型の nvarchar(15)という名前の入力パラメーターを持ちます。 このコードでは、プロシージャの終了時に接続が破棄されるように、using ブロック内で新しい SqlConnection を作成しています。 SqlCommand オブジェクトおよび SqlParameter オブジェクトが作成され、それぞれのプロパティが設定されます。 SqlDataReader によって SqlCommand が実行された後、ストアド プロシージャから結果セットが返されて、出力がコンソール ウィンドウに表示されます。

Note

SqlCommand オブジェクトと SqlParameter オブジェクトを作成してから別個のステートメントでプロパティを設定する代わりに、オーバーロード コンストラクターを使用して複数のプロパティを 1 つのステートメントで設定することもできます。

static void GetSalesByCategory(string connectionString,
    string categoryName)
{
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        // Create the command and set its properties.
        SqlCommand command = new SqlCommand();
        command.Connection = connection;
        command.CommandText = "SalesByCategory";
        command.CommandType = CommandType.StoredProcedure;

        // Add the input parameter and set its properties.
        SqlParameter parameter = new SqlParameter();
        parameter.ParameterName = "@CategoryName";
        parameter.SqlDbType = SqlDbType.NVarChar;
        parameter.Direction = ParameterDirection.Input;
        parameter.Value = categoryName;

        // Add the parameter to the Parameters collection.
        command.Parameters.Add(parameter);

        // Open the connection and execute the reader.
        connection.Open();
        using (SqlDataReader reader = command.ExecuteReader())
        {
            if (reader.HasRows)
            {
                while (reader.Read())
                {
                    Console.WriteLine("{0}: {1:C}", reader[0], reader[1]);
                }
            }
            else
            {
                Console.WriteLine("No rows found.");
            }
            reader.Close();
        }
    }
}

関連項目