导航

SqlDataAdapter.RowUpdated事件用法

Posted on 2010-08-09 14:11  lilin  阅读(1560)  评论(2编辑  收藏  举报

  利用SqlDataAdapter.Update(DataTable) 批量操作数据时(如Insert操作),当没有事物处理时,如果入库出现致命错误(如主键冲突),SQL语句就会停止。如何才能实现SQL语句不停止,继续执行剩下的DataTable入库,这时可利用SqlDataAdapter.RowUpdated事件来实现。
事件是这样定义的:public event SqlRowUpdatedEventHandler RowUpdated

 

实现原理就是定阅这个事件,当更新某行出错时,清除本行,在回调Insert方法。
代码如下:

 

void Insert(DataTable dt)
{
if(dt.Rows.Count > 0)
{
SqlConnection conn = new SqlConnection(connString);
SqlCommand com = new SqlCommand();
com.CommandText = "Insert Into table (id,CallID) Values (@id,@CallID)";
com.Connection = conn;

com.Parameters.Add("@id", SqlDbType.Int, 8, "id");
com.Parameters.Add("@CallID", SqlDbType.Int, 8, "CallID");

SqlDataAdapter adapter = new SqlDataAdapter();
adapter.InsertCommand = com;
adapter.RowUpdated += new SqlRowUpdatedEventHandler(adapter_RowUpdated);
           //吃掉异常
            try
            {
                adapter.Update(dt);
            }
            catch (Exception ex)
            {
            }
}
void adapter_RowUpdated(object sender, SqlRowUpdatedEventArgs e)
{
//出现异常时
if (e.RecordsAffected == 0)
{
System.Data.SqlClient.SqlException sqle = e.Errors as System.Data.SqlClient.SqlException;
int n = sqle.Number;
if (n == 2627)
{
//移出出错行,
dt.Rows.Remove(e.Row);
Insert(dt);
}
}
}

上面代码中e.RecordsAffected 为已插入的行数;如果语句失败,则为 0。
sqle.Number为SQL错误类型。
2627就是主键冲突错误,这个错误类型是.Net类库通过SQL系统表master得到的,
select * from master.dbo.sysmessages

 


这样当入库时出现致命错误,SQL还可以继续往下执行,完成剩下的DataTable入库。