2009-12-21 3 views
0

저장 프로 시저를 호출하기 위해 XML RPC 메커니즘을 사용하여 호출을 수락하는 타사 응용 프로그램이 있습니다.연결이 끊긴 데이터 집합의 여러 테이블에서 SQLServer로 변경 보내기

이 메커니즘을 사용하여 여러 개의 테이블이 포함 된 ZIP 압축 데이터 세트를 일련의 업데이트/삭제/삽입으로 보냅니다. 반면 CLR sproc은 데이터의 압축을 풀고 데이터 집합을 가져옵니다.

는 그런 다음, 다음 코드가 실행됩니다 :

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

그러나이

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 이벤트에 대한 이벤트 핸들러입니다 우리가 많은 레코드를 가지고있을 때 정말 느립니다.

여러 가지 테이블에서 많은 양의 udpate/delete를 보내려면 완전히 다른 방식으로이 방법을 최적화 할 수 있습니까? 나는 이것을 위해 TSQL을 사용하고 싶지만 데이터 세트를 일반 sproc에 보내는 방법을 생각할 수는 없다.

추가 참고 :

  • 우리는 직접 SQLServer에 데이터베이스에 액세스 할 수 없습니다.
  • 우리는 압축하지 않고 시도했지만 느렸다.

답변

0

SQL Server 2008을 사용하는 경우, 당신은 SQL 서버 2005를 사용,

Look here for more info on MERGE

+0

불행하게도 MERGE로 보일 것입니다. –

관련 문제