Export (0) Print
Expand All

Modifying Data using the SqlDataSource Control

You can use the SqlDataSource control to modify data in a database. The most common way to use the SqlDataSource control in update scenarios is to retrieve data and display it using a data-bound Web server control, such as a GridView, DetailsView, or FormView control. You configure the data-bound control and the SqlDataSource to update the data. Most data-bound controls allow you to configure them to support insert, update, and delete operations, and they pass the values to be updated to the data source control. The data source control then submits the updated values to the database using an SQL statement or stored procedure.

The SqlDataSource control is designed to update data one record at a time. If you need to perform batch updates, you must write explicit looping logic in your ASP.NET application.

To modify data in a database using the SqlDataSource control, you need to set at least the following properties:

  • ProviderName   Set to the name of the ADO.NET provider that represents the database you are working with.

  • ConnectionString   Set to a connection string that works for your database.

  • SqlDataSource command properties   Set to SQL statements that modify data in the database.

The following sections describe these properties in more detail.

Set the ProviderName property to the name of the ADO.NET provider for the type of database in which your data is stored, which can include the following:

  • If you are working with Microsoft SQL Server, set the ProviderName property to "System.Data.SqlClient". This is the default provider if you do not specify a different one.

  • If you are working with an Oracle database, set the ProviderName property to "System.Data.OracleClient".

  • If you are working with an OLE DB data source, set the ProviderName property to "System.Data.OleDb".

  • If you are working with an ODBC data source, set the ProviderName property to "System.Data.Odbc".

Set the ConnectionString property to connect to a specific database. It is recommended that you store connection strings in the ConnectionStrings element in the application's configuration file. You can then reference the stored connection strings using the <%$ ConnectionStrings:connectionStringName %> syntax in control markup. The connection string must be a valid connection string for the specified ProviderName.

The SqlDataSource control has three command properties that can contain SQL statement that modifies data: the InsertCommand, UpdateCommand, and DeleteCommand properties. The command properties can be set to an SQL statement or to the name of a stored procedure if your data source supports stored procedures. The actual syntax of the SQL statement depends on the schema of your data and on which database you are using. The statement can include parameters if the data source supports them.

NoteNote

The statement that you set for the command property is the same statement that you set for the CommandText property of an ADO.NET IDbCommand object when writing ADO.NET data-manipulation code.

The SQL statement in the UpdateCommand property is executed every time the Update method is called. The Update method is called implicitly by data-bound controls when a user clicks an Update button in a GridView, FormView, or DetailsView control. You can also call this method explicitly from your own code. The SqlDataSource control's Insert and Delete methods work similarly.

The following code example shows how you can use a SqlDataSource control to insert, update, and delete records using a FormView control. The sample connects to the SQL Server Northwind database.



<%@ 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>



The command can be the name of a stored procedure if the database you are working with supports stored procedures. If you use stored procedures to update data, you must set the UpdateCommandType property to StoredProcedure.

Parameters are used to send values for insert, update, and delete operations to the data source. Parameter names and values are based on data fields bound to a control or alternatively on parameter objects that you define explicitly. Parameters from a data-bound control include both values for the data operation and for key values to identify a specific row, as defined by the DataKeyNames property of the bound control.

You can create explicit Parameter definitions to specify parameter order, parameter type, and parameter direction as well as additional parameters other than those based on fields bound to a control. An example of this would be an output parameter that returns a value automatically generated by the data source such as an auto-incrementing primary key or a date-time stamp.

NoteNote

Explicitly specifying parameters is especially important when working with the System.Data.OleDb and System.Data.Odbc providers that do not support named parameters in SQL statements and instead use the '?' placeholder to specify a parameter. In those cases you should define parameters in the order specified in the associated SQL statement.

For more information and for examples of using parameters, see Using Parameters with the SqlDataSource Control and How a Data Source Control Creates Parameters for Data-bound Fields.

The SqlDataSource control raises events that you can handle to run your own code before and after the control performs an insert, update, or delete operation.

The SqlDataSource control raises the Inserting, Updating, or Deleting events before it executes the SQL statement for the corresponding command property. You can add a handler for these events to manipulate, reorder, or validate parameters for a statement before it is executed, as well as to cancel the command. For example, if you are using a QueryStringParameter with the SqlDataSource control, you might handle the Updating event to validate the value of the parameter before performing an update. (By default, the QueryStringParameter takes the value of a query string variable and submits it to the database without any validation.) If the value is not acceptable, you can cancel the update by setting the Cancel property of the event's SqlDataSourceCommandEventArgs object to true.

The SqlDataSource control raises the Inserted, Updated, or Deleted events after the database operation completes. You can handle these events to determine whether an exception was thrown during the database operation, to learn how many records were affected by the operation, or to examine any output values the database operation returns.

For example, the following code example uses the Updating and Updated events to execute the UpdateCommand within a transaction.


<%@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>


The SqlDataSource control can perform update and delete operations using optimistic concurrency. Optimistic concurrency is a database strategy that protects against losing changes at a data source in scenarios where multiple users are manipulating the data at the same time. The SqlDataSource control uses the ConflictDetection property to determine what level of optimistic concurrency checking to use when performing update and delete operations.

By default, the ConflictDetection property is set to ConflictOptions.OverwriteChanges, which means that update operations overwrite any existing values in the record without determining whether the record has been modified by another source. This scenario is sometimes called "last writer wins."

You can set the ConflictDetection property to ConflictOptions.CompareAllValues to ensure that the SqlDataSource control includes all original values during the update or delete command. This allows you to write your SQL statement in such a way that if the data currently in the database does not match the data that was initially read from the database, the update operation is not performed. For an example, see Optimistic Concurrency (ADO.NET). You can handle the Updated event to check how many records are affected by an update operation; if no records are updated, a concurrency violation has occurred.

Community Additions

ADD
Show:
© 2014 Microsoft