将ADO.Net DataTable插入SQL表

时间:2010-03-18 17:50:41

标签: asp.net sql-server ado.net insert bulkinsert

我实施的当前解决方案非常糟糕!

我使用for... loop将ADO.NET数据表中的记录插入到SQL表中。

我想立即将数据表插入到SQL表中,而不是迭代...

这可能吗,还是我问得太多了?

4 个答案:

答案 0 :(得分:9)

您可以将整个DataTable作为单个表值参数传递,并立即插入整个TVP。以下是Table-Valued Parameters in SQL Server 2008 (ADO.NET)的示例:

// Assumes connection is an open SqlConnection.
using (connection)
{
// Create a DataTable with the modified rows.
DataTable addedCategories = CategoriesDataTable.GetChanges(
    DataRowState.Added);

// Define the INSERT-SELECT statement.
string sqlInsert = 
    "INSERT INTO dbo.Categories (CategoryID, CategoryName)"
    + " SELECT nc.CategoryID, nc.CategoryName"
    + " FROM @tvpNewCategories AS nc;"

// Configure the command and parameter.
SqlCommand insertCommand = new SqlCommand(
    sqlInsert, connection);
SqlParameter tvpParam = insertCommand.Parameters.AddWithValue(
    "@tvpNewCategories", addedCategories);
tvpParam.SqlDbType = SqlDbType.Structured;
tvpParam.TypeName = "dbo.CategoryTableType";

// Execute the command.
insertCommand.ExecuteNonQuery();
}

TVP仅在SQL 2008中可用。

答案 1 :(得分:3)

我认为您正在寻找SQLBulkCopy

答案 2 :(得分:0)

您还可以尝试以下方法。

private void button1_Click(object sender, EventArgs e)
{
    tabevent();
    DataSet ds = new DataSet();
    DataTable table = new DataTable("DataFromDGV");

    ds.Tables.Add(table);

    foreach (DataGridViewColumn col in dataGridView1.Columns)
        table.Columns.Add(col.HeaderText, typeof(string));

    foreach (DataGridViewRow row in dataGridView1.Rows)
    {
        table.Rows.Add(row);
        foreach (DataGridViewCell cell in row.Cells)
        {

                    table.Rows[row.Index][cell.ColumnIndex] = cell.Value;
                }
            }

            // DataTable ds1changes = ds1.Tables[0].GetChanges();
            if (table != null)
            {
                SqlConnection dbConn = new SqlConnection(@"Data Source=wsswe;Initial Catalog=vb;User ID=sa;Password=12345");
                SqlCommand dbCommand = new SqlCommand();
                dbCommand.Connection = dbConn;
                foreach (DataRow row in table.Rows)
                {
                    if (row["quantity"] != null && row["amount"]!=null && row["itemname"]!=null)
                    {
                        if (row["amount"].ToString() != string.Empty)
                        {
                            dbCommand.CommandText =
                            "INSERT INTO Bill" +
                            "(Itemname,Participants,rate,Quantity,Amount)" +
                            "SELECT '" + Convert.ToString(row["itemname"]) + "' AS Itemname,'" + Convert.ToString(row["Partcipants"]) + "' AS Participants,'" + Convert.ToInt32(row["rate"]) + "' AS rate,'" +
                             Convert.ToInt32(row["quantity"]) + "' AS Quantity,'" + Convert.ToInt32(row["amount"]) + "' AS Amount";


                            dbCommand.Connection.Open();
                            dbCommand.ExecuteNonQuery();

                            if (dbCommand.Connection.State != ConnectionState.Closed)
                            {
                                dbCommand.Connection.Close();
                            }

                            MessageBox.Show("inserted");

                        }
                    }
                }
            }
        } 

答案 3 :(得分:0)

SqlBulkCopy是最简单的解决方案。

        using (SqlConnection dbConn = new SqlConnection(connectionString))
        {
            dbConn.Open();
            using (SqlBulkCopy bulkCopy = new SqlBulkCopy(dbConn))
            {
                bulkCopy.DestinationTableName =
                    "dbo.MyTable";
                try
                {
                    bulkCopy.WriteToServer(myDataTable, DataRowState.Added);
                }
                catch (Exception ex)
                {
                    myLogger.Error("Fail to upload session data. ", ex);
                }
            }
        }

如果DataTable中的列与数据库表不匹配,则可以创建SqlBulkCopyColumnMapping。