This documentation is archived and is not being maintained.

SqlBulkCopy.WriteToServer Method (DataTable, DataRowState)

Copies only rows that match the supplied row state in the supplied DataTable to a destination table specified by the DestinationTableName property of the SqlBulkCopy object.

Namespace:  System.Data.SqlClient
Assembly:  System.Data (in System.Data.dll)

public void WriteToServer(
	DataTable table,
	DataRowState rowState


Type: System.Data.DataTable

A DataTable whose rows will be copied to the destination table.

Type: System.Data.DataRowState

A value from the DataRowState enumeration. Only rows matching the row state are copied to the destination.

Only rows in the DataTable that are in the states indicated in the rowState argument and have not been deleted are copied to the destination table.


If Deleted is specified, any Unchanged, Added, and Modified rows will also be copied to the server. No exception will be raised.

While the bulk copy operation is in progress, the associated destination SqlConnection is busy serving it, and no other operations can be performed on the connection.

The ColumnMappings collection maps from the DataTable columns to the destination database table.

The following Console application demonstrates how to bulk load only the rows in a DataTable that match a specified state. In this case, only unchanged rows are added. The destination table is a table in the AdventureWorks database.

In this example, a DataTable is created at run time and three rows are added to it. Before the WriteToServer method is executed, one of the rows is edited. The WriteToServer method is called with a DataRowState.Unchanged rowState argument, so only the two unchanged rows are bulk copied to the destination.

Important noteImportant Note:

This sample will not run unless you have created the work tables as described in Bulk Copy Example Setup (ADO.NET). This code is provided to demonstrate the syntax for using SqlBulkCopy only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a Transact-SQL INSERT … SELECT statement to copy the data.

using System.Data.SqlClient;

class Program
    static void Main()
        string connectionString = GetConnectionString();
        // Open a connection to the AdventureWorks database. 
        using (SqlConnection connection =
                   new SqlConnection(connectionString))

            // Perform an initial count on the destination table.
            SqlCommand commandRowCount = new SqlCommand(
                "SELECT COUNT(*) FROM " +
            long countStart = System.Convert.ToInt32(
            Console.WriteLine("Starting row count = {0}", countStart);

            // Create a table with some rows. 
            DataTable newProducts = MakeTable();

            // Make a change to one of the rows in the DataTable.
            DataRow row = newProducts.Rows[0];
            row["Name"] = "AAA";

            // Create the SqlBulkCopy object.  
            // Note that the column positions in the source DataTable  
            // match the column positions in the destination table so  
            // there is no need to map columns.  
            using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
                bulkCopy.DestinationTableName = 

                    // Write unchanged rows from the source to the destination.
                    bulkCopy.WriteToServer(newProducts, DataRowState.Unchanged);
                catch (Exception ex)

            // Perform a final count on the destination  
            // table to see how many rows were added.
            long countEnd = System.Convert.ToInt32(
            Console.WriteLine("Ending row count = {0}", countEnd);
            Console.WriteLine("{0} rows were added.", countEnd - countStart);
            Console.WriteLine("Press Enter to finish.");

    private static DataTable MakeTable()
        // Create a new DataTable named NewProducts. 
        DataTable newProducts = new DataTable("NewProducts");

        // Add three column objects to the table. 
        DataColumn productID = new DataColumn();
        productID.DataType = System.Type.GetType("System.Int32");
        productID.ColumnName = "ProductID";
        productID.AutoIncrement = true;

        DataColumn productName = new DataColumn();
        productName.DataType = System.Type.GetType("System.String");
        productName.ColumnName = "Name";

        DataColumn productNumber = new DataColumn();
        productNumber.DataType = System.Type.GetType("System.String");
        productNumber.ColumnName = "ProductNumber";

        // Create an array for DataColumn objects.
        DataColumn[] keys = new DataColumn[1];
        keys[0] = productID;
        newProducts.PrimaryKey = keys;

        // Add some new rows to the collection. 
        DataRow row = newProducts.NewRow();
        row["Name"] = "CC-101-WH";
        row["ProductNumber"] = "Cyclocomputer - White";

        row = newProducts.NewRow();
        row["Name"] = "CC-101-BK";
        row["ProductNumber"] = "Cyclocomputer - Black";

        row = newProducts.NewRow();
        row["Name"] = "CC-101-ST";
        row["ProductNumber"] = "Cyclocomputer - Stainless";

        // Return the new DataTable.  
        return newProducts;
    private static string GetConnectionString()
        // To avoid storing the connection string in your code,  
        // you can retrieve it from a configuration file. 
        return "Data Source=(local); " +
            " Integrated Security=true;" +
            "Initial Catalog=AdventureWorks;";

Windows 7, Windows Vista, Windows XP SP2, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP Starter Edition, Windows Server 2008 R2, Windows Server 2008, Windows Server 2003, Windows Server 2000 SP4, Windows Millennium Edition, Windows 98

The .NET Framework and .NET Compact Framework do not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.

.NET Framework

Supported in: 3.5, 3.0, 2.0