適用対象: .NET Framework .NET
.NET Standard
コマンド オブジェクトは、パラメーターを使用して 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 型は、Value オブジェクトの Parameter の .NET Framework 型から、または DbType オブジェクトの Parameter から推論されます。
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)。
SqlDbType から DateTimeOffset への推論は、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)。
SqlDbType から TimeSpan への推論は、SQL Server 2008 より前のバージョンの SQL Server ではサポートされていません。 |
| UInt16 | UInt16 |
SqlDbType から UInt16 への推論はサポートされていません。 |
| UInt32 | UInt32 |
SqlDbType から UInt32 への推論はサポートされていません。 |
| UInt64 | UInt64 |
SqlDbType から UInt64 への推論はサポートされていません。 |
AnsiString |
VarChar |
|
AnsiStringFixedLength |
Char |
|
Currency |
Money |
|
Date |
Date (SQL Server 2008)。
SqlDbType から Date への推論は、SQL Server 2008 より前のバージョンの SQL Server ではサポートされていません。 |
|
SByte |
SqlDbType から SByte への推論はサポートされていません。 |
|
StringFixedLength |
NChar |
|
Time |
Time (SQL Server 2008)。
SqlDbType から Time への推論は、SQL Server 2008 より前のバージョンの SQL Server ではサポートされていません。 |
|
VarNumeric |
SqlDbType から VarNumeric への推論はサポートされていません。 |
|
| ユーザー定義型 ( SqlUserDefinedAggregateAttributeを持つオブジェクト) | SqlClient は常に Object を返します |
SqlDbType.Udt が存在する場合は SqlUserDefinedTypeAttribute。それ以外の場合は Variant |
| SqlJson | String |
SqlDbType.Json |
| SqlVector<T> | Binary |
SqlDbType.Vector |
Note
decimal から他の型への変換は縮小変換になるため、decimal 値は最も近い整数値に切り捨てられます。 変換の結果が変換先の型で表現できない場合は、OverflowException がスローされます。
Note
JSON
Value型のパラメーター stringを渡すときに、SqlDbType を Json に設定します。 それ以外の場合、SqlDbType は既定で Nvarchar に設定されます。
ベクトル
SQL ベクター データ型の場合は、Value型のパラメーター Microsoft.Data.SqlTypes.SqlVector<T>を指定する必要があります。 パラメーター Size とベクターディメンションは、パラメーター Valueから推論されます。 パラメーター Size は無視されます。
Note
サーバーに NULL パラメーター値を送信する場合は、DBNull (Visual Basic の場合は null) ではなく、Nothing を指定する必要があります。 システムの null 値は、値のない空オブジェクトです。
DBNull は、null 値を表すために使用します。
パラメーター情報を派生させる
DbCommandBuilder クラスを使用してストアド プロシージャからパラメーターを派生させることができます。
SqlCommandBuilder クラスには静的メソッド DeriveParameters が用意されています。これにより、ストアド プロシージャからのパラメーター情報を使用するコマンド オブジェクトのパラメーターのコレクションが自動的に設定されます。
DeriveParameters により、コマンドの既存のパラメーター情報が上書きされます。
Note
パラメーター情報を派生させた場合、情報を取得するためにデータ ソースへのラウンド トリップが 1 つ増えるため、パフォーマンスが低下します。 パラメーター情報がデザイン時にわかっている場合は、パラメーターを明示的に設定することでアプリケーションのパフォーマンスを改善できます。
詳細については、「CommandBuilder でのコマンドの生成」を参照してください。
SqlCommand およびストアド プロシージャでのパラメーターの使用
ストアド プロシージャは、データドリブンのアプリケーションに多くの利点を提供します。 ストアド プロシージャを使用すると、データベース操作を 1 つのコマンドでカプセル化し、最良のパフォーマンスのために最適化し、セキュリティを強化して拡張することができます。 ストアド プロシージャは、ストアド プロシージャ名の後にパラメーター引数を記述して SQL ステートメントとして渡すことで呼び出すことができますが、ADO.NET の Parameters オブジェクトの DbCommand コレクションを使用すると、ストアド プロシージャ パラメーターをより明示的に定義でき、出力パラメーターや戻り値にもアクセスできます。
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();
}
}
}