C# 我可以在SQL中使用什么作为内部标识符?

C# 我可以在SQL中使用什么作为内部标识符?,c#,sql-server,C#,Sql Server,首先介绍一下背景: 我开发了一种通过使用IEnumerable和yield从SQL中的表中批量或页面检索行的方法。当您需要只读访问时,它非常有效,但当您需要对底层数据进行更新时,它就不那么有效了 因此,我编写了一个方法,它接受一个通用的DataTable,并构建一个update语句,然后将该语句连同整个DataTable作为表值参数传递给SQL 方法如下所示: string[] validColumns = SQL_Columns.Split(','); foreach(DataColu

首先介绍一下背景:

我开发了一种通过使用
IEnumerable
yield
从SQL中的表中批量或页面检索行的方法。当您需要只读访问时,它非常有效,但当您需要对底层数据进行更新时,它就不那么有效了

因此,我编写了一个方法,它接受一个通用的
DataTable
,并构建一个update语句,然后将该语句连同整个
DataTable
作为表值参数传递给SQL

方法如下所示:

string[] validColumns = SQL_Columns.Split(',');
    foreach(DataColumn column in p_UpdatesTable.Columns)
    {
      if(!validColumns.Contains(column.ColumnName))
      {
        throw new Exception("Column '" + column.ColumnName + "' is not valid for this table");
      }
    }

    //Establish SQL Connection
    using (SqlConnection sqlConnection = new SqlConnection(connectionString))
    {
      sqlConnection.Open();
      StringBuilder commandBuilder = new StringBuilder();
      commandBuilder.Append("UPDATE Table SET ");
      List<string> columnsToUpdate = new List<string>(p_UpdatesTable.Columns.Count);
      foreach(DataColumn column in p_UpdatesTable.Columns)
      {
        if (!column.ColumnName.Equals("UID", StringComparison.InvariantCultureIgnoreCase))
        {
          StringBuilder columnBuilder = new StringBuilder();
          columnBuilder.Append(column.ColumnName);
          columnBuilder.Append(" = U.");
          columnBuilder.Append(column.ColumnName);
          columnsToUpdate.Add(columnBuilder.ToString());
        }
      }
      commandBuilder.Append(string.Join(",", columnsToUpdate.ToArray()));
      commandBuilder.Append(" FROM @UpdateTable AS U WHERE UID = U.UID");
      using (SqlCommand sqlCommand = new SqlCommand(commandBuilder.ToString(), sqlConnection))
      {
        SqlParameter updateTableParameter = sqlCommand.Parameters.Add("UpdateTable", SqlDbType.Structured);
        updateTableParameter.Value = p_UpdatesTable;
        int rowsAffected = sqlCommand.ExecuteNonQuery();
        if(rowsAffected != p_UpdatesTable.Rows.Count)
        {
          throw new Exception("Update command affected " + rowsAffected + " rows out of the " + p_UpdatesTable.Rows.Count + " expected.");
        }
      }
      sqlConnection.Dispose();
    }
      |  UID   | column 1 | column 2 | column 3 |
row 1 |    1   |   x      |    y     |    ?     |
row 2 |    2   |   x      |    y     |    z     |
public sealed class Maybe<T> {
    private readonly T value;
    private readonly bool hasValue;

    private Maybe() {
        hasValue = false;
    }

    public readonly Maybe<T> Nothing = new Maybe();

    public Maybe(T value) {
        this.value = value;
        hasValue = true;
    }

    public T Value {
        get {
            return value;
        }
    }

    public bool HasValue {
        get {
            return value;
        }
    }
}
private void AddUpdate<T>(DataTable p_UpdateTable, string p_ColumnName, long p_uid, Maybe<T> p_value) {
    // ...
    if(existingRow != null) {
        if(p_value.HasValue)
            existingRow[p_ColumnName] = p_value.Value;
    }
    else {
        DataRow newRow = p_UpdateTable.NewRow();
        newRow["UID"] = p_uid;
        if(p_value.HasValue)
            newRow[p_ColumnName] = p_value.Value;
        p_UpdateTable.Rows.Add(newRow);
    }
    // ...
}
在第二排,它看起来像这样:

string[] validColumns = SQL_Columns.Split(',');
    foreach(DataColumn column in p_UpdatesTable.Columns)
    {
      if(!validColumns.Contains(column.ColumnName))
      {
        throw new Exception("Column '" + column.ColumnName + "' is not valid for this table");
      }
    }

    //Establish SQL Connection
    using (SqlConnection sqlConnection = new SqlConnection(connectionString))
    {
      sqlConnection.Open();
      StringBuilder commandBuilder = new StringBuilder();
      commandBuilder.Append("UPDATE Table SET ");
      List<string> columnsToUpdate = new List<string>(p_UpdatesTable.Columns.Count);
      foreach(DataColumn column in p_UpdatesTable.Columns)
      {
        if (!column.ColumnName.Equals("UID", StringComparison.InvariantCultureIgnoreCase))
        {
          StringBuilder columnBuilder = new StringBuilder();
          columnBuilder.Append(column.ColumnName);
          columnBuilder.Append(" = U.");
          columnBuilder.Append(column.ColumnName);
          columnsToUpdate.Add(columnBuilder.ToString());
        }
      }
      commandBuilder.Append(string.Join(",", columnsToUpdate.ToArray()));
      commandBuilder.Append(" FROM @UpdateTable AS U WHERE UID = U.UID");
      using (SqlCommand sqlCommand = new SqlCommand(commandBuilder.ToString(), sqlConnection))
      {
        SqlParameter updateTableParameter = sqlCommand.Parameters.Add("UpdateTable", SqlDbType.Structured);
        updateTableParameter.Value = p_UpdatesTable;
        int rowsAffected = sqlCommand.ExecuteNonQuery();
        if(rowsAffected != p_UpdatesTable.Rows.Count)
        {
          throw new Exception("Update command affected " + rowsAffected + " rows out of the " + p_UpdatesTable.Rows.Count + " expected.");
        }
      }
      sqlConnection.Dispose();
    }
      |  UID   | column 1 | column 2 | column 3 |
row 1 |    1   |   x      |    y     |    ?     |
row 2 |    2   |   x      |    y     |    z     |
public sealed class Maybe<T> {
    private readonly T value;
    private readonly bool hasValue;

    private Maybe() {
        hasValue = false;
    }

    public readonly Maybe<T> Nothing = new Maybe();

    public Maybe(T value) {
        this.value = value;
        hasValue = true;
    }

    public T Value {
        get {
            return value;
        }
    }

    public bool HasValue {
        get {
            return value;
        }
    }
}
private void AddUpdate<T>(DataTable p_UpdateTable, string p_ColumnName, long p_uid, Maybe<T> p_value) {
    // ...
    if(existingRow != null) {
        if(p_value.HasValue)
            existingRow[p_ColumnName] = p_value.Value;
    }
    else {
        DataRow newRow = p_UpdateTable.NewRow();
        newRow["UID"] = p_uid;
        if(p_value.HasValue)
            newRow[p_ColumnName] = p_value.Value;
        p_UpdateTable.Rows.Add(newRow);
    }
    // ...
}
第1行第3列的值从未设置,因此默认为null。当我使用update语句时,SQL会将该值设置为null,即使表中已经有内容,但我根本不希望它更新该行的字段,因为我没有为该行指定值


我希望能够将一个值替换为
,而不是将其默认为null,这样我就可以将update语句更改为类似
update Table SET Column1=U.Column1,Column2=U.Column2,Column3=CASE当U.Column3=somevalue然后Column3 ELSE U.Column3从@UpdateTable U
结束时,您可以使自己有一点
可能
它可以是
T
的实际值,在这种情况下,您可以推动更新,也可以是一个特殊的非a值。它可能看起来像这样:

string[] validColumns = SQL_Columns.Split(',');
    foreach(DataColumn column in p_UpdatesTable.Columns)
    {
      if(!validColumns.Contains(column.ColumnName))
      {
        throw new Exception("Column '" + column.ColumnName + "' is not valid for this table");
      }
    }

    //Establish SQL Connection
    using (SqlConnection sqlConnection = new SqlConnection(connectionString))
    {
      sqlConnection.Open();
      StringBuilder commandBuilder = new StringBuilder();
      commandBuilder.Append("UPDATE Table SET ");
      List<string> columnsToUpdate = new List<string>(p_UpdatesTable.Columns.Count);
      foreach(DataColumn column in p_UpdatesTable.Columns)
      {
        if (!column.ColumnName.Equals("UID", StringComparison.InvariantCultureIgnoreCase))
        {
          StringBuilder columnBuilder = new StringBuilder();
          columnBuilder.Append(column.ColumnName);
          columnBuilder.Append(" = U.");
          columnBuilder.Append(column.ColumnName);
          columnsToUpdate.Add(columnBuilder.ToString());
        }
      }
      commandBuilder.Append(string.Join(",", columnsToUpdate.ToArray()));
      commandBuilder.Append(" FROM @UpdateTable AS U WHERE UID = U.UID");
      using (SqlCommand sqlCommand = new SqlCommand(commandBuilder.ToString(), sqlConnection))
      {
        SqlParameter updateTableParameter = sqlCommand.Parameters.Add("UpdateTable", SqlDbType.Structured);
        updateTableParameter.Value = p_UpdatesTable;
        int rowsAffected = sqlCommand.ExecuteNonQuery();
        if(rowsAffected != p_UpdatesTable.Rows.Count)
        {
          throw new Exception("Update command affected " + rowsAffected + " rows out of the " + p_UpdatesTable.Rows.Count + " expected.");
        }
      }
      sqlConnection.Dispose();
    }
      |  UID   | column 1 | column 2 | column 3 |
row 1 |    1   |   x      |    y     |    ?     |
row 2 |    2   |   x      |    y     |    z     |
public sealed class Maybe<T> {
    private readonly T value;
    private readonly bool hasValue;

    private Maybe() {
        hasValue = false;
    }

    public readonly Maybe<T> Nothing = new Maybe();

    public Maybe(T value) {
        this.value = value;
        hasValue = true;
    }

    public T Value {
        get {
            return value;
        }
    }

    public bool HasValue {
        get {
            return value;
        }
    }
}
private void AddUpdate<T>(DataTable p_UpdateTable, string p_ColumnName, long p_uid, Maybe<T> p_value) {
    // ...
    if(existingRow != null) {
        if(p_value.HasValue)
            existingRow[p_ColumnName] = p_value.Value;
    }
    else {
        DataRow newRow = p_UpdateTable.NewRow();
        newRow["UID"] = p_uid;
        if(p_value.HasValue)
            newRow[p_ColumnName] = p_value.Value;
        p_UpdateTable.Rows.Add(newRow);
    }
    // ...
}
公共密封类{
私有只读T值;
私有只读布尔值;
二等兵{
hasValue=false;
}
public readonly Maybe Nothing=new Maybe();
公共价值(T值){
这个值=值;
hasValue=true;
}
公共价值{
得到{
返回值;
}
}
公共布尔值{
得到{
返回值;
}
}
}
您可以这样使用:

string[] validColumns = SQL_Columns.Split(',');
    foreach(DataColumn column in p_UpdatesTable.Columns)
    {
      if(!validColumns.Contains(column.ColumnName))
      {
        throw new Exception("Column '" + column.ColumnName + "' is not valid for this table");
      }
    }

    //Establish SQL Connection
    using (SqlConnection sqlConnection = new SqlConnection(connectionString))
    {
      sqlConnection.Open();
      StringBuilder commandBuilder = new StringBuilder();
      commandBuilder.Append("UPDATE Table SET ");
      List<string> columnsToUpdate = new List<string>(p_UpdatesTable.Columns.Count);
      foreach(DataColumn column in p_UpdatesTable.Columns)
      {
        if (!column.ColumnName.Equals("UID", StringComparison.InvariantCultureIgnoreCase))
        {
          StringBuilder columnBuilder = new StringBuilder();
          columnBuilder.Append(column.ColumnName);
          columnBuilder.Append(" = U.");
          columnBuilder.Append(column.ColumnName);
          columnsToUpdate.Add(columnBuilder.ToString());
        }
      }
      commandBuilder.Append(string.Join(",", columnsToUpdate.ToArray()));
      commandBuilder.Append(" FROM @UpdateTable AS U WHERE UID = U.UID");
      using (SqlCommand sqlCommand = new SqlCommand(commandBuilder.ToString(), sqlConnection))
      {
        SqlParameter updateTableParameter = sqlCommand.Parameters.Add("UpdateTable", SqlDbType.Structured);
        updateTableParameter.Value = p_UpdatesTable;
        int rowsAffected = sqlCommand.ExecuteNonQuery();
        if(rowsAffected != p_UpdatesTable.Rows.Count)
        {
          throw new Exception("Update command affected " + rowsAffected + " rows out of the " + p_UpdatesTable.Rows.Count + " expected.");
        }
      }
      sqlConnection.Dispose();
    }
      |  UID   | column 1 | column 2 | column 3 |
row 1 |    1   |   x      |    y     |    ?     |
row 2 |    2   |   x      |    y     |    z     |
public sealed class Maybe<T> {
    private readonly T value;
    private readonly bool hasValue;

    private Maybe() {
        hasValue = false;
    }

    public readonly Maybe<T> Nothing = new Maybe();

    public Maybe(T value) {
        this.value = value;
        hasValue = true;
    }

    public T Value {
        get {
            return value;
        }
    }

    public bool HasValue {
        get {
            return value;
        }
    }
}
private void AddUpdate<T>(DataTable p_UpdateTable, string p_ColumnName, long p_uid, Maybe<T> p_value) {
    // ...
    if(existingRow != null) {
        if(p_value.HasValue)
            existingRow[p_ColumnName] = p_value.Value;
    }
    else {
        DataRow newRow = p_UpdateTable.NewRow();
        newRow["UID"] = p_uid;
        if(p_value.HasValue)
            newRow[p_ColumnName] = p_value.Value;
        p_UpdateTable.Rows.Add(newRow);
    }
    // ...
}
private void AddUpdate(数据表p_UpdateTable,字符串p_ColumnName,长p_uid,可能是p_值){
// ...
如果(existingRow!=null){
if(p_值.HasValue)
existingRow[p_ColumnName]=p_value.value;
}
否则{
DataRow newRow=p_UpdateTable.newRow();
newRow[“UID”]=p_UID;
if(p_值.HasValue)
newRow[p_ColumnName]=p_value.value;
p_UpdateTable.Rows.Add(newRow);
}
// ...
}

顺便说一句,
DataTable
参数不需要
ref

我最终选择了一条稍微不同的路线,不是使用标识符,而是完全使用另一列

我的
AddUpdate
现在看起来像这样:

private void AddUpdate(DataTable p_UpdateTable, string p_ColumnName, long p_uid, object p_value)
{
  if (!StronglyTypedDataSet.Columns.Contains(p_ColumnName))
  {
    throw new ArgumentException("Table '" + p_ColumnName + "' does not exist in table", "p_ColumnName");
  }
  if (!p_UpdateTable.Columns.Contains(p_ColumnName))
  {
    var matchingColumn = StronglyTypedDataSet.Columns.Cast<DataColumn>().Where(c => c.ColumnName.Equals(p_ColumnName)).First();
    DataColumn columnToAdd = p_UpdateTable.Columns.Add(p_ColumnName, matchingColumn.DataType);
    columnToAdd.MaxLength = matchingColumn.MaxLength;
    DataColumn setNullColumn = p_UpdateTable.Columns.Add(p_ColumnName + "_null", typeof(bool));
    setNullColumn.DefaultValue = false;
  }
  var existingRow = p_UpdateTable.Rows.Cast<DataRow>().Where(r => Convert.ToInt64(r["UID"]) == p_uid).FirstOrDefault();
  if (existingRow != null)
  {
    existingRow[p_ColumnName] = p_value;
    if (p_value == null || p_value == DBNull.Value)
    {
      existingRow[p_ColumnName + "_null"] = true;
    }
  }
  else
  {
    DataRow newRow = p_UpdateTable.NewRow();
    newRow["UID"] = p_uid;
    newRow[p_ColumnName] = p_value;
    if (p_value == null || p_value == DBNull.Value)
    {
      newRow[p_ColumnName + "_null"] = true;
    }
    p_UpdateTable.Rows.Add(newRow);
  }
}
string[] validColumns = SQL_Columns.Split(',');
    var trimmed = validColumns.Select(c => c.Trim());
    foreach(DataColumn column in p_UpdatesTable.Columns)
    {
      if(!column.ColumnName.EndsWith("_null") && !trimmed.Contains(column.ColumnName))
      {
        throw new Exception("Column '" + column.ColumnName + "' is not valid for table");
      }
    }
    string tableTypeName = "dbo.UpdateSpecific" + Guid.NewGuid().ToString().Replace("-", "").Replace("{", "").Replace("}", "");
    StringBuilder tableTypeBuilder = new StringBuilder();
    tableTypeBuilder.Append("CREATE TYPE ");
    tableTypeBuilder.Append(tableTypeName);
    tableTypeBuilder.Append(" AS TABLE (");
    List<string> tableTypeColumns = new List<string>(p_UpdatesTable.Columns.Count);

    StringBuilder commandBuilder = new StringBuilder();
    commandBuilder.Append("UPDATE Table SET ");
    List<string> columnsToUpdate = new List<string>(p_UpdatesTable.Columns.Count);
    foreach (DataColumn column in p_UpdatesTable.Columns)
    {
      //build command to create table type
      StringBuilder columnTypeBuilder = new StringBuilder();
      columnTypeBuilder.Append("[");
      columnTypeBuilder.Append(column.ColumnName);
      columnTypeBuilder.Append("] ");
      if(column.DataType == typeof(int))
      {
        columnTypeBuilder.Append("INT");
      }
      else if(column.DataType == typeof(long))
      {
        columnTypeBuilder.Append("BIGINT");
      }
      else if(column.DataType == typeof(bool))
      {
        columnTypeBuilder.Append("BIT");
      }
      else if(column.DataType == typeof(string))
      {
        columnTypeBuilder.Append("VARCHAR(");
        columnTypeBuilder.Append(column.MaxLength);
        columnTypeBuilder.Append(")");
      }
      else if(column.DataType == typeof(byte[]))
      {
        columnTypeBuilder.Append("IMAGE");
      }
      tableTypeColumns.Add(columnTypeBuilder.ToString());

      //build actual update statement
      if (!column.ColumnName.Equals("UID", StringComparison.InvariantCultureIgnoreCase) && !column.ColumnName.EndsWith("_null"))
      {
        StringBuilder columnBuilder = new StringBuilder();
        columnBuilder.Append(column.ColumnName);
        columnBuilder.Append(" = (CASE WHEN U.");
        columnBuilder.Append(column.ColumnName);
        columnBuilder.Append(" IS NULL THEN (CASE WHEN ISNULL(U.");
        columnBuilder.Append(column.ColumnName);
        columnBuilder.Append("_null, 0) = 1 THEN U.");
        columnBuilder.Append(column.ColumnName);
        columnBuilder.Append(" ELSE C.");
        columnBuilder.Append(column.ColumnName);
        columnBuilder.Append(" END) ELSE U.");
        columnBuilder.Append(column.ColumnName);
        columnBuilder.Append(" END)");
        columnsToUpdate.Add(columnBuilder.ToString());
      }
    }
    tableTypeBuilder.Append(string.Join(",", tableTypeColumns.ToArray()));
    tableTypeBuilder.Append(")");

    commandBuilder.Append(string.Join(",", columnsToUpdate.ToArray()));
    commandBuilder.Append(" FROM Table AS C JOIN @UpdateTable AS U ON C.UID = U.UID");

    //Establish SQL Connection
    using (SqlConnection sqlConnection = new SqlConnection(context.strContext[(int)eCCE_Context._CONNECTION_STRING]))
    {
      sqlConnection.Open();
      try
      {
        using (SqlCommand createTableTypeCommand = new SqlCommand(tableTypeBuilder.ToString(), sqlConnection))
        {
          createTableTypeCommand.ExecuteNonQuery();
        }

        using (SqlCommand sqlCommand = new SqlCommand(commandBuilder.ToString(), sqlConnection))
        {
          SqlParameter updateTableParameter = sqlCommand.Parameters.Add("@UpdateTable", SqlDbType.Structured);
          updateTableParameter.Value = p_UpdatesTable;
          updateTableParameter.TypeName = tableTypeName;
          int rowsAffected = sqlCommand.ExecuteNonQuery();
          if (rowsAffected != p_UpdatesTable.Rows.Count)
          {
            throw new Exception("Update command affected " + rowsAffected + " rows out of the " + p_UpdatesTable.Rows.Count + " expected.");
          }
        }
      }
      finally
      {
        string dropStatement = "IF  EXISTS (SELECT * FROM sys.types st JOIN sys.schemas ss ON st.schema_id = ss.schema_id WHERE st.name = N'"+ tableTypeName.Substring(tableTypeName.IndexOf(".")+1) +"' AND ss.name = N'dbo') DROP TYPE " + tableTypeName;
        using (SqlCommand dropTableTypeCommand = new SqlCommand(dropStatement, sqlConnection))
        {
          dropTableTypeCommand.ExecuteNonQuery();
        }
      }
      sqlConnection.Dispose();
    }
private void AddUpdate(数据表p_UpdateTable、字符串p_ColumnName、长p_uid、对象p_值)
{
如果(!StronglyTypedDataSet.Columns.Contains(p\u ColumnName))
{
抛出新ArgumentException(“表“”+p_ColumnName+””在表中不存在,“p_ColumnName”);
}
如果(!p_UpdateTable.Columns.Contains(p_ColumnName))
{
var matchingColumn=StronglyTypedDataSet.Columns.Cast()。其中(c=>c.ColumnName.Equals(p_ColumnName)).First();
DataColumn columnToAdd=p_UpdateTable.Columns.Add(p_ColumnName,matchingColumn.DataType);
columnToAdd.MaxLength=匹配column.MaxLength;
DataColumn setNullColumn=p_UpdateTable.Columns.Add(p_ColumnName+“_null”,typeof(bool));
setNullColumn.DefaultValue=false;
}
var existingRow=p_UpdateTable.Rows.Cast()。其中(r=>Convert.ToInt64(r[“UID]”))==p_UID.FirstOrDefault();
如果(existingRow!=null)
{
existingRow[p_ColumnName]=p_值;
if(p_值==null | | p_值==DBNull.value)
{
existingRow[p_ColumnName+“_null”]=true;
}
}
其他的
{
DataRow newRow=p_UpdateTable.newRow();
newRow[“UID”]=p_UID;
newRow[p_ColumnName]=p_值;
if(p_值==null | | p_值==DBNull.value)
{
newRow[p_ColumnName+“_null”]=true;
}
p_UpdateTable.Rows.Add(newRow);
}
}
这样,如果一个列被默认为null,因为它是在一些行被添加到表中之后才被添加的,那么我可以在我的update语句中执行一个不更新该值的检查

update语句现在如下所示:

private void AddUpdate(DataTable p_UpdateTable, string p_ColumnName, long p_uid, object p_value)
{
  if (!StronglyTypedDataSet.Columns.Contains(p_ColumnName))
  {
    throw new ArgumentException("Table '" + p_ColumnName + "' does not exist in table", "p_ColumnName");
  }
  if (!p_UpdateTable.Columns.Contains(p_ColumnName))
  {
    var matchingColumn = StronglyTypedDataSet.Columns.Cast<DataColumn>().Where(c => c.ColumnName.Equals(p_ColumnName)).First();
    DataColumn columnToAdd = p_UpdateTable.Columns.Add(p_ColumnName, matchingColumn.DataType);
    columnToAdd.MaxLength = matchingColumn.MaxLength;
    DataColumn setNullColumn = p_UpdateTable.Columns.Add(p_ColumnName + "_null", typeof(bool));
    setNullColumn.DefaultValue = false;
  }
  var existingRow = p_UpdateTable.Rows.Cast<DataRow>().Where(r => Convert.ToInt64(r["UID"]) == p_uid).FirstOrDefault();
  if (existingRow != null)
  {
    existingRow[p_ColumnName] = p_value;
    if (p_value == null || p_value == DBNull.Value)
    {
      existingRow[p_ColumnName + "_null"] = true;
    }
  }
  else
  {
    DataRow newRow = p_UpdateTable.NewRow();
    newRow["UID"] = p_uid;
    newRow[p_ColumnName] = p_value;
    if (p_value == null || p_value == DBNull.Value)
    {
      newRow[p_ColumnName + "_null"] = true;
    }
    p_UpdateTable.Rows.Add(newRow);
  }
}
string[] validColumns = SQL_Columns.Split(',');
    var trimmed = validColumns.Select(c => c.Trim());
    foreach(DataColumn column in p_UpdatesTable.Columns)
    {
      if(!column.ColumnName.EndsWith("_null") && !trimmed.Contains(column.ColumnName))
      {
        throw new Exception("Column '" + column.ColumnName + "' is not valid for table");
      }
    }
    string tableTypeName = "dbo.UpdateSpecific" + Guid.NewGuid().ToString().Replace("-", "").Replace("{", "").Replace("}", "");
    StringBuilder tableTypeBuilder = new StringBuilder();
    tableTypeBuilder.Append("CREATE TYPE ");
    tableTypeBuilder.Append(tableTypeName);
    tableTypeBuilder.Append(" AS TABLE (");
    List<string> tableTypeColumns = new List<string>(p_UpdatesTable.Columns.Count);

    StringBuilder commandBuilder = new StringBuilder();
    commandBuilder.Append("UPDATE Table SET ");
    List<string> columnsToUpdate = new List<string>(p_UpdatesTable.Columns.Count);
    foreach (DataColumn column in p_UpdatesTable.Columns)
    {
      //build command to create table type
      StringBuilder columnTypeBuilder = new StringBuilder();
      columnTypeBuilder.Append("[");
      columnTypeBuilder.Append(column.ColumnName);
      columnTypeBuilder.Append("] ");
      if(column.DataType == typeof(int))
      {
        columnTypeBuilder.Append("INT");
      }
      else if(column.DataType == typeof(long))
      {
        columnTypeBuilder.Append("BIGINT");
      }
      else if(column.DataType == typeof(bool))
      {
        columnTypeBuilder.Append("BIT");
      }
      else if(column.DataType == typeof(string))
      {
        columnTypeBuilder.Append("VARCHAR(");
        columnTypeBuilder.Append(column.MaxLength);
        columnTypeBuilder.Append(")");
      }
      else if(column.DataType == typeof(byte[]))
      {
        columnTypeBuilder.Append("IMAGE");
      }
      tableTypeColumns.Add(columnTypeBuilder.ToString());

      //build actual update statement
      if (!column.ColumnName.Equals("UID", StringComparison.InvariantCultureIgnoreCase) && !column.ColumnName.EndsWith("_null"))
      {
        StringBuilder columnBuilder = new StringBuilder();
        columnBuilder.Append(column.ColumnName);
        columnBuilder.Append(" = (CASE WHEN U.");
        columnBuilder.Append(column.ColumnName);
        columnBuilder.Append(" IS NULL THEN (CASE WHEN ISNULL(U.");
        columnBuilder.Append(column.ColumnName);
        columnBuilder.Append("_null, 0) = 1 THEN U.");
        columnBuilder.Append(column.ColumnName);
        columnBuilder.Append(" ELSE C.");
        columnBuilder.Append(column.ColumnName);
        columnBuilder.Append(" END) ELSE U.");
        columnBuilder.Append(column.ColumnName);
        columnBuilder.Append(" END)");
        columnsToUpdate.Add(columnBuilder.ToString());
      }
    }
    tableTypeBuilder.Append(string.Join(",", tableTypeColumns.ToArray()));
    tableTypeBuilder.Append(")");

    commandBuilder.Append(string.Join(",", columnsToUpdate.ToArray()));
    commandBuilder.Append(" FROM Table AS C JOIN @UpdateTable AS U ON C.UID = U.UID");

    //Establish SQL Connection
    using (SqlConnection sqlConnection = new SqlConnection(context.strContext[(int)eCCE_Context._CONNECTION_STRING]))
    {
      sqlConnection.Open();
      try
      {
        using (SqlCommand createTableTypeCommand = new SqlCommand(tableTypeBuilder.ToString(), sqlConnection))
        {
          createTableTypeCommand.ExecuteNonQuery();
        }

        using (SqlCommand sqlCommand = new SqlCommand(commandBuilder.ToString(), sqlConnection))
        {
          SqlParameter updateTableParameter = sqlCommand.Parameters.Add("@UpdateTable", SqlDbType.Structured);
          updateTableParameter.Value = p_UpdatesTable;
          updateTableParameter.TypeName = tableTypeName;
          int rowsAffected = sqlCommand.ExecuteNonQuery();
          if (rowsAffected != p_UpdatesTable.Rows.Count)
          {
            throw new Exception("Update command affected " + rowsAffected + " rows out of the " + p_UpdatesTable.Rows.Count + " expected.");
          }
        }
      }
      finally
      {
        string dropStatement = "IF  EXISTS (SELECT * FROM sys.types st JOIN sys.schemas ss ON st.schema_id = ss.schema_id WHERE st.name = N'"+ tableTypeName.Substring(tableTypeName.IndexOf(".")+1) +"' AND ss.name = N'dbo') DROP TYPE " + tableTypeName;
        using (SqlCommand dropTableTypeCommand = new SqlCommand(dropStatement, sqlConnection))
        {
          dropTableTypeCommand.ExecuteNonQuery();
        }
      }
      sqlConnection.Dispose();
    }
string[]validColumns=SQL_Columns.Split(',');
var Trim=validColumns.Select(c=>c.Trim());
foreach(p_UpdatesTable.Columns中的DataColumn列)
{
如果(!column.ColumnName.EndsWith(_null)&&!trimmed.Contains(column.ColumnName))
{
抛出新异常(“Column'+Column.ColumnName+”'对表无效”);
}
}
字符串tableTypeName=“dbo.UpdateSpecific”+Guid.NewGuid().ToString().Replace(“-”,”).Replace(“{”,”).Replace(“},”);
StringBuilder tableTypeBuilder=新StringBuilder();
tableTypeBuilder.Append(“创建类型”);
tableTypeBuilder.Append(tableTypeName);
tableTypeBuilder.Append(“作为表(”);
List tableTypeColumns=新列表(p_UpdatesTable.Columns.Count);
StringBuilder commandBuilder=新建StringBuilder();
Append(“更新表集”);
List columnsToUpdate=新列表(p_UpdatesTable.Columns.Count);
foreach(p_UpdatesTable.Columns中的DataColumn列)
{
//创建表类型的build命令
StringBuilder columnTypeBuilder=新StringBuilder();
columnTypeBuilder.Append(“[”);
columnTypeBuilder.Append(column.ColumnName);
columnTypeBuilder.Append(“]”);
if(column.DataType==typeof(int))
{
columnTypeBuilder.Append(“INT”);
}
else if(column.DataType==typeof(long))
{
columnTypeBuilder.Append(“BIGINT”);
}
else if(column.DataType==typeof(bool))
{
columnTypeBuilder.Append(“位”);
}
else if(column.DataType==typeof(string))
{
追加(“VARCHAR(”);
columnTypeBuilder.Append(column.MaxLength);
柱型