private IDbCommand BuildUpdateCommand(DataTableMapping mappings, DataRow dataRow)
{
if (ADP.IsEmpty(this.quotedBaseTableName))
{
return(null);
}
IDbCommand cmd = BuildNewCommand(this.updateCommand);
// count the columns for the @p, key count, ?
int pcount = 1; // @p1, @p2, ...
int columnCount = 0;
int valueCount = 0;
int setCount = 0;
StringBuilder builder = new StringBuilder();
builder.Append("UPDATE ");
builder.Append(QuotedBaseTableName);
builder.Append(" SET ");
// search for the columns in that base table, to build the set clause
int length = this.dbSchemaRows.Length;
for (int i = 0; i < length; ++i)
{
DBSchemaRow row = this.dbSchemaRows[i];
if ((null == row) || (0 == row.BaseColumnName.Length) || ExcludeFromUpdateSet(row))
{
continue;
}
columnCount++;
object value = null;
string sourceColumn = this.sourceColumnNames[i]; // MDAC 60079
if ((null != mappings) && (null != dataRow))
{
value = GetParameterUpdateValue(sourceColumn, mappings, dataRow, row.IsReadOnly); // MDAC 61424
if (null == value) // unspecified values are skipped
{
if (row.IsReadOnly) // MDAC 68339
{
columnCount--;
}
continue;
}
}
if (0 < valueCount)
{
builder.Append(" , ");
}
builder.Append(QuotedColumn(row.BaseColumnName));
AppendParameterText(builder, pcount);
IDataParameter p = GetNextParameter(cmd, valueCount);
p.ParameterName = "@p" + pcount.ToString();
p.Direction = ParameterDirection.Input;
p.SourceColumn = sourceColumn;
p.SourceVersion = DataRowVersion.Current;
p.Value = value;
if (p is OleDbParameter)
{
ApplyParameterInfo((OleDbParameter)p, pcount, row);
}
else if (p is SqlParameter)
{
ApplyParameterInfo((SqlParameter)p, pcount, row);
}
else if (p is OdbcParameter)
{
ApplyParameterInfo((OdbcParameter)p, pcount, row);
}
if (!cmd.Parameters.Contains(p))
{
cmd.Parameters.Add(p);
}
pcount++;
valueCount++;
}
setCount = valueCount;
builder.Append(" WHERE ( ");
// search the columns again to build the where clause with optimistic concurrency
string andclause = "";
int whereCount = 0;
string nullWhereParameter = null, nullWhereSourceColumn = null;
for (int i = 0; i < length; ++i)
{
DBSchemaRow row = this.dbSchemaRows[i];
if ((null == row) || (0 == row.BaseColumnName.Length) || !IncludeForUpdateWhereClause(row))
{
continue;
}
builder.Append(andclause);
andclause = CommandBuilder.AndClause;
object value = null;
string sourceColumn = this.sourceColumnNames[i]; // MDAC 60079
if ((null != mappings) && (null != dataRow))
{
value = GetParameterValue(sourceColumn, mappings, dataRow, DataRowVersion.Original);
}
bool pkey = IsPKey(row);
string backendColumnName = QuotedColumn(row.BaseColumnName);
if (pkey)
{
if (Convert.IsDBNull(value))
{
builder.Append(String.Format(WhereClausepn, backendColumnName));
}
else if (this.namedParameters)
{
builder.Append(String.Format(WhereClause1p, backendColumnName, pcount));
}
else
{
builder.Append(String.Format(WhereClause2p, backendColumnName));
}
}
else if (this.namedParameters)
{
builder.Append(String.Format(WhereClause1, backendColumnName, pcount, 1 + pcount));
}
else
{
builder.Append(String.Format(WhereClause2, backendColumnName));
}
if (!pkey || !Convert.IsDBNull(value))
{
IDataParameter p = GetNextParameter(cmd, valueCount); // first parameter value
p.ParameterName = "@p" + pcount.ToString();
p.Direction = ParameterDirection.Input;
if (pkey)
{
p.SourceColumn = sourceColumn;
p.SourceVersion = DataRowVersion.Original;
p.Value = value;
}
else
{
p.SourceColumn = null;
p.Value = (ADP.IsNull(value)) ? 1 : 0;
}
pcount++;
valueCount++;
if (p is OleDbParameter)
{
ApplyParameterInfo((OleDbParameter)p, pcount, row);
}
else if (p is SqlParameter)
{
ApplyParameterInfo((SqlParameter)p, pcount, row);
}
else if (p is OdbcParameter)
{
ApplyParameterInfo((OdbcParameter)p, pcount, row);
}
if (!pkey)
{
p.DbType = DbType.Int32;
}
if (!cmd.Parameters.Contains(p))
{
cmd.Parameters.Add(p);
}
}
if (!pkey)
{
IDataParameter p = GetNextParameter(cmd, valueCount);
p.ParameterName = "@p" + pcount.ToString();
p.Direction = ParameterDirection.Input;
p.SourceColumn = sourceColumn;
p.SourceVersion = DataRowVersion.Original;
p.Value = value;
pcount++;
valueCount++;
if (p is OleDbParameter)
{
ApplyParameterInfo((OleDbParameter)p, pcount, row);
}
else if (p is SqlParameter)
{
ApplyParameterInfo((SqlParameter)p, pcount, row);
}
else if (p is OdbcParameter)
{
ApplyParameterInfo((OdbcParameter)p, pcount, row);
}
if (!cmd.Parameters.Contains(p))
{
cmd.Parameters.Add(p);
}
}
if (IncrementUpdateWhereCount(row))
{
whereCount++;
}
}
builder.Append(" )");
cmd.CommandText = builder.ToString();
RemoveExtraParameters(cmd, valueCount);
#if DEBUG
if (AdapterSwitches.OleDbSql.TraceInfo)
{
ADP.DebugWriteLine(cmd.CommandText);
}
#endif
this.updateCommand = cmd;
if (0 == columnCount)
{
throw ADP.DynamicSQLReadOnly(ADP.UpdateCommand);
}
if (0 == setCount) // MDAC 60667
{
cmd = null;
}
if (0 == whereCount)
{
throw ADP.DynamicSQLNoKeyInfo(ADP.UpdateCommand);
}
if (null != nullWhereParameter)
{
DataColumn column = GetParameterDataColumn(nullWhereSourceColumn, mappings, dataRow);
throw ADP.WhereClauseUnspecifiedValue(nullWhereParameter, nullWhereSourceColumn, column.ColumnName);
}
return(cmd);
}