C# 用SqlDataAdapter的Update更新数据库问题
string strCmd = "SELECT Top 0 * FROM tabAreaStationData";// 查询0个数据 只需要表的架构不需要数据 SqlDataAdapter sqlAdapter = new SqlDataAdapter(strCmd, sqlCn); DataTable dt = new DataTable(); //创建一个表对象 sqlAdapter.FillSchema(dt,SchemaType.Mapped);// 填充表的架构 //这部分表dt填充数据 SqlCommandBuilder baseInsertCommand = new SqlCommandBuilder(sqlAdapter); sqlAdapter.Update(dt);把dt表更新到数据库
private void sqlDt_ColumnChanging(object sender, DataColumnChangeEventArgs eCol){ switch (eCol.Column.ColumnName) { case "学号": if (Information.IsNumeric(eCol.ProposedValue.Trim) == false) { //通过SetColumnError设定字段的错误信息 eCol.Row.SetColumnError("学号", "学号必须为数字!"); } else { if (eCol.ProposedValue.Trim.Length != 12) { eCol.Row.SetColumnError("学号", "学号只能是12个数字字符"); } else { //将字段的错误信息重设成空字符串(清除错误信息) eCol.Row.SetColumnError("学号", ""); } } break; case "姓名": if (eCol.ProposedValue.Trim.Length == 0) { eCol.Row.SetColumnError("姓名", "姓名不能为空!"); } else { eCol.Row.SetColumnError("姓名", ""); } break; case "性别": if (eCol.ProposedValue.Trim.Length == 0) { eCol.Row.SetColumnError("性别", "性别不能为空!"); } else { if (eCol.ProposedValue.Trim != "男" & eCol.ProposedValue.Trim != "女") { eCol.Row.SetColumnError("性别", "性别只能为男或女!"); } else { eCol.Row.SetColumnError("性别", ""); } } break; case "班级编号": if (Information.IsNumeric(eCol.ProposedValue.trim) == false) { eCol.Row.SetColumnError("班级编号", "学号必须为数字!"); } else { if (eCol.ProposedValue.Trim.Length != 10) { eCol.Row.SetColumnError("班级编号", "班级编号必须是10个数字!"); } else { string strComm = "Select 班级编号 From 班级 Where 班级编号='" + eCol.ProposedValue.trim + "'"; SqlCommand sqlComm = new SqlCommand(strComm, sqlConn); sqlConn.Close(); sqlConn.Open(); //设定读取数据完毕后,自动关闭数据库连接 SqlDataReader sqlDr = sqlComm.ExecuteReader(CommandBehavior.CloseConnection); //判断输入的班级编号是否存在 if (!sqlDr.HasRows) { eCol.Row.SetColumnError("班级编号", "输入的班级编号不存在!"); } else { eCol.Row.SetColumnError("班级编号", ""); } //要关闭SqlDataReader sqlDr.Close(); } } // 检查是否有任何字段存在错误,如果已经没有任何字段有错误,则调用 ClearErros 方法来清除记录上的所有错误。 DataColumn[] colErrors = null; colErrors = eCol.Row.GetColumnsInError(); if (colErrors.Length == 0) { eCol.Row.ClearErrors(); } break; }}private void btnSave_Click(System.Object sender, System.EventArgs e){ string strErrInfo = ""; if ((SqlDs1.Tables(0).HasErrors)) { MessageBox.Show("输入有误,请修正后提交更新!" + ControlChars.CrLf + strErrInfo, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { if ((SqlDs1.HasChanges())) { sqlDa.Update(SqlDs1, "学生信息"); SqlDs1.AcceptChanges(); MessageBox.Show("记录更新成功!", "操作结果", MessageBoxButtons.OK, MessageBoxIcon.Information); InitControlState(); } }}
[解决办法]
"如果dt表X字段与数据库中表X字段值相同
直接覆盖掉数据库这一行的值
请问如何实现"
这个问题使用SqlDataAdapter的Update 已没法解决了, 不如在数据库表里建个替代触发器(instead of)试试
[解决办法]
循环遍历 dt 的行数据
如果ID(唯一标示)相同就更新
不同的就插入
使用这样方法是有一定的局限性的
当然如果循环遍历dt的话也就失去了 使用dt的意义
期待更好的方法
[解决办法]
SqlCommandBuilder批处理操作
要判断存在不太适合。
if not exists()
insert
[解决办法]
做一个触发器吧。
insert前先select是否存在,存在就将那行数据update。
[解决办法]
private void button2_Click(object sender, EventArgs e)//用于未注册前判断输入的用户名是否合法
{
myConnection = new SqlConnection(myConnectionString);
cmd = new SqlCommand();
cmd.Connection = myConnection;
string sql;
sql = "select user from dr where ID='" + textBox1.Text.Trim() + "'";
cmd.CommandText = sql;
myConnection.Open();
if (cmd.ExecuteScalar() == null)
{
MessageBox.Show("不存在该用户,您可以用这个账号注册!");
}
else
{
MessageBox.Show("该用户已经存在,请重新输入账号注册!");
textBox1.Text = "";
}
}
[解决办法]
数据库中的这个表很大,全部填充到dt显然不合理,内存很可能不够。
也可以在update前取出dt的唯一列的所有值,拼接成sql,select * from 表 where 唯一列 in (值1,值2...),在查询后返回的结果集中存在的就将dt中相应的行状态变为Modified。
[解决办法]
if (cmd.ExecuteScalar() == null)//说明数据库中没有你刚输入的用户这样之后就这可以插入新的用户了。