SqlDataAdapter 不更新数据库中的行
SqlDataAdapter not updating rows in Database
我正在使用 SqlDataAdapter 更新我用另一种方法从数据库查询的数据表,在该方法中有列、状态和 Is_processed 已更新。
现在,我希望将这些更改保留(更新)在数据库中。以下是实现的目标:
代码
batchSize = 10;
string cmd;
int updatedRows;
try
{
string connString = db.ConnectionString;
using (SqlConnection conn = new SqlConnection(connString))
using (SqlDataAdapter adapter = new SqlDataAdapter())
{
cmd = "UPDATE IMPORTED_ACCOUNTS SET STATUS = @Status , IS_PROCESSED = @IsProcessed " +
", CREATED_ON = @CreatedOn , CREATED_BY = @CreatedBy , UPDATED_ON = @UpdatedOn , UPDATED_BY = @UpdatedBy " +
"WHERE CONVENTIONAL_ACCOUNT = @ConAcct";
adapter.UpdateCommand = new SqlCommand(cmd, conn);
adapter.UpdateCommand.UpdatedRowSource = UpdateRowSource.OutputParameters;
adapter.UpdateCommand.Parameters.AddWithValue("@Status", "Status");
adapter.UpdateCommand.Parameters.Add("@IsProcessed", SqlDbType.Bit, 1, dTable.Columns["IsProcessed"].ColumnName);
adapter.UpdateCommand.Parameters.Add("@CreatedOn",SqlDbType.DateTime,30, dTable.Columns["CreatedOn"].ColumnName);
adapter.UpdateCommand.Parameters.AddWithValue("@CreatedBy", dTable.Columns["CreatedBy"].ColumnName);
adapter.UpdateCommand.Parameters.Add("@UpdatedOn",SqlDbType.DateTime,30, dTable.Columns["UpdatedOn"].ColumnName);
adapter.UpdateCommand.Parameters.AddWithValue("@UpdatedBy", dTable.Columns["UpdatedBy"].ColumnName);
adapter.UpdateCommand.Parameters.AddWithValue("@ConAcct", dTable.Columns["ConventionalAccount"].ColumnName);
cmd = "INSERT INTO IMPORTED_ACCOUNTS ([STATUS],[IS_PROCESSED],[CREATED_ON],[CREATED_BY],[UPDATED_ON],[UPDATED_BY], CONVENTIONAL_ACCOUNT) " +
"VALUES (@Status , @IsProcessed, @CreatedOn, @CreatedBy, @UpdatedOn, @UpdatedBy, @ConAcct) ";
adapter.InsertCommand = new SqlCommand(cmd, conn);
adapter.InsertCommand.UpdatedRowSource = UpdateRowSource.OutputParameters;
adapter.InsertCommand.Parameters.AddWithValue("@Status", dTable.Columns["Status"].ColumnName);
adapter.InsertCommand.Parameters.Add("@IsProcessed", SqlDbType.Bit, 1, dTable.Columns["IsProcessed"].ColumnName);
adapter.InsertCommand.Parameters.Add("@CreatedOn", SqlDbType.DateTime, 30, dTable.Columns["CreatedOn"].ColumnName);
adapter.InsertCommand.Parameters.AddWithValue("@CreatedBy", dTable.Columns["CreatedBy"].ColumnName);
adapter.InsertCommand.Parameters.Add("@UpdatedOn", SqlDbType.DateTime, 30, dTable.Columns["UpdatedOn"].ColumnName);
adapter.InsertCommand.Parameters.AddWithValue("@UpdatedBy", dTable.Columns["UpdatedBy"].ColumnName);
adapter.InsertCommand.Parameters.Add("@ConAcct", SqlDbType.VarChar, 100, dTable.Columns["ConventionalAccount"].ColumnName);
cmd = "DELETE FROM IMPORTED_ACCOUNTS WHERE CONVENTIONAL_ACCOUNT = @ConAcct";
adapter.DeleteCommand = new SqlCommand(cmd, conn);
adapter.DeleteCommand.UpdatedRowSource = UpdateRowSource.OutputParameters;
adapter.DeleteCommand.Parameters.AddWithValue("@ConAcct", dTable.Columns["ConventionalAccount"].ColumnName);
adapter.UpdateBatchSize = batchSize;
updatedRows = adapter.Update(dTable); // point where code breaks
}
return updatedRows;
}
catch (Exception ex)
{
return 0;
}
错误
它在 catch 块中出现以下错误:
Violation of PRIMARY KEY constraint 'PK_ACCTS'. Cannot insert
duplicate key in object 'dbo.IMPORTED_ACCOUNTS'.
评论
为什么在数据库中已经存在应该更新的行时尝试在数据库中插入行?
adapter.Update(dTable) 方法触发 Update 而不是 Insert 的条件是什么?
想不通...
非常感谢您的帮助!
适配器将根据 table 中每行的 DataRow.RowState
来决定何时插入、更新或删除。
有关可能的状态,请参阅 https://msdn.microsoft.com/es-es/library/system.data.datarowstate(v=vs.110).aspx。
填充数据表后,您可以调用 DataTable.AcceptChanges 方法将所有行标记为未更改。
此外,如果您有自动数字 PK,最佳做法是使用这些属性设置 DataTable 中的字段:
- 自增:真
- 自动增量种子:-1
最后一个确保如果您在数据中插入新值table,新 ID 值将不会与现有 ID 值冲突
在 .NET 中 DataAdapter
根据 DataRow.RowState
属性 进行数据库更改。
如果它具有 Added
值 - 数据适配器将尝试插入记录。
如果您需要更新记录 - 那么这个 属性 应该有 Modified
值。
您不能直接设置值 od RowState
。例如,当您向 dataTable 添加行时,它已自动设置为 Added
。
不过,您仍然可以间接修改该值。为此,您应该为需要更新的数据行调用 DataRow.AcceptChanges
,这会将 RowState
设置为 Unchanged
。然后你应该修改这些数据行中的任何内容,在这种情况下,它们将具有 RowState = Modified
.
我正在使用 SqlDataAdapter 更新我用另一种方法从数据库查询的数据表,在该方法中有列、状态和 Is_processed 已更新。
现在,我希望将这些更改保留(更新)在数据库中。以下是实现的目标:
代码
batchSize = 10;
string cmd;
int updatedRows;
try
{
string connString = db.ConnectionString;
using (SqlConnection conn = new SqlConnection(connString))
using (SqlDataAdapter adapter = new SqlDataAdapter())
{
cmd = "UPDATE IMPORTED_ACCOUNTS SET STATUS = @Status , IS_PROCESSED = @IsProcessed " +
", CREATED_ON = @CreatedOn , CREATED_BY = @CreatedBy , UPDATED_ON = @UpdatedOn , UPDATED_BY = @UpdatedBy " +
"WHERE CONVENTIONAL_ACCOUNT = @ConAcct";
adapter.UpdateCommand = new SqlCommand(cmd, conn);
adapter.UpdateCommand.UpdatedRowSource = UpdateRowSource.OutputParameters;
adapter.UpdateCommand.Parameters.AddWithValue("@Status", "Status");
adapter.UpdateCommand.Parameters.Add("@IsProcessed", SqlDbType.Bit, 1, dTable.Columns["IsProcessed"].ColumnName);
adapter.UpdateCommand.Parameters.Add("@CreatedOn",SqlDbType.DateTime,30, dTable.Columns["CreatedOn"].ColumnName);
adapter.UpdateCommand.Parameters.AddWithValue("@CreatedBy", dTable.Columns["CreatedBy"].ColumnName);
adapter.UpdateCommand.Parameters.Add("@UpdatedOn",SqlDbType.DateTime,30, dTable.Columns["UpdatedOn"].ColumnName);
adapter.UpdateCommand.Parameters.AddWithValue("@UpdatedBy", dTable.Columns["UpdatedBy"].ColumnName);
adapter.UpdateCommand.Parameters.AddWithValue("@ConAcct", dTable.Columns["ConventionalAccount"].ColumnName);
cmd = "INSERT INTO IMPORTED_ACCOUNTS ([STATUS],[IS_PROCESSED],[CREATED_ON],[CREATED_BY],[UPDATED_ON],[UPDATED_BY], CONVENTIONAL_ACCOUNT) " +
"VALUES (@Status , @IsProcessed, @CreatedOn, @CreatedBy, @UpdatedOn, @UpdatedBy, @ConAcct) ";
adapter.InsertCommand = new SqlCommand(cmd, conn);
adapter.InsertCommand.UpdatedRowSource = UpdateRowSource.OutputParameters;
adapter.InsertCommand.Parameters.AddWithValue("@Status", dTable.Columns["Status"].ColumnName);
adapter.InsertCommand.Parameters.Add("@IsProcessed", SqlDbType.Bit, 1, dTable.Columns["IsProcessed"].ColumnName);
adapter.InsertCommand.Parameters.Add("@CreatedOn", SqlDbType.DateTime, 30, dTable.Columns["CreatedOn"].ColumnName);
adapter.InsertCommand.Parameters.AddWithValue("@CreatedBy", dTable.Columns["CreatedBy"].ColumnName);
adapter.InsertCommand.Parameters.Add("@UpdatedOn", SqlDbType.DateTime, 30, dTable.Columns["UpdatedOn"].ColumnName);
adapter.InsertCommand.Parameters.AddWithValue("@UpdatedBy", dTable.Columns["UpdatedBy"].ColumnName);
adapter.InsertCommand.Parameters.Add("@ConAcct", SqlDbType.VarChar, 100, dTable.Columns["ConventionalAccount"].ColumnName);
cmd = "DELETE FROM IMPORTED_ACCOUNTS WHERE CONVENTIONAL_ACCOUNT = @ConAcct";
adapter.DeleteCommand = new SqlCommand(cmd, conn);
adapter.DeleteCommand.UpdatedRowSource = UpdateRowSource.OutputParameters;
adapter.DeleteCommand.Parameters.AddWithValue("@ConAcct", dTable.Columns["ConventionalAccount"].ColumnName);
adapter.UpdateBatchSize = batchSize;
updatedRows = adapter.Update(dTable); // point where code breaks
}
return updatedRows;
}
catch (Exception ex)
{
return 0;
}
错误
它在 catch 块中出现以下错误:
Violation of PRIMARY KEY constraint 'PK_ACCTS'. Cannot insert duplicate key in object 'dbo.IMPORTED_ACCOUNTS'.
评论 为什么在数据库中已经存在应该更新的行时尝试在数据库中插入行? adapter.Update(dTable) 方法触发 Update 而不是 Insert 的条件是什么?
想不通... 非常感谢您的帮助!
适配器将根据 table 中每行的 DataRow.RowState
来决定何时插入、更新或删除。
有关可能的状态,请参阅 https://msdn.microsoft.com/es-es/library/system.data.datarowstate(v=vs.110).aspx。
填充数据表后,您可以调用 DataTable.AcceptChanges 方法将所有行标记为未更改。
此外,如果您有自动数字 PK,最佳做法是使用这些属性设置 DataTable 中的字段:
- 自增:真
- 自动增量种子:-1
最后一个确保如果您在数据中插入新值table,新 ID 值将不会与现有 ID 值冲突
在 .NET 中 DataAdapter
根据 DataRow.RowState
属性 进行数据库更改。
如果它具有 Added
值 - 数据适配器将尝试插入记录。
如果您需要更新记录 - 那么这个 属性 应该有 Modified
值。
您不能直接设置值 od RowState
。例如,当您向 dataTable 添加行时,它已自动设置为 Added
。
不过,您仍然可以间接修改该值。为此,您应该为需要更新的数据行调用 DataRow.AcceptChanges
,这会将 RowState
设置为 Unchanged
。然后你应该修改这些数据行中的任何内容,在这种情况下,它们将具有 RowState = Modified
.