SqlDataSource コントロールによるデータの変更

Visual Studio 2010

更新 : 2007 年 11 月

SqlDataSource コントロールを使用して、データベースのデータを変更できます。データの更新で SqlDataSource コントロールを使用する最も一般的な方法は、GridViewDetailsViewFormView などのデータ連結 Web サーバー コントロールを使用してデータを取得して表示することです。データ連結コントロールと SqlDataSource を構成してデータを更新します。ほとんどのデータ連結コントロールは、挿入、更新、および削除の各操作をサポートするように構成できます。また、データ ソース コントロールに更新対象の値を渡します。次に、データ ソース コントロールは SQL ステートメントまたはストアド プロシージャを使用して更新された値をデータベースに送信します。

SqlDataSource コントロールは、一度に 1 つのデータ レコードを更新するように設計されています。バッチ更新を実行する必要がある場合は、ASP.NET アプリケーションにループ ロジックを明示的に記述する必要があります。

SqlDataSource コントロールを使用してデータベースのデータを変更するには、少なくとも次のプロパティを設定する必要があります。

  • ProviderName   操作するデータベースを表す ADO.NET プロバイダの名前に設定します。

  • ConnectionString   データベースに使用する接続文字列に設定します。

  • SqlDataSource コマンド プロパティ   データベースのデータを変更する SQL ステートメントに設定します。

以下のセクションでは、これらのプロパティについて詳しく説明します。

ProviderName プロパティをデータが格納されているデータベースの種類に対応する ADO.NET プロバイダの名前に設定します。次の名前を設定できます。

  • Microsoft SQL Server を使用する場合、ProviderName プロパティを "System.Data.SqlClient" に設定します。別の値を指定しない場合は、この値が既定値になります。

  • Oracle データベースを使用する場合、ProviderName プロパティを "System.Data.OracleClient" に設定します。

  • OLE DB データ ソースを使用する場合、ProviderName プロパティを "System.Data.OleDb" に設定します。

  • ODBC データ ソースを使用する場合、ProviderName プロパティを "System.Data.Odbc" に設定します。

ConnectionString プロパティを特定のデータベースに接続するように設定します。接続文字列は、アプリケーションの構成ファイルの ConnectionStrings 要素に格納することをお勧めします。次に、コントロールのマークアップで、<%$ ConnectionStrings:connectionStringName %> 構文を使用して格納されている接続文字列を参照します。接続文字列は、指定された ProviderName に対して有効な接続文字列である必要があります。

SqlDataSource コントロールには、データを変更する SQL ステートメントを指定できる InsertCommandUpdateCommand、および DeleteCommand の 3 つのコマンド プロパティがあります。コマンド プロパティは SQL ステートメントに設定できます。また、データ ソースがストアド プロシージャをサポートする場合は、ストアド プロシージャの名前にも設定できます。SQL ステートメントの実際の構文は、データのスキーマと使用するデータベースに依存します。データ ソースがパラメータをサポートする場合は、ステートメントにパラメータを含めることができます。

fkzs2t3h.alert_note(ja-jp,VS.100).gifメモ :

コマンド プロパティに設定するステートメントは、ADO.NET データ操作コードを記述する際の ADO.NET IDbCommand オブジェクトの CommandText プロパティに設定するステートメントと同じです。

Update メソッドが呼び出されるたびに、UpdateCommand プロパティの SQL ステートメントが実行されます。Update メソッドは、GridViewFormView、または DetailsView の各コントロールでユーザーが [更新] をクリックすると、データ連結コントロールによって暗黙的に呼び出されます。このメソッドは、独自のコードから明示的に呼び出すこともできます。SqlDataSource コントロールの Insert メソッドと Delete メソッドは同じように動作します。

SqlDataSource コントロールで、FormView コントロールを使用してレコードを挿入、更新、および削除するコード例を次に示します。この例では、SQL Server Northwind データベースに接続します。


<%@ Page language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">

  void EmployeesGridView_OnSelectedIndexChanged(Object sender, EventArgs e)
  {
    EmployeeDetailsSqlDataSource.SelectParameters["EmpID"].DefaultValue = 
      EmployeesGridView.SelectedValue.ToString();
    EmployeeFormView.DataBind();
  }

  void EmployeeFormView_ItemUpdated(Object sender, FormViewUpdatedEventArgs e)
  {
    EmployeesGridView.DataBind();
  }

  void EmployeeFormView_ItemDeleted(Object sender, FormViewDeletedEventArgs e)
  {
    EmployeesGridView.DataBind();
  }

  void EmployeeDetailsSqlDataSource_OnInserted(Object sender, SqlDataSourceStatusEventArgs e)
  {
    System.Data.Common.DbCommand command = e.Command;    

    EmployeeDetailsSqlDataSource.SelectParameters["EmpID"].DefaultValue = 
      command.Parameters["@EmpID"].Value.ToString();

    EmployeesGridView.DataBind();
    EmployeeFormView.DataBind();
  }

</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
  <head runat="server">
    <title>FormView Example</title>
</head>
<body>
    <form id="form1" runat="server">

      <h3>FormView Example</h3>

        <table cellspacing="10">

          <tr>
            <td>
              <asp:GridView ID="EmployeesGridView" 
                DataSourceID="EmployeesSqlDataSource" 
                AutoGenerateColumns="false"
                DataKeyNames="EmployeeID" 
                OnSelectedIndexChanged="EmployeesGridView_OnSelectedIndexChanged"
                RunAt="Server">

                <HeaderStyle backcolor="Navy"
                  forecolor="White" />

                <Columns>

                  <asp:ButtonField Text="Details..."
                    HeaderText="Show<BR>Details"
                    CommandName="Select"/>  

                  <asp:BoundField DataField="EmployeeID" HeaderText="Employee ID"/>
                  <asp:BoundField DataField="LastName"   HeaderText="Last Name"/>                        
                  <asp:BoundField DataField="FirstName"  HeaderText="First Name"/>

                </Columns>

              </asp:GridView>

            </td>

            <td valign="top">

              <asp:FormView ID="EmployeeFormView"
                DataSourceID="EmployeeDetailsSqlDataSource"
                DataKeyNames="EmployeeID"     
                Gridlines="Both" 
                OnItemUpdated="EmployeeFormView_ItemUpdated"
                OnItemDeleted="EmployeeFormView_ItemDeleted"      
                RunAt="server">

                <HeaderStyle backcolor="Navy"
                  forecolor="White"/>

                <RowStyle backcolor="White"/>         

                <EditRowStyle backcolor="LightCyan"/>

                <ItemTemplate>
                  <table>
                    <tr><td align="right"><b>Employee ID:</b></td><td><%# Eval("EmployeeID") %></td></tr>
                    <tr><td align="right"><b>First Name:</b></td> <td><%# Eval("FirstName") %></td></tr>
                    <tr><td align="right"><b>Last Name:</b></td>  <td><%# Eval("LastName") %></td></tr>
                    <tr>
                      <td colspan="2">
                        <asp:LinkButton ID="EditButton"
                                        Text="Edit"
                                        CommandName="Edit"
                                        RunAt="server"/>
                        &nbsp;
                        <asp:LinkButton ID="NewButton"
                                        Text="New"
                                        CommandName="New"
                                        RunAt="server"/>
                        &nbsp;
                        <asp:LinkButton ID="DeleteButton"
                                        Text="Delete"
                                        CommandName="Delete"
                                        RunAt="server"/>
                      </td>
                    </tr>
                  </table>                 
                </ItemTemplate>

                <EditItemTemplate>
                  <table>
                    <tr><td align="right"><b>Employee ID:</b></td><td><%# Eval("EmployeeID") %></td></tr>

                    <tr><td align="right"><b>First Name:</b></td>
                        <td><asp:TextBox ID="EditFirstNameTextBox" 
                                         Text='<%# Bind("FirstName") %>' 
                                         RunAt="Server" /></td></tr>

                    <tr><td align="right"><b>Last Name:</b></td>
                        <td><asp:TextBox ID="EditLastNameTextBox" 
                                         Text='<%# Bind("LastName") %>' 
                                         RunAt="Server" /></td></tr>
                    <tr>
                      <td colspan="2">
                        <asp:LinkButton ID="UpdateButton"
                                        Text="Update"
                                        CommandName="Update"
                                        RunAt="server"/>
                        &nbsp;
                        <asp:LinkButton ID="CancelUpdateButton"
                                        Text="Cancel"
                                        CommandName="Cancel"
                                        RunAt="server"/>
                      </td>
                    </tr>
                  </table>                 
                </EditItemTemplate>

                <InsertItemTemplate>
                  <table>
                    <tr><td align="right"><b>First Name:</b></td>
                        <td><asp:TextBox ID="InsertFirstNameTextBox" 
                                         Text='<%# Bind("FirstName") %>' 
                                         RunAt="Server" /></td></tr>

                    <tr><td align="right"><b>Last Name:</b></td>
                        <td><asp:TextBox ID="InsertLastNameTextBox" 
                                         Text='<%# Bind("LastName") %>' 
                                         RunAt="Server" /></td></tr>

                    <tr>
                      <td colspan="2">
                        <asp:LinkButton ID="InsertButton"
                                        Text="Insert"
                                        CommandName="Insert"
                                        RunAt="server"/>
                        &nbsp;
                        <asp:LinkButton ID="CancelInsertButton"
                                        Text="Cancel"
                                        CommandName="Cancel"
                                        RunAt="server"/>
                      </td>
                    </tr>
                  </table>                 
                </InsertItemTemplate>

              </asp:FormView>

            </td>

          </tr>

        </table>

        <asp:sqlDataSource ID="EmployeesSqlDataSource"  
          selectCommand="SELECT EmployeeID, FirstName, LastName FROM Employees" 
          connectionstring="<%$ ConnectionStrings:NorthwindConnection %>" 
          RunAt="server">
        </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>

      </form>
  </body>
</html>



使用しているデータベースがストアド プロシージャをサポートしていれば、このコマンドをストアド プロシージャの名前にできます。ストアド プロシージャを使用してデータを更新する場合、UpdateCommandType プロパティを StoredProcedure に設定する必要があります。

パラメータは、データ ソースに対する挿入、更新、および削除の各操作に使用する値を送信するために使用します。パラメータ名と値は、コントロールに連結されたデータ フィールド、または明示的に定義したパラメータ オブジェクトに基づきます。データ連結コントロールから渡されるパラメータには、連結コントロールの DataKeyNames プロパティでの定義に従い、データ操作のための値と特定の行を指定するためのキー値の両方が含まれます。

コントロールに連結されたフィールドに基づくパラメータ以外の追加パラメータに加えて、Parameter の定義を明示的に作成して、パラメータの順序、型、および方向を指定できます。この例としては、自動的にインクリメントされる主キー、日時のタイムスタンプなどのデータ ソースによって自動的に生成される値を返す出力パラメータがあります。

fkzs2t3h.alert_note(ja-jp,VS.100).gifメモ :

明示的にパラメータを指定することは、SQL ステートメントの名前付きパラメータをサポートせずに、代わりに '?' プレースホルダを使用してパラメータを指定する、System.Data.OleDb プロバイダおよび System.Data.Odbc プロバイダを使用する場合に特に重要です。このような場合、対応する SQL ステートメントに指定されている順序でパラメータを定義する必要があります。

パラメータの使用の詳細およびその例については、「SqlDataSource コントロールにおけるパラメータの使用」と「データ ソース コントロールがデータ連結フィールドのパラメータを作成する方法」を参照してください。

SqlDataSource コントロールは、挿入、更新、または削除の各操作を実行する前または後に独自のコードを実行するために処理できるイベントを発生します。

SqlDataSource コントロールは、対応するコマンド プロパティに対して SQL ステートメントを実行する前に InsertingUpdating、または Deleting の各イベントを発生します。このイベントのハンドラを追加すると、ステートメントを実行する前にパラメータの操作、並べ替え、検証に加えてコマンドのキャンセルもできます。たとえば、SqlDataSource コントロールと共に QueryStringParameter を使用する場合、Updating イベントを処理して、更新を実行する前にパラメータの値を検証できます。既定では、QueryStringParameter がクエリ文字列変数の値を受け取り、検証せずにデータベースに送信します。値が許容範囲にない場合、イベントの SqlDataSourceCommandEventArgs オブジェクトの Cancel プロパティを true に設定して更新をキャンセルできます。

SqlDataSource コントロールは、データベースの操作が完了した後に InsertedUpdated、または Deleted の各イベントを発生します。これらのイベントを処理すると、データベースの操作中に例外がスローされたかどうかを確認したり、操作の影響を受けたレコードの数を取得したりできます。また、データベース操作が返す出力値を調べることもできます。

Updating イベントと Updated イベントを使用して、トランザクションの内部で UpdateCommand を実行するコード例を次に示します。

<%@Page  Language="C#" %>
<%@Import Namespace="System.Data" %>
<%@Import Namespace="System.Data.Common" %>
<%@Import Namespace="System.Data.SqlClient" %>
<%@Import Namespace="System.Diagnostics" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

 private void On_Click(Object source, EventArgs e) {    
    SqlDataSource1.Update();
 }

 private void OnSqlUpdating(Object source, SqlDataSourceCommandEventArgs e) {
    DbCommand command = e.Command;
    DbConnection cx  = command.Connection;    
    cx.Open();    
    DbTransaction tx = cx.BeginTransaction();
    command.Transaction = tx;
 }

 private void OnSqlUpdated(Object source, SqlDataSourceStatusEventArgs e) {
    DbCommand command = e.Command;
    DbTransaction tx = command.Transaction;

    // In this code example the OtherProcessSucceeded variable represents
    // the outcome of some other process that occurs whenever the data is 
    // updated, and must succeed for the data change to be committed. For 
    // simplicity, we set this value to true. 
    bool OtherProcessSucceeded = true;

    if (OtherProcessSucceeded) {
        tx.Commit();
        Label2.Text="The record was updated successfully!";
    }
    else {
        tx.Rollback();
        Label2.Text="The record was not updated.";
    }
 }

</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
  <head runat="server">
    <title>ASP.NET Example</title>
</head>
<body>
    <form id="form1" runat="server">
      <asp:SqlDataSource
          id="SqlDataSource1"
          runat="server"
          ConnectionString="<%$ ConnectionStrings:MyNorthwind%>"
          SelectCommand="SELECT EmployeeID, LastName, Address FROM Employees"
          UpdateCommand="UPDATE Employees SET Address=@Address WHERE EmployeeID=@EmployeeID"
          OnUpdating="OnSqlUpdating"
          OnUpdated ="OnSqlUpdated">
          <UpdateParameters>
              <asp:ControlParameter Name="Address" ControlId="TextBox1" PropertyName="Text"/>
              <asp:ControlParameter Name="EmployeeID" ControlId="DropDownList1" PropertyName="SelectedValue"/>
          </UpdateParameters>
      </asp:SqlDataSource>

      <asp:DropDownList
          id="DropDownList1"
          runat="server"
          DataTextField="LastName"
          DataValueField="EmployeeID"
          DataSourceID="SqlDataSource1">
      </asp:DropDownList>

      <br />
      <asp:Label id="Label1" runat="server" Text="Enter a new address for the selected user."
        AssociatedControlID="TextBox1" />
      <asp:TextBox id="TextBox1" runat="server" />
      <asp:Button id="Submit" runat="server" Text="Submit" OnClick="On_Click" />

      <br /><asp:Label id="Label2" runat="server" Text="" />

    </form>
  </body>
</html>


<%@Page  Language="VJ#" %>
<%@Import Namespace="System.Data" %>
<%@Import Namespace="System.Data.Common" %>
<%@Import Namespace="System.Diagnostics" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

     private void On_Click(Object source, System.EventArgs e)
    {
        try {
            SqlDataSource1.Update();
        }
        catch (System.Exception except) {
            // Handle Exception
        }

        Label2.set_Text("The record was updated successfully!");
    } //On_Click

    private void OnSqlUpdate(Object source, SqlDataSourceCommandEventArgs e)
    {
        // Log the command in the Event Log on the Web server.
        String logInfo = e.get_Command().get_CommandText() 
            + " is being submitted to the database.";

        IEnumerator ie = e.get_Command().get_Parameters().GetEnumerator();
        while (ie.MoveNext()) {
            DbParameter param = ((DbParameter)(ie.get_Current()));
            logInfo = logInfo + " " + param.get_ParameterName()+ "=" 
            + param.get_Value();
        }

        EventLog log = new EventLog();
        log.set_Log("Application");
        log.set_Source("ASP.NET Example");
        log.WriteEntry(logInfo);
    } //OnSqlUpdate    

</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
  <head runat="server">
    <title>ASP.NET Example</title>
</head>
<body>
    <form id="form1" runat="server">
      <asp:SqlDataSource
          id="SqlDataSource1"
          runat="server"
          ConnectionString="Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;"
          SelectCommand="SELECT EmployeeID, LastName, Address FROM Employees"
          UpdateCommand="UPDATE Employees SET Address=@Address WHERE EmployeeID=@EmployeeID"
          OnUpdating="OnSqlUpdate">
          <UpdateParameters>
              <asp:ControlParameter Name="Address" ControlId="TextBox1" PropertyName="Text"/>
              <asp:ControlParameter Name="EmployeeID" ControlId="DropDownList1" PropertyName="SelectedValue"/>
          </UpdateParameters>
      </asp:SqlDataSource>

      <asp:DropDownList
          id="DropDownList1"
          runat="server"
          DataTextField="LastName"
          DataValueField="EmployeeID"
          DataSourceID="SqlDataSource1">
      </asp:DropDownList>

      <br />
      <asp:Label id="Label1" runat="server" Text="Enter a new address for the selected user."
        AssociatedControlID="TextBox1" />
      <asp:TextBox id="TextBox1" runat="server" />
      <asp:Button id="Submit" runat="server" Text="Submit" OnClick="On_Click" />

      <br /><asp:Label id="Label2" runat="server" Text="" />

    </form>
  </body>
</html>


SqlDataSource コントロールは、オプティミスティック同時実行制御を使用して更新操作と削除操作を実行できます。オプティミスティック同時実行制御は、複数のユーザーが同時にデータを操作する状況で、データ ソースの変更内容の消失を防止するためのデータベースの方策です。SqlDataSource コントロールは ConflictDetection プロパティを使用して、更新操作と削除操作を実行する際にどのレベルのオプティミスティック同時実行制御のチェックを使用するかを決定します。

既定では、ConflictDetection プロパティは ConflictOptions.OverwriteChanges に設定されます。この設定では、更新操作を行うと、別のソースがレコードを変更したかどうかの確認なしに、レコードのすべての既存の値が上書きされます。この状況は、"last writer wins (最後の書き込みが採用される)" とも呼ばれます。

ConflictDetection プロパティを ConflictOptions.CompareAllValues に設定すると、更新コマンドまたは削除コマンドの実行中に SqlDataSource コントロールに確実にすべての元の値が含まれるようにできます。これを使用して、データベースの現在のデータが最初にデータベースから読み込まれたデータと一致しない場合は更新操作を実行しない SQL ステートメントを記述できます。例については、「オプティミスティック同時実行制御 (ADO.NET)」を参照してください。Updated イベントを処理すると、更新操作の影響を受けたレコードの数を確認できます。レコードが更新されていない場合は同時実行違反が発生しています。

表示: