SQL Server数据全同步及价值分析[终结版]

SQL Server数据全同步[终结版]

版权所有,转载请注明出处,谢谢!

经过两天的同步编写和测试,出了第一个Release版本:

1. 本函数仅支持单向同步,即从一个主数据库想多个从数据库同步

2.主数据库的任何增删改都会同步到所有从数据库上

3. 最重要的一点:同步数据库的价值所在:当主数据库服务器不可用时,程序可以使用其他从数据库或者备用数据库,这对于未来公有云和私有云应用具有重大价值!

代码:

<span style="font-size:18px;">/// <summary>
        /// Note: for columns, the first string must be primary key name!
        /// </summary>
        /// <param name="server"></param>
        /// <param name="database"></param>
        /// <param name="uid"></param>
        /// <param name="password"></param>
        /// <param name="tableName"></param>
        /// <param name="columns"></param>
        /// <param name="ignoreUpdateColumns"></param>
        /// <param name="ignoreInsertColumns"></param>
        public void BulkUpdateTo(string server, string database, string uid, string password, string tableName, List<string> columns, List<string> ignoreUpdateColumns, List<string> ignoreInsertColumns)
        {
            string primaryKeyName = columns[0];
            string connectionString = "Server=" + server + ";Database=" + database + ";User Id=" + uid + ";Password=" + password;
            // Create destination connection
            SqlConnection destinationConnector = new SqlConnection(connectionString);

            SqlCommand cmd = new SqlCommand("SELECT * FROM " + tableName, destinationConnector);
            // Open source and destination connections.
            this.EnsureConnectionIsOpen();
            destinationConnector.Open();

            Dictionary<int, string> Index_PrimaryKeyValue = new Dictionary<int, string>();

            SqlDataReader readerSource = cmd.ExecuteReader();
            Dictionary<string, Dictionary<string, string>> recordsDest = new Dictionary<string, Dictionary<string, string>>();
            int i = 0;
            while (readerSource.Read())
            {
                Index_PrimaryKeyValue.Add(i, readerSource[primaryKeyName].ToString());
                string recordIndex = Index_PrimaryKeyValue[i];
                recordsDest[recordIndex] = new Dictionary<string, string>();
                foreach (string keyName in columns)
                {
                    recordsDest[recordIndex].Add(keyName, readerSource[keyName].ToString());
                }
                i++;
            }

            // Select data from Products table
            cmd = new SqlCommand("SELECT * FROM " + tableName, mySqlConn);
            // Execute reader
            SqlDataReader reader = cmd.ExecuteReader();
            Dictionary<string, Dictionary<string, string>> recordsSource = new Dictionary<string, Dictionary<string, string>>();

            Dictionary<int, string> Index_PrimaryKeyValue2 = new Dictionary<int, string>();

            int j = 0;
            while (reader.Read())
            {
                Index_PrimaryKeyValue2.Add(j, reader[primaryKeyName].ToString());
                string recordIndex = Index_PrimaryKeyValue2[j];
                recordsSource[recordIndex] = new Dictionary<string, string>();
                foreach (string keyName in columns)
                {
                    recordsSource[recordIndex].Add(keyName, reader[keyName].ToString());
                }
                j++;
            }
            reader.Close();
            readerSource.Close();

            foreach (var record in recordsSource)
            {
                string setScripts = string.Empty;
                string insertKeysScripts = string.Empty;
                string insertValuesScripts = string.Empty;
                int setScriptsIndex = 0;
                int insertScriptsIndex = 0;
                string primaryKeyValue = record.Key;
                if (recordsDest.ContainsKey(primaryKeyValue))
                {
                    foreach (string keyName in columns)
                    {
                        if (!ignoreUpdateColumns.Contains(keyName))
                        {
                            if (recordsDest[primaryKeyValue][keyName] == record.Value[keyName])
                            {
                                //do nothing
                            }
                            else
                            {
                                if (setScriptsIndex == 0)
                                {
                                    setScripts += keyName + "='" + recordsSource[primaryKeyValue][keyName] + "' ";
                                }
                                else
                                {
                                    setScripts += "," + keyName + "='" + recordsSource[primaryKeyValue][keyName] + "' ";
                                }
                                setScriptsIndex++;
                            }
                        }
                    }
                }
                else
                {
                    foreach (string keyName in columns)
                    {
                        if (!ignoreInsertColumns.Contains(keyName))
                        {
                            if (insertScriptsIndex == 0)
                            {
                                insertKeysScripts += keyName;
                                insertValuesScripts += "'" + recordsSource[primaryKeyValue][keyName] + "' ";
                            }
                            else
                            {
                                insertKeysScripts += "," + keyName;
                                insertValuesScripts += ",'" + recordsSource[primaryKeyValue][keyName] + "' ";
                            }
                            insertScriptsIndex++;
                        }
                    }
                }

                //update source to dest
                if (setScriptsIndex > 0)
                {
                    cmd = new SqlCommand("Update " + tableName + " set " + setScripts + " where " + primaryKeyName + "='" + recordsSource[primaryKeyValue][primaryKeyName] + "'", destinationConnector);
                    cmd.ExecuteNonQuery();
                }

                //insert source to dest
                if (insertScriptsIndex > 0)
                {
                    cmd = new SqlCommand("insert into " + tableName + " (" + insertKeysScripts + ") values (" + insertValuesScripts + ")", destinationConnector);
                    cmd.ExecuteNonQuery();
                }
            }

            //after update and insert, the count still not match, means we delete some records in source db, then we also need to delete the records in destination db
            foreach (var re in recordsDest)
            {
                //get the delete record primary key value
                if (!recordsSource.ContainsKey(re.Key))
                {
                    cmd = new SqlCommand("delete from " + tableName + " where " + primaryKeyName + "='" + re.Value[primaryKeyName].ToString() + "'", destinationConnector);
                    cmd.ExecuteNonQuery();
                }
            }

            // Close objects
            destinationConnector.Close();
            mySqlConn.Close();
        }</span>

 

代码的基础类其他部分请看下列文章:

1. C#同步SQL Server数据库中的数据--数据库同步工具[同步已有的有变化的数据]       

2.分析下自己写的SQL Server同步工具的性能和缺陷             

3.C#同步SQL Server数据库中的数据--数据库同步工具[同步新数据]            

4.C#同步SQL Server数据库Schema

 

 

 

 

时间: 2024-09-18 20:01:16

SQL Server数据全同步及价值分析[终结版]的相关文章

Sql Server函数全解&lt;三&gt;数据类型转换函数和文本图像函数

原文:Sql Server函数全解<三>数据类型转换函数和文本图像函数 一:数据类型转换函数 在同时处理不同数据类型的值时,SQL Server一般会自动进行隐士类型转换.对于数据类型相近的值是有效的,比如int和float,但是对于其它数据类型,例如整型和字符类型,隐士转换就无法实现了,此时必须使用显示转换.为了实现这种显示转换,T-SQL提供了两个显示转换函数,分别是CAST和CONVERT函数. CAST(x AS type)和CONVERT(type,x)函数将一个类型的值转换为另一个

SQL Server 跨库同步数据

原文:SQL Server 跨库同步数据 最近有个需求是要跨库进行数据同步,两个数据库分布在两台物理计算机上,自动定期同步可以通过SQL Server代理作业来实现,但是前提是需要编写一个存储过程来实现同步逻辑处理.这里的存储过程用的不是opendatasource,而是用的链接服务器来实现的.存储过程创建在IP1:192.168.0.3服务器上,需要将视图v_custom的客户信息同步到IP2:192.168.0.10服务器上的t_custom表中.逻辑是如果不存在则插入,存在则更新字段.  

SQL Server 复制 - 发布订阅(SQL Server 数据同步)

原文:SQL Server 复制 - 发布订阅(SQL Server 数据同步) SQL Server的同步是通过SQL Server自带的复制工具来实现的,分发布和订阅2大步. A,复制-发布 发布之前,需要设置好几个前置条件,发布属性和快照位置.发布主要是设置发布数据库,如未设置,所有的发布,订阅可正常进行,也可通过快照同步,但是却无法在后面的修改中实时同步. 其次,设置快照位置.快照位置设置是在"分发服务器属性"中的发布服务器设置.如果设置的位置不能被订阅机访问,订阅是最好采用发

SQL Server 跨库同步数据_MsSql

最近有个需求是要跨库进行数据同步,两个数据库分布在两台物理计算机上,自动定期同步可以通过SQL Server代理作业来实现,但是前提是需要编写一个存储过程来实现同步逻辑处理.这里的存储过程用的不是opendatasource,而是用的链接服务器来实现的.存储过程创建在IP1:192.168.0.3服务器上,需要将视图v_custom的客户信息同步到IP2:192.168.0.10服务器上的t_custom表中.逻辑是如果不存在则插入,存在则更新字段. create PROCEDURE [dbo]

删除-sql server的个性化同步需求 ?

问题描述 sql server的个性化同步需求 ? 请教一个问题:大家看看这样的需求怎么实现: A数据库,B数据库:要求A上正常的操作增删改查能同步到B上,但是如果在A上操作年结以后,手工脚本删除数据的时候,这个大批量删除的动作要求不能同步到B上.换句话说就是A上的数据只是B上的子集. 这样的需求能实现吗? 大家给给思路呢,谢谢! 解决方案 我能想到的一种方案是 触发器...正常的操作增删改查 的时候 在A上用触发器 插入到B数据库..一旦执行大批量删除动作的时候 在头部加上关闭触发器..执行完

Sql Server函数全解&lt;五&gt;之系统函数

原文:Sql Server函数全解<五>之系统函数  系统信息包括当前使用的数据库名称,主机名,系统错误消息以及用户名称等内容.使用SQL SERVER中的系统函数可以在需要的时候获取这些信息.下面介绍系统函数的作用和使用方法. 1.返回表中指定字段的长度   COL_LENGTH(table,column)函数返回表中指定字段的长度值.其返回值为int类型,table为要确定其列长度信息的表的名称,是nvarchar类型的表达式.column为要确定其长度的列的名称,是nvarchar类型的

ASP实现备份sql server数据

server|sql|备份|数据 建个bak文件夹啊,放数据! db.asp代码如下: <%dim conndim connstr'on error resume nextset conn=server.CreateObject("adodb.connection")connstr="Provider=SQLOLEDB;data source=192.168.2.1;UID=sa;Pwd=123;DataBase=test"conn.Open connstr

使用SQL Server数据服务开发功能强大且可扩展的应用程序

本文使用了以下技术: SQL Server 本文将介绍以下内容: SSDS 数据模型 管理实体.容器和颁发机构 创建示例 Web 应用程序 类序列化和反序列化 本专栏基于 SQL Server 数据服务的预发布版本撰写而成.文中包含的所有信息均有可能发生变更. 目录 SSDS 数据模型 构建分类广告系统 添加城市 添加类别 更新和删除实体 添加和删除列表架构 分类 Web 应用程序 类反序列化 使用自定义列表架构

SQL Server 2008 数据库同步的问题无法请求订阅只能推送订阅

问题描述 SQL Server 2008 数据库同步的问题无法请求订阅只能推送订阅 订阅服务器是通过vpn连接的网络,发布服务器发布的订阅通过ftp下载的方式,可以推送订阅,但就是无法请求订阅. ip段是不同的