$ 0 0 这几天因为工作需要对数据库的数据进行同步,顺便研究了一下从2个不同的数据库中同步表结构相同表的数据 网上的一些资料好像都做得很复杂 自己整理写了一个简单的(不考虑性能)同步工具,分享一下表同步过程中遇到的问题,具体请看下面代码吧 检索关键词: sqldataadapter 做表同步 同步2张表的数据 把一张表的数据镜像克隆到另一张表 同步2张表的数据但不进行删除数据 /// /// 同步表 /// /// 表名 /// 源数据库连接字符串 /// 目标据库连接字符串 /// 是否处理新增 /// 是否处理更新 /// 是否处理删除 void SynchronousTable(string tableName, string sourceConnString, string targetConnString,bool add,bool update,bool delete) { string sql = string.Format("select * from {0}", tableName); using (SqlDataAdapter sda_source = new SqlDataAdapter(sql, sourceConnString)) { using (SqlDataAdapter sda_target = new SqlDataAdapter(sql, targetConnString)) { //获取自动生成的脚本 SqlCommandBuilder build = new SqlCommandBuilder(sda_target); build.ConflictOption = ConflictOption.OverwriteChanges;//根据主键进行更新 build.SetAllValues = true;//保证更新时,更新语句是设置所有的值,而不是只有修改的列,平常用时,建议为false,性能高,做同步时,建议用true。 build.QuotePrefix = "[";//保留在查询语句中出现的[ build.QuoteSuffix = "]";//保留在查询语句中出现的] sda_target.DeleteCommand = build.GetDeleteCommand(); sda_target.InsertCommand = build.GetInsertCommand(); sda_target.UpdateCommand = build.GetUpdateCommand(); DataTable dt_target = new DataTable(); sda_target.ContinueUpdateOnError = true;//设置执行出错仍然继续 int sum = 0;//总更新数量 sda_source.AcceptChangesDuringFill = false;//保证填充数据后,所有的状态都为add sda_source.Fill(dt_target);//把源表数据填充到待处理的目标表中 if (add)//追加数据 { int num = sda_target.Update(dt_target);//必须设置 sda_target.ContinueUpdateOnError = true;//设置执行出错仍然继续 WriteMessageLine("共执行{0}条插入语句", num); sum += num; } if (update)//更新目标表中和源表中同时存在的数据 { for (int i = dt_target.Rows.Count-1; i >=0; i--) { if (dt_target.Rows[i].RowState != DataRowState.Added) { dt_target.Rows.RemoveAt(i);//移除所有已经添加的数据 } } dt_target.AcceptChanges();//因datatable设置只有unchanged的行才能手工修改状态,这边进行同意所有修改 for (int i = 0; i < dt_target.Rows.Count; i++) { dt_target.Rows[i].SetModified();//设置添加失败的所有行为修改状态 } int num = sda_target.Update(dt_target);//表中可能存在不是修改的数据,这部分数据有新增(当追加数据没有勾时),所以必须设置sda_target.ContinueUpdateOnError = true; WriteMessageLine("共执行{0}条更新语句", num); sum += num; } dt_target.Rows.Clear();//释放内存,如果表太大,这里不释放,后面就更艰难了 WriteMessageLine("共更新{1}条记录到表{0}", tableName, sum); if (delete)//删除目标表中,源表不存在的数据 { dt_target = new DataTable(); sda_target.MissingSchemaAction = MissingSchemaAction.AddWithKey;//加载结构 sda_target.Fill(dt_target); DataTable dt_source = new DataTable(); sda_source.MissingSchemaAction = MissingSchemaAction.AddWithKey;//加载结构 sda_source.Fill(dt_source); for (int i = 0; i < dt_source.Rows.Count; i++) { System.Collections.ArrayList al = new System.Collections.ArrayList(); for (int j = 0; j < dt_source.PrimaryKey.Length; j++) { al.Add(dt_source.Rows[i][dt_source.PrimaryKey[j]]); } DataRow dr= dt_target.Rows.Find(al.ToArray()); if(dr!=null){ dt_target.Rows.Remove(dr); } } for (int i = 0; i < dt_target.Rows.Count; i++) { dt_target.Rows[i].SetModified(); } int num = sda_target.Update(dt_target); WriteMessageLine("共执行{0}条删除语句", num); } } } } void WriteMessageLine(string format, params object[] args) { string msg = DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss]") + string.Format(format, args); if(textBox7.TextLength>30000) textBox7.Clear(); textBox7.AppendText(msg + "\r\n"); LogHelper.WriteInfomationMessage(msg); Application.DoEvents(); } 作者:DeleteElf 发表于2013-3-29 12:03:01 原文链接 阅读:28 评论:0 查看评论