zoukankan      html  css  js  c++  java
  • 两个数据库通过DataTable实现差异传输

    两个主要方法

    /// <summary>
    /// 用途:
    /// 用源表和目标表比较,返回差异的数据(目标表为参照物)
    /// 
    /// 逻辑:
    /// 1、合并两个表
    /// 2、循环合并后得到的表,判断是否在目标表中存在,如果不存在,则是新增的,RowState为设置为ADD,如果存在,RowState设置为Modify
    /// </summary>
    /// <param name="sourceTable">源表</param>
    /// <param name="targetTable">目标表</param>
    /// <param name="primaryKeyColumn">主键字段</param>
    /// <returns>差异数据的DataTable,该DataTable中必须有TableName属性,而且是跟数据库中的表一致的</returns>
    private DataTable GetDataTableExceptData(DataTable sourceTable,DataTable targetTable,string tableName,string primaryKeyColumn)
    {
    DataTable dtExcept = new DataTable(sourceTable.TableName);

    try
    {
    dtExcept = sourceTable.AsEnumerable().Except(targetTable.AsEnumerable(),DataRowComparer.Default).CopyToDataTable();
    }
    catch (Exception)
    {

    }


    for (int i = 0; i < dtExcept.Rows.Count; i++)
    {
    object obj = dtExcept.Rows[i][primaryKeyColumn];

    targetTable.DefaultView.Sort = primaryKeyColumn;
    int count = targetTable.DefaultView.Find(obj);

    if (count >= 0)
    {
    dtExcept.Rows[i].SetModified();
    }else{
    dtExcept.Rows[i].SetAdded();
    }
    }

    dtExcept.TableName = tableName;
    return dtExcept;

    }

    /// <summary>
    /// 用途:
    /// 根据DataTable 获取SQL脚本
    /// 
    /// 逻辑:
    /// 1、先判断是否是自动曾长的,如果是自动增长,先关闭自动增长
    /// </summary>
    /// <param name="dt">源DataTable与目标DataTable的差异</param>
    /// <param name="primaryKeyColumn">主键字段</param>
    /// <param name="isIdentity">是否自动增长</param>
    /// <returns>SQL脚本</returns>
    private StringBuilder GetScriptByDataTable(DataTable dt, string primaryKeyColumn,bool isIdentity)
    {
    StringBuilder sb = new StringBuilder("");

    // 开启自动增长时能进行插入数据,后面对应有关闭
    if (isIdentity)
    {
    sb.AppendLine();
    sb.Append("-- ===========================" + dt.TableName + "===============================");
    sb.AppendLine();
    sb.Append("SET IDENTITY_INSERT " + dt.TableName + " ON");
    }

    if (dt.TableName == "")
    {
    DialogResult result = MessageBox.Show("DataTable 的 TableName 未指定");
    return null; 
    }

    List<string> list_Column = new List<string>();
    foreach (DataColumn item in dt.Columns)
    {
    list_Column.Add(item.ColumnName);
    }


    for (int i = 0; i < dt.Rows.Count; i++)
    {
    StringBuilder sb_Insert = new StringBuilder("");
    DataRowState rowState = dt.Rows[i].RowState;
    if (rowState == DataRowState.Added)
    {
    StringBuilder sb_Column = new StringBuilder();
    StringBuilder sb_Values = new StringBuilder();

    sb_Insert.AppendLine();
    sb_Insert.Append("INSERT INTO " + dt.TableName + "(");
    for (int m = 0; m < list_Column.Count; m++)
    {
    sb_Column.Append("," + list_Column[m]);
    sb_Values.Append(",'" + dt.Rows[i][list_Column[m]]+"'");
    }
    sb_Insert.Append(sb_Column.ToString());
    sb_Insert.Append(") VALUES(");
    sb_Insert.Append(sb_Values.ToString());
    sb_Insert.Append(");");
    sb_Insert.Replace("INSERT INTO "+ dt.TableName +"(,", "INSERT INTO "+ dt.TableName +"(");
    sb_Insert.Replace("VALUES(,", "VALUES(");

    sb.Append(sb_Insert.ToString());
    }
    if (rowState == DataRowState.Modified)
    {
    StringBuilder sb_Update = new StringBuilder("");
    sb_Update.AppendLine();
    sb_Update.Append("UPDATE " + dt.TableName + " SET ");
    for (int k = 0; k < list_Column.Count; k++)
    {
    if (list_Column[k] != primaryKeyColumn)
    {
    sb_Update.Append("," + list_Column[k] + "='" + dt.Rows[i][list_Column[k]] + "'");
    }
    }
    sb_Update.Replace("SET ,", "SET ");
    sb_Update.Append(" WHERE " + primaryKeyColumn + " = '" + dt.Rows[i][primaryKeyColumn] + "';");

    sb.Append(sb_Update.ToString());
    }
    if (i > 0 && i % 100 == 0)
    {
    sb.AppendLine();
    sb.Append("GO;");
    sb.AppendLine();
    }
    }

    // 关闭自动增长时能进行插入数据,前面对应有开启
    if (isIdentity)
    {
    sb.AppendLine();
    sb.Append("SET IDENTITY_INSERT " + dt.TableName + " OFF");
    }

    return sb;
    }

    =========================================================================

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Configuration;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;

    namespace IT_Tools
    {
    public partial class FormOATransmission : Form
    {
    /// <summary>
    /// 源数据库链接
    /// </summary>
    private static string ConnectionString_Source = ConfigurationManager.AppSettings["DB_Source"].ToString().Trim(); // 开发机
    /// <summary>
    /// 目标数据库链接
    /// </summary>
    private static string ConnectionString_Target = ConfigurationManager.AppSettings["DB_Target"].ToString().Trim(); // 生产机
    /// <summary>
    /// 需要更新的表集合
    /// </summary>
    private static ArrayList tableList = new ArrayList();
    public FormOATransmission()
    {
    InitializeComponent();
    }

    // 两个环境的表对比
    private void btnDbCompare_Click(object sender, EventArgs e)
    {
    string strTableName = ""; // 当前表名称,用于表集合循环
    string strPrimaryKeyColumn = "";// 当前表主键字段,用于表集合循环
    bool isIdentity=false; // 是否自动曾长,用于表集合循环

    DataTable dtSource = null; // 用于存放源表的数据,结构和表名称与目标表一致
    DataTable dtTarget = null; // 用于存放目标表的数据,结构和表名称与源表一致
    DataTable dt = null;

    StringBuilder sb_CurrentTableScript = null;
    StringBuilder sb_AllTableScript = new StringBuilder();

    DataTable dtTableList = GetTableList(); //获取需要更新的表集合

    for (int i = 0; i < dtTableList.Rows.Count; i++)
    {
    strTableName = dtTableList.Rows[i]["TableName"].ToString();
    string sql = "select * from " + strTableName;
    dtSource = SqlHelper.ExecuteDataset(ConnectionString_Source, CommandType.Text, sql).Tables[0];
    dtTarget = SqlHelper.ExecuteDataset(ConnectionString_Target, CommandType.Text, sql).Tables[0];

    strPrimaryKeyColumn = dtTableList.Rows[i]["PrimaryKeyColumn"].ToString();
    isIdentity = bool.Parse(dtTableList.Rows[i]["IsIdentity"].ToString());

    dt = GetDataTableExceptData(dtSource, dtTarget, strTableName, strPrimaryKeyColumn);
    if (dt.Rows.Count > 0)
    {
    sb_CurrentTableScript = GetScriptByDataTable(dt, strPrimaryKeyColumn, isIdentity);

    sb_CurrentTableScript.AppendLine();
    sb_AllTableScript.Append(sb_CurrentTableScript);
    }
    }

    rtbSqlContent.Text = sb_AllTableScript.ToString();


    }

    /// <summary>
    /// 用途:
    /// 用源表和目标表比较,返回差异的数据(目标表为参照物)
    ///
    /// 逻辑:
    /// 1、合并两个表
    /// 2、循环合并后得到的表,判断是否在目标表中存在,如果不存在,则是新增的,RowState为设置为ADD,如果存在,RowState设置为Modify
    /// </summary>
    /// <param name="sourceTable">源表</param>
    /// <param name="targetTable">目标表</param>
    /// <param name="primaryKeyColumn">主键字段</param>
    /// <returns>差异数据的DataTable,该DataTable中必须有TableName属性,而且是跟数据库中的表一致的</returns>
    private DataTable GetDataTableExceptData(DataTable sourceTable,DataTable targetTable,string tableName,string primaryKeyColumn)
    {
    DataTable dtExcept = new DataTable(sourceTable.TableName);

    try
    {
    dtExcept = sourceTable.AsEnumerable().Except(targetTable.AsEnumerable(),DataRowComparer.Default).CopyToDataTable();
    }
    catch (Exception)
    {

    }


    for (int i = 0; i < dtExcept.Rows.Count; i++)
    {
    object obj = dtExcept.Rows[i][primaryKeyColumn];

    targetTable.DefaultView.Sort = primaryKeyColumn;
    int count = targetTable.DefaultView.Find(obj);

    if (count >= 0)
    {
    dtExcept.Rows[i].SetModified();
    }else{
    dtExcept.Rows[i].SetAdded();
    }
    }

    dtExcept.TableName = tableName;
    return dtExcept;

    }

    /// <summary>
    /// 用途:
    /// 根据DataTable 获取SQL脚本
    ///
    /// 逻辑:
    /// 1、先判断是否是自动曾长的,如果是自动增长,先关闭自动增长
    /// </summary>
    /// <param name="dt">源DataTable与目标DataTable的差异</param>
    /// <param name="primaryKeyColumn">主键字段</param>
    /// <param name="isIdentity">是否自动增长</param>
    /// <returns>SQL脚本</returns>
    private StringBuilder GetScriptByDataTable(DataTable dt, string primaryKeyColumn,bool isIdentity)
    {
    StringBuilder sb = new StringBuilder("");

    // 开启自动增长时能进行插入数据,后面对应有关闭
    if (isIdentity)
    {
    sb.AppendLine();
    sb.Append("-- ===========================" + dt.TableName + "===============================");
    sb.AppendLine();
    sb.Append("SET IDENTITY_INSERT " + dt.TableName + " ON");
    }

    if (dt.TableName == "")
    {
    DialogResult result = MessageBox.Show("DataTable 的 TableName 未指定");
    return null;
    }

    List<string> list_Column = new List<string>();
    foreach (DataColumn item in dt.Columns)
    {
    list_Column.Add(item.ColumnName);
    }


    for (int i = 0; i < dt.Rows.Count; i++)
    {
    StringBuilder sb_Insert = new StringBuilder("");
    DataRowState rowState = dt.Rows[i].RowState;
    if (rowState == DataRowState.Added)
    {
    StringBuilder sb_Column = new StringBuilder();
    StringBuilder sb_Values = new StringBuilder();

    sb_Insert.AppendLine();
    sb_Insert.Append("INSERT INTO " + dt.TableName + "(");
    for (int m = 0; m < list_Column.Count; m++)
    {
    sb_Column.Append("," + list_Column[m]);
    sb_Values.Append(",'" + dt.Rows[i][list_Column[m]]+"'");
    }
    sb_Insert.Append(sb_Column.ToString());
    sb_Insert.Append(") VALUES(");
    sb_Insert.Append(sb_Values.ToString());
    sb_Insert.Append(");");
    sb_Insert.Replace("INSERT INTO "+ dt.TableName +"(,", "INSERT INTO "+ dt.TableName +"(");
    sb_Insert.Replace("VALUES(,", "VALUES(");

    sb.Append(sb_Insert.ToString());
    }
    if (rowState == DataRowState.Modified)
    {
    StringBuilder sb_Update = new StringBuilder("");
    sb_Update.AppendLine();
    sb_Update.Append("UPDATE " + dt.TableName + " SET ");
    for (int k = 0; k < list_Column.Count; k++)
    {
    if (list_Column[k] != primaryKeyColumn)
    {
    sb_Update.Append("," + list_Column[k] + "='" + dt.Rows[i][list_Column[k]] + "'");
    }
    }
    sb_Update.Replace("SET ,", "SET ");
    sb_Update.Append(" WHERE " + primaryKeyColumn + " = '" + dt.Rows[i][primaryKeyColumn] + "';");

    sb.Append(sb_Update.ToString());
    }
    if (i > 0 && i % 100 == 0)
    {
    sb.AppendLine();
    sb.Append("GO;");
    sb.AppendLine();
    }
    }

    // 关闭自动增长时能进行插入数据,前面对应有开启
    if (isIdentity)
    {
    sb.AppendLine();
    sb.Append("SET IDENTITY_INSERT " + dt.TableName + " OFF");
    }

    return sb;
    }

    /// <summary>
    /// 需要同步的表
    /// </summary>
    /// <returns></returns>
    private DataTable GetTableList()
    {
    DataTable dt = new DataTable();
    DataRow row = null;

    dt.Columns.AddRange(new DataColumn[]{
    new DataColumn("TableName",typeof(string))
    ,new DataColumn("PrimaryKeyColumn",typeof(string))
    ,new DataColumn("IsIdentity",typeof(bool))
    });

    row = dt.NewRow();
    row["TableName"] = "TB_A";
    row["PrimaryKeyColumn"] = "Id";
    row["IsIdentity"] = true;
    dt.Rows.Add(row);

    row = dt.NewRow();
    row["TableName"] = "TB_B";
    row["PrimaryKeyColumn"] = "Id";
    row["IsIdentity"] = true;
    dt.Rows.Add(row);

    return dt;
    }

    // 表的同步
    private void btnDbTransmisson_Click(object sender, EventArgs e)
    {

    }
    }
    }

  • 相关阅读:
    LightOJ 1132 Summing up Powers(矩阵快速幂)
    hdu 3804 Query on a tree (树链剖分+线段树)
    LightOJ 1052 String Growth && uva 12045 Fun with Strings (矩阵快速幂)
    uva 12304 2D Geometry 110 in 1! (Geometry)
    LA 3263 That Nice Euler Circuit (2D Geometry)
    2013 SCAUCPC Summary
    poj 3321 Apple Tree (Binary Index Tree)
    uva 11796 Dog Distance (几何+模拟)
    uva 11178 Morley's Theorem (2D Geometry)
    动手动脑
  • 原文地址:https://www.cnblogs.com/chengeng/p/7505475.html
Copyright © 2011-2022 走看看