저장 프로 시저를 호출하기 위해 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에 데이터베이스에 액세스 할 수 없습니다.
- 우리는 압축하지 않고 시도했지만 느렸다.
불행하게도 MERGE로 보일 것입니다. –