2012-10-20 192 views
3
for (int i = 0; i < myClass.Length; i++) 
{ 
     string upSql = "UPDATE CumulativeTable SET EngPosFT = @EngPosFT,[email protected] WHERE RegNumber [email protected] AND [email protected] AND [email protected] AND [email protected]"; 
     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更新声明。请欣赏代码示例使用上面的代码。谢谢批量插入到SQL Server 2008中

使用此测试

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 

回答

1

看看BULK INSERT T-SQL命令。但是由于我对该命令没有太多的亲身经历,我确实看到了一些直接的机会,通过在循环外部创建命令和参数,并使用相同的sql来改进此代码,并且仅在循环内部进行必要的更改:

string upSql = "UPDATE CumulativeTable SET EngPosFT = @EngPosFT,[email protected] WHERE RegNumber [email protected] AND [email protected] AND [email protected] AND [email protected]"; 
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()); 
} 
+0

Thanks Joel。减少执行时间,但仍然保持与服务器不一致。我只希望有人可以编写批量插入代码,因为我现在试图让它正确地工作几个小时。 –

0

在这种情况下它始终是最好写一个存储过程,并呼吁在该存储过程为循环,传递所需的参数在每次调用。

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是你的表值参数。

这将作为一次往返服务器进行处理。

+0

谢谢,我会尝试。 –

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); 
        } 
       } 
      } 
     } 
    }