批量插入SQL Server 2008

时间:2012-10-20 20:58:26

标签: sql-server-2008 bulkinsert

for (int i = 0; i < myClass.Length; i++)
{
        string upSql = "UPDATE CumulativeTable SET EngPosFT = @EngPosFT,EngFTAv=@EngFTAv WHERE RegNumber =@RegNumber AND Session=@Session AND Form=@Form AND Class=@Class";
        SqlCommand cmdB = new SqlCommand(upSql, connection);

        cmdB.CommandTimeout = 980000;

        cmdB.Parameters.AddWithValue("@EngPosFT", Convert.ToInt32(Pos.GetValue(i)));
        cmdB.Parameters.AddWithValue("@RegNumber", myClass.GetValue(i));
        cmdB.Parameters.AddWithValue("@EngFTAv", Math.Round((engtot / arrayCount), 2));
        cmdB.Parameters.AddWithValue("@Session", drpSess.SelectedValue);
        cmdB.Parameters.AddWithValue("@Form", drpForm.SelectedValue);
        cmdB.Parameters.AddWithValue("@Class", drpClass.SelectedValue);


        int idd = Convert.ToInt32(cmdB.ExecuteScalar());
}

假设myClass.Length为60.这会执行60个更新语句。如何将其限制为1个更新语句。请使用上面的代码代码示例,将不胜感激。感谢

尝试使用此

StringBuilder command = new StringBuilder();

            SqlCommand cmdB = null;
            for (int i = 0; i < myClass.Length; i++)
            {
                command.Append("UPDATE CumulativeTable SET" + " EngPosFT = " + Convert.ToInt32(Pos.GetValue(i)) + "," + " EngFTAv = " + Math.Round((engtot / arrayCount), 2) +
        " WHERE RegNumber = " + myClass.GetValue(i) + " AND Session= " + drpSess.SelectedValue + " AND Form= " + drpForm.SelectedValue + " AND Class= " + drpClass.SelectedValue + ";");

               //or command.AppendFormat("UPDATE CumulativeTable SET EngPosFT = {0},EngFTAv={1} WHERE RegNumber ={2} AND Session={3} AND Form={4} AND Class={5};", Convert.ToInt32(Pos.GetValue(i)), Math.Round((engtot / arrayCount), 2), myClass.GetValue(i), drpSess.SelectedValue, drpForm.SelectedValue, drpClass.SelectedValue);



            }//max length is 128 error is encountered

4 个答案:

答案 0 :(得分:1)

查看BULK INSERT T-SQL命令。但由于我没有很多关于该命令的个人经验,我确实看到一些立即机会通过在循环外创建命令和参数来使用相同的sql改进此代码,并且仅在循环内进行必要的更改:

string upSql = "UPDATE CumulativeTable SET EngPosFT = @EngPosFT,EngFTAv=@EngFTAv WHERE RegNumber =@RegNumber AND Session=@Session AND Form=@Form AND Class=@Class";
SqlCommand cmdB = new SqlCommand(upSql, connection);

cmdB.CommandTimeout = 980000;

//I had to guess at the sql types you used here. 
//Adjust this to match your actual column data types
cmdB.Parameters.Add("@EngPosFT", SqlDbType.Int);  
cmdB.Parameters.Add("@RegNumber", SqlDbType.Int); 

//It's really better to use explicit types here, too.
//I'll just update the first parameter as an example of how it looks:
cmdB.Parameters.Add("@EngFTAv", SqlDbType.Decimal).Value = Math.Round((engtot / arrayCount), 2));
cmdB.Parameters.AddWithValue("@Session", drpSess.SelectedValue);
cmdB.Parameters.AddWithValue("@Form", drpForm.SelectedValue);
cmdB.Parameters.AddWithValue("@Class", SqlDbTypedrpClass.SelectedValue);

for (int i = 0; i < myClass.Length; i++)
{
    cmdB.Parameters[0].Value = Convert.ToInt32(Pos.GetValue(i)));
    cmdB.Parameters[1].Value = myClass.GetValue(i));

    int idd = Convert.ToInt32(cmdB.ExecuteScalar());
}

答案 1 :(得分:1)

在这种情况下,最好创建一个接受Table Valued Parameter的存储过程。在.NET方面,您创建了一个DataTable对象,其中包含您要使用的每组值的行。

在SQL Server方面,您可以将参数视为查询中的另一个表。所以在存储过程中,你有:

UPDATE a
SET
    EngPosFT = b.EngPosFT,
    EngFTAv=b.EngFTAv
FROM
    CumulativeTable a
       inner join
    @MyParm b
       on
           a.RegNumber =b.RegNumber AND
           a.Session=b.Session AND
           a.Form=b.Form AND
           a.Class=b.Class

@MyParm是您的表值参数。

然后,这将作为服务器的单次往返处理。

答案 2 :(得分:0)

在这种情况下,最好编写 存储过程 并在 for 循环中调用该存储过程,并传递必要的参数在每次通话时。

答案 3 :(得分:0)

using System;
using System.Data;
using System.Data.SqlClient;

    namespace DataTableExample
    {
        class Program
        {
          static void Main(string[] args)
            {
                DataTable prodSalesData = new DataTable("ProductSalesData");

                // Create Column 1: SaleDate
                DataColumn dateColumn = new DataColumn();
                dateColumn.DataType = Type.GetType("System.DateTime");
                dateColumn.ColumnName = "SaleDate";

                // Create Column 2: ProductName
                DataColumn productNameColumn = new DataColumn();
                productNameColumn.ColumnName = "ProductName";

                // Create Column 3: TotalSales
                DataColumn totalSalesColumn = new DataColumn();
                totalSalesColumn.DataType = Type.GetType("System.Int32");
                totalSalesColumn.ColumnName = "TotalSales";

                // Add the columns to the ProductSalesData DataTable
                prodSalesData.Columns.Add(dateColumn);
                prodSalesData.Columns.Add(productNameColumn);
                prodSalesData.Columns.Add(totalSalesColumn);

                // Let's populate the datatable with our stats.
                // You can add as many rows as you want here!

                // Create a new row
                DataRow dailyProductSalesRow = prodSalesData.NewRow();
                dailyProductSalesRow["SaleDate"] = DateTime.Now.Date;
                dailyProductSalesRow["ProductName"] = "Nike";
                dailyProductSalesRow["TotalSales"] = 10;

                // Add the row to the ProductSalesData DataTable
                prodSalesData.Rows.Add(dailyProductSalesRow);

                // Copy the DataTable to SQL Server using SqlBulkCopy
                using (SqlConnection dbConnection = new SqlConnection("Data Source=ProductHost;Initial Catalog=dbProduct;Integrated Security=SSPI;Connection Timeout=60;Min Pool Size=2;Max Pool Size=20;"))
                {
                    dbConnection.Open();
                    using (SqlBulkCopy s = new SqlBulkCopy(dbConnection))
                    {
                        s.DestinationTableName = prodSalesData.TableName;

                        foreach (var column in prodSalesData.Columns)
                            s.ColumnMappings.Add(column.ToString(), column.ToString());

                        s.WriteToServer(prodSalesData);
                    }
                }
            }
        }
    }