2012-10-20 186 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); 
        } 
       } 
      } 
     } 
    }