在 SqlDataAdapter.Update() 中获取错误消息
Posted
技术标签:
【中文标题】在 SqlDataAdapter.Update() 中获取错误消息【英文标题】:Getting error message in SqlDataAdapter.Update() 【发布时间】:2016-07-14 19:43:38 【问题描述】:我有一个数据库表(在本例中为空)
create table words
(
id int not null,
word nvarchar(50) not null
)
还有一个DataGridView
,我是这样填写的:
private SqlConnection _conn;
private SqlDataAdapter _wordsAdapter;
private DataTable _wordsDataTable = new DataTable();
private DataGridView _tblWords;
private void FillWords()
_wordsAdapter = new SqlDataAdapter(new SqlCommand("select id, word from words", _conn));
_wordsAdapter.Fill(_wordsDataTable);
DataGridViewColumn column = new DataGridViewTextBoxColumn();
column.DataPropertyName = "id";
column.Name = "id";
_tblWords.Columns.Add(column);
column = new DataGridViewTextBoxColumn();
column.DataPropertyName = "word";
column.Name = "word";
_tblWords.Columns.Add(column);
_tblWords.DataSource = _wordsDataTable;
private void Update()
_wordsAdapter.InsertCommand = new SqlCommand("insert into words (id, word) values (@id, @word)", _conn);
SqlParameter p = _wordsAdapter.InsertCommand.Parameters.Add("@id", SqlDbType.Int);
p.SourceColumn = "id";
p.SourceVersion = DataRowVersion.Original;
p = _wordsAdapter.InsertCommand.Parameters.Add("@word", SqlDbType.NVarChar);
p.SourceColumn = "word";
p.SourceVersion = DataRowVersion.Original;
_wordsAdapter.Update(_wordsDataTable);
然后我用一些值填充单行 _tblWords 并调用 Update()
。并收到此消息:
抛出异常:“System.Data.SqlClient.SqlException”在 System.Data.dll 附加信息:无法将值 NULL 插入列 'id'、表 'DB.MDF.dbo.words';列不允许空值。插入 失败。
为什么 'id' 的值不是从 DataTable 中获取的?我做错了什么?
更新: 在 Update() 函数的开头插入此代码后,一切正常:
private void Update()
_wordsDataTable.Rows.Clear();
_wordsDataTable.Rows.Add(0, "xxx");
...
所以只有当我通过 DataGridView 填充 DataTable 时才会出现问题。为什么?!
【问题讨论】:
您正在从 datagridview 获取数据并将其插入到表中。 ID 列应该是主键或标识列,因此它不允许您插入重复值。如果要更新表中的单词列,则使用 UPDATE 语句。 表是空的,所以在这种特殊情况下该行是插入的。没有重复,因为插入的行是表中的第一行。但我仍然得到错误。 我正在尝试运行您的代码。_cb
是什么?
对不起,在这个例子中实际上_cb 不是必需的。将其更改为 'new SqlCommand()'
您是否在调试器中查看过此内容并检查数据表中是否有值?
【参考方案1】:
我猜测问题与 DataGridView 中的最后一个空行有关。
您可以尝试这样的操作,而不是最后一行 _wordsAdapter.Update(_wordsDataTable);
var haveDbNull = _wordsDataTable.Rows.Cast<DataRow>().ToLookup(r => r.ItemArray.Contains(DBNull.Value));
Debug.Print("have DbNull values: " + haveDbNull[true].Count()); // check this number in the Debug Output window
Debug.Print("don't have DbNull values: " + haveDbNull[false].Count());
_wordsAdapter.Update(haveDbNull[false].ToArray()); // to update just the rows that dont have DBNull values
【讨论】:
插入的行没有空值。那就是问题所在。当我通过 DataGridView 按值插入它时,出现错误。当我以编程方式将其插入 DataTable 时,一切正常。 我不知道你为什么使用p.SourceVersion = DataRowVersion.Original;
。您应该删除它们或将它们更改为 p.SourceVersion = DataRowVersion.Current;
msdn.microsoft.com/en-us/library/system.data.datarowversion
我也尝试了 Current,结果相同。如果我完全删除它,还会出现另一个错误,说没有提供参数值。问题是它从 DataTable 中获取 null 值而不是当前值。
那我放弃了.. 你可以试试csharp.net-informations.com/dataadapter/… 的示例,然后从那里开始【参考方案2】:
我找到了一些解决方案。我只是删除添加的行并以编程方式添加相同的值。
object[] rowValues = dt.Rows[row].ItemArray;
dt.Rows.RemoveAt(row);
dt.Rows.Add(rowValues);
有谁知道不那么丑陋的方法吗?
【讨论】:
【参考方案3】:解决方法一如既往的简单……
_dtWords.EndInit();
【讨论】:
以上是关于在 SqlDataAdapter.Update() 中获取错误消息的主要内容,如果未能解决你的问题,请参考以下文章
在 SqlDataAdapter.Update() 中获取错误消息
当 RowState = Modified 时 SQLDataAdapter.Update() 不更新
SqlDataAdapter.Update(数据表)不工作(不更新数据库)