2009-12-21 65 views
0

我們有第三方應用程序,它使用XML RPC機制接受調用以調用存儲的特效。將斷開連接的數據集中多個表的更改發送到SQLServer

我們使用這種機制發送一個包含多個表的ZIP壓縮數據集,其中包含一堆update/delete/insert。另一方面,CLR sproc解壓縮數據並獲取數據集。

接着,下面的代碼被執行:

using (var conn = new SqlConnection("context connection=true")) 
    { 
     if (conn.State == ConnectionState.Closed) 
      conn.Open(); 

     try 
     { 
      foreach (DataTable table in ds.Tables) 
      { 
       string columnList = ""; 
       for (int i = 0; i < table.Columns.Count; i++) 
       { 
        if (i == 0) 
         columnList = table.Columns[0].ColumnName; 
        else 
         columnList += "," + table.Columns[i].ColumnName; 
       } 

       var da = new SqlDataAdapter("SELECT " + columnList + " FROM " + table.TableName, conn); 

       var builder = new SqlCommandBuilder(da); 
       builder.ConflictOption = ConflictOption.OverwriteChanges; 

       da.RowUpdating += onUpdatingRow; 
       da.Update(ds, table.TableName); 

      } 
     } 

     catch (....) 
     { 
      ..... 
     } 
    } 

下面是RowUpdating事件的事件處理程序:

public static void onUpdatingRow(object sender, SqlRowUpdatingEventArgs e) 
{ 
    if ((e.StatementType == StatementType.Update) && (e.Command == null)) 
    { 
     e.Command = CreateUpdateCommand(e.Row, sender as SqlDataAdapter); 
     e.Status = UpdateStatus.Continue; 
    } 
} 

和CreateUpdateCommand方法:

private static SqlCommand CreateUpdateCommand(DataRow row, SqlDataAdapter da) 
{ 
    string whereClause = ""; 
    string setClause = ""; 

    SqlConnection conn = da.SelectCommand.Connection; 
    for (int i = 0; i < row.Table.Columns.Count; i++) 
    { 
     char quoted; 

     if ((row.Table.Columns[i].DataType == Type.GetType("System.String")) || 
      (row.Table.Columns[i].DataType == Type.GetType("System.DateTime"))) 
      quoted = '\''; 
     else 
      quoted = ' '; 

     string val = row[i].ToString(); 
     if (row.Table.Columns[i].DataType == Type.GetType("System.Boolean")) 
      val = (bool)row[i] ? "1" : "0"; 

     bool isPrimaryKey = false; 

     for (int j = 0; j < row.Table.PrimaryKey.Length; j++) 
     { 
      if (row.Table.PrimaryKey[j].ColumnName == row.Table.Columns[i].ColumnName) 
      { 
       if (whereClause != "") 
        whereClause += " AND "; 
       if (row[i] == DBNull.Value) 
        whereClause += row.Table.Columns[i].ColumnName + "=NULL"; 
       else 
        whereClause += row.Table.Columns[i].ColumnName + "=" + quoted + 
            val + quoted; 
       isPrimaryKey = true; 
       break; 
      } 
     } 

     /* Only values for column that is not a primary key can be modified */ 
     if (!isPrimaryKey) 
     { 
      if (setClause != "") 
       setClause += ", "; 

      if (row[i] == DBNull.Value) 
       setClause += row.Table.Columns[i].ColumnName + "=NULL"; 
      else 
       setClause += row.Table.Columns[i].ColumnName + "=" + quoted + 
          val + quoted; 

     } 
    } 

    return new SqlCommand("UPDATE " + row.Table.TableName + " SET " + setClause + " WHERE " + whereClause, conn); 
} 

然而,這我們有很多記錄的時候真的很慢。

有沒有一種方法來優化這個或完全不同的方式發送大量udpate/delete在幾個表上?我真的很想爲此使用TSQL,但無法想出將數據集發送到常規存儲過程的方法。

其他注意事項:

  • 我們不能直接訪問SQL Server數據庫。
  • 我們嘗試不加壓縮,速度較慢。

回答

相關問題