SqlDataSource コントロールにおけるパラメータの使用
更新 : 2007 年 11 月
多くの場合、SQL ステートメントとストアド プロシージャには実行時に評価されるパラメータが含まれます。パラメータを使用して記述された SQL ステートメントは、パラメータ化された SQL ステートメントと呼ばれます。
SqlDataSource コントロールを使用する場合は、パラメータを使用する SQL クエリと SQL ステートメントを指定できます。これによって、実行時に評価される値に基づいてデータベースの情報を読み書きできるため、より柔軟にデータをバインディングできるようになります。パラメータ値は、ASP.NET アプリケーションの変数、ユーザー ID、ユーザーが選択する値を含むさまざまなソースから取得できます。パラメータを使用すると、データを取得するための検索条件、データ ストアで挿入、更新、または削除する値、および並べ替え、ページング、フィルタ処理のための値を指定できます。
パラメータの使用
すべてのデータ ソース コントロールと同様に、SqlDataSource コントロールは実行時に入力パラメータを受け取ってパラメータ コレクションで管理します。それぞれのデータ操作には、関連するパラメータ コレクションがあります。たとえば、選択操作では SelectParameters コレクションを使用し、更新操作では UpdateParameters コレクションを使用します。
各パラメータには、名前、型、方向、および既定値を指定できます。コントロール、セッション変数、ユーザー プロファイルなどの特定のオブジェクトから値を受け取るパラメータには、追加のプロパティを設定する必要があります。たとえば、ControlParameter では ControlID を設定してパラメータ値を取得するコントロールを指定し、PropertyName プロパティを設定してパラメータ値を含むプロパティを指定します。詳細については、「データ ソース コントロールとパラメータの使用」を参照してください。
SqlDataSource コントロールは、GridView コントロール、FormView コントロールなどの自動的な更新、挿入、および削除をサポートするデータ バインド コントロールが渡す値に基づいてパラメータを自動的に作成します。詳細については、「データ ソース コントロールがデータ連結フィールドのパラメータを作成する方法」を参照してください。
コマンドにおけるパラメータの指定
SqlDataSource コントロールを使用すると、パラメータ化された SQL ステートメントまたはストアド プロシージャの名前にコントロールのコマンド プロパティを設定できます。コマンドにストアド プロシージャを指定する場合は、コマンドの型を StoredProcedure に指定する必要があります。
パラメータ名
SqlDataSource コントロールは、すべてのパラメータ名の先頭に ParameterPrefix プロパティの値を追加します。既定のプリフィックスは "@" です。
GridView コントロールなどのデータ バインド コントロールが SqlDataSource コントロールにバインドされている場合、データ バインド コントロールは、更新または削除の操作中に現在のレコード値および元のレコード値を SqlDataSource コントロールに渡します。現在の値は、Values 辞書に渡されます。元の値は、Keys 辞書または OldValues 辞書に渡されます。これらの辞書の内容は、指定されたデータ操作のために、基になる DbCommand オブジェクトの Parameters コレクションに追加されます。
SqlDataSource コントロールの SQL コマンドでは、パラメータのプレースホルダをコマンドに渡された古い値に合わせる名前付け規則を使用します。プレースホルダ名の形式は、SqlDataSource コントロールの OldValuesParameterFormatString プロパティによって指定します。フィールド名のプレースホルダとして、OldValuesParameterFormatString プロパティに "{0}" を含む文字列を設定します。たとえば、OldValuesParameterFormatString プロパティを "old_{0}" に設定すると、元の値のパラメータの名前はフィールド名に "@old_" というプリフィックスが付けられた名前に解決されます。たとえば、LastModifiedDate という名前のフィールドを含む更新操作を実行するとします。フィールドの現在の値は Values 辞書に渡され、フィールドの元の値は OldValues 辞書に渡されます。現在の値を渡すために @LastModifiedDate というパラメータが作成され、元の値を渡すために @old\_LastModifiedDate というパラメータが作成されます。その後に、次の例に示すように、両方のパラメータを SQL ステートメントに含めてフィールドの現在の値と元の値を区別します。
UPDATE Table1 SET LastModifiedDate = @LastModifiedDate
WHERE Key = @Key AND LastModifiedDate = @old_LastModifiedDate
コマンドで現在の値と元の値を区別する機能は、オプティミスティック同時実行制御チェックを実行する場合または主キーを変更できるデータ ソースを使用する場合に必ず必要になります。
データ バインド コントロールが渡す辞書の詳細については、「データ ソース コントロールがデータ連結フィールドのパラメータを作成する方法」を参照してください。
SqlClient プロバイダにおけるパラメータの使用
既定では、SqlDataSource コントロールは、SQL Server をデータ ソースとして使用する場合に System.Data.SqlClient データ プロバイダを使用します。System.Data.SqlClient プロバイダは、次の例のようにプレースホルダとして名前付きパラメータをサポートします。
SELECT * FROM Employees WHERE LastName = @LastName
AND FirstName = @FirstName
名前付きパラメータによって、コマンドのパラメータ コレクションでパラメータを指定する順序は重要ではなくなります。ただし、SQL コマンドで使用するパラメータ名は、対応するコレクションのパラメータ名に一致する必要があります。
System.Data.SqlClient プロバイダを使用する SqlDataSource コントロールの SQL コマンドで名前付きパラメータを使用する方法の例を次に示します。
<asp:sqlDataSource ID="EmployeeDetailsSqlDataSource"
SelectCommand="SELECT EmployeeID, LastName, FirstName FROM Employees WHERE EmployeeID = @EmpID"
InsertCommand="INSERT INTO Employees(LastName, FirstName) VALUES (@LastName, @FirstName);
SELECT @EmpID = SCOPE_IDENTITY()"
UpdateCommand="UPDATE Employees SET LastName=@LastName, FirstName=@FirstName
WHERE EmployeeID=@EmployeeID"
DeleteCommand="DELETE Employees WHERE EmployeeID=@EmployeeID"
ConnectionString="<%$ ConnectionStrings:NorthwindConnection %>"
OnInserted="EmployeeDetailsSqlDataSource_OnInserted"
RunAt="server">
<SelectParameters>
<asp:Parameter Name="EmpID" Type="Int32" DefaultValue="0" />
</SelectParameters>
<InsertParameters>
<asp:Parameter Name="EmpID" Direction="Output" Type="Int32" DefaultValue="0" />
</InsertParameters>
</asp:sqlDataSource>
<asp:sqlDataSource ID="EmployeeDetailsSqlDataSource"
SelectCommand="SELECT EmployeeID, LastName, FirstName FROM Employees WHERE EmployeeID = @EmpID"
InsertCommand="INSERT INTO Employees(LastName, FirstName) VALUES (@LastName, @FirstName);
SELECT @EmpID = SCOPE_IDENTITY()"
UpdateCommand="UPDATE Employees SET LastName=@LastName, FirstName=@FirstName
WHERE EmployeeID=@EmployeeID"
DeleteCommand="DELETE Employees WHERE EmployeeID=@EmployeeID"
ConnectionString="<%$ ConnectionStrings:NorthwindConnection %>"
OnInserted="EmployeeDetailsSqlDataSource_OnInserted"
RunAt="server">
<SelectParameters>
<asp:Parameter Name="EmpID" Type="Int32" DefaultValue="0" />
</SelectParameters>
<InsertParameters>
<asp:Parameter Name="EmpID" Direction="Output" Type="Int32" DefaultValue="0" />
</InsertParameters>
</asp:sqlDataSource>
OleDb プロバイダと Odbc プロバイダにおけるパラメータの使用
OLE DB データ ソースまたは ODBC データ ソースに接続する場合は、それぞれ System.Data.OleDb プロバイダまたは System.Data.Odbc プロバイダを使用してデータ ソースを操作するように SqlDataSource コントロールを構成します。System.Data.OleDb プロバイダと System.Data.Odbc プロバイダは、次の例のように "?" 文字によって識別される位置パラメータだけをサポートします。
SELECT * FROM Employees WHERE LastName = ? AND FirstName = ?
パラメータ化された SQL ステートメントで System.Data.OleDb プロバイダと System.Data.Odbc プロバイダを使用する場合、パラメータのプレースホルダを指定する順序は対応するパラメータ コレクションのパラメータの順序に一致する必要があります。パラメータの順序は、UpdateCommand に対する UpdateParameters コレクションなどのように、対応するデータ操作に対してコレクションで明示的に指定することによって制御できます。データ バインド コントロールによって渡された値から自動的に作成されるパラメータのコレクションを明示的に作成する場合、明示的に作成されたパラメータは自動的に生成されたパラメータを上書きします。これによって、パラメータを目的の順序で確実に渡すことができます。値を返すストアド プロシージャを呼び出す場合、コマンド パラメータ コレクションの最初のパラメータとして、ReturnValue の Direction 値でパラメータを指定する必要があります。
メモ : |
---|
既定では、データ バインド コントロールからバインドされたフィールドに基づいたパラメータは、Values、Keys、OldValues の順序でパラメータ辞書からコマンドに追加されます。削除操作の場合は、Keys 辞書のみが使用されます。挿入操作の場合は、Values 辞書のみが使用されます。データ バインド コントロールが渡す辞書の詳細については、「データ ソース コントロールがデータ連結フィールドのパラメータを作成する方法」を参照してください。 |
System.Data.OleDb プロバイダを使用する SqlDataSource コントロールのパラメータを指定する方法の例を次に示します。パラメータは、コレクションのパラメータの順序が SQL ステートメントのプレースホルダの順序に一致するように明示的に指定されます。
<Fields>
<asp:BoundField DataField="EmployeeID" HeaderText="Employee ID" InsertVisible="False" ReadOnly="true"/>
<asp:BoundField DataField="FirstName" HeaderText="First Name"/>
<asp:BoundField DataField="LastName" HeaderText="Last Name"/>
<asp:TemplateField HeaderText="Birth Date">
<ItemTemplate>
<asp:Label ID="BirthDateLabel" Runat="Server"
Text='<%# Eval("BirthDate", "{0:d}") %>' />
</ItemTemplate>
<InsertItemTemplate>
<asp:Calendar ID="InsertBirthDateCalendar" Runat="Server"
SelectedDate='<%# Bind("BirthDate") %>' />
</InsertItemTemplate>
<EditItemTemplate>
<asp:Calendar ID="EditBirthDateCalendar" Runat="Server"
VisibleDate='<%# Eval("BirthDate") %>'
SelectedDate='<%# Bind("BirthDate") %>' />
</EditItemTemplate>
</asp:TemplateField>
</Fields>
<Fields>
<asp:BoundField DataField="EmployeeID" HeaderText="Employee ID" InsertVisible="False" ReadOnly="true"/>
<asp:BoundField DataField="FirstName" HeaderText="First Name"/>
<asp:BoundField DataField="LastName" HeaderText="Last Name"/>
<asp:TemplateField HeaderText="Birth Date">
<ItemTemplate>
<asp:Label ID="BirthDateLabel" Runat="Server"
Text='<%# Eval("BirthDate", "{0:d}") %>' />
</ItemTemplate>
<InsertItemTemplate>
<asp:Calendar ID="InsertBirthDateCalendar" Runat="Server"
SelectedDate='<%# Bind("BirthDate") %>' />
</InsertItemTemplate>
<EditItemTemplate>
<asp:Calendar ID="EditBirthDateCalendar" Runat="Server"
VisibleDate='<%# Eval("BirthDate") %>'
SelectedDate='<%# Bind("BirthDate") %>' />
</EditItemTemplate>
</asp:TemplateField>
</Fields>