SQL Server数据全同步及价值分析[终结版]
SQL Server数据全同步[终结版]
版权全部。转载请注明出处。谢谢!
经过两天的同步编写和測试。出了第一个Release版本号:
1. 本函数仅支持单向同步。即从一个主数据库想多个从数据库同步
2.主数据库的不论什么增删改都会同步到全部从数据库上
3. 最重要的一点:同步数据库的价值所在:当主数据库server不可用时,程序能够使用其它从数据库或者备用数据库,这对于未来公有云和私有云应用具有重大价值!
代码:
<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同步工具的性能和缺陷
SQL Server数据全同步及价值分析[终结版]的更多相关文章
- SQL Server 复制 - 发布订阅(SQL Server 数据同步)
原文:SQL Server 复制 - 发布订阅(SQL Server 数据同步) SQL Server的同步是通过SQL Server自带的复制工具来实现的,分发布和订阅2大步. A,复制-发布 发布 ...
- Docker-compose搭建ELK环境并同步MS SQL Server数据
前言 本文作为学习记录,供大家参考:一次使用阿里云(Aliyun)1核2G centos7.5 云主机搭建Docker下的ELK环境,并导入MS SQL Server的商品数据以供Kibana展示的配 ...
- Oracle DBLink跨数据库访问SQL server数据同步 踩坑实录
项目需求:这里暂且叫A公司吧,A公司有一套人事管理软件,需要与我们公司的软件做人员信息同步,A公司用的是SQL server数据库,我们公司用的Oracle,接口都不会开发(一万句"fuck ...
- SQL Server 2008 数据库同步的两种方式 (发布、订阅)
参考转载: SQL Server 2008 数据库同步的两种方式 (发布.订阅) 使用Sqlserver事务发布实现数据同步
- Sql Server函数全解<五>之系统函数
原文:Sql Server函数全解<五>之系统函数 系统信息包括当前使用的数据库名称,主机名,系统错误消息以及用户名称等内容.使用SQL SERVER中的系统函数可以在需要的时候获取这些 ...
- 浅谈SQL Server数据内部表现形式
在上篇文章 浅谈SQL Server内部运行机制 中,与大家分享了SQL Server内部运行机制,通过上次的分享,相信大家已经能解决如下几个问题: 1.SQL Server 体系结构由哪几部分组成? ...
- SQL server数据缓存依赖
SQL server数据缓存依赖有两种实现模式,轮询模式,通知模式. 1 轮询模式实现步骤 此模式需要SQL SERVER 7.0/2000/2005版本以上版本都支持 主要包含以下几 ...
- [SQL]SQL Server数据表的基础知识与增查删改
SQL Server数据表的基础知识与增查删改 由张晨辉(学生) 于19天 前发表 | 阅读94次 一.常用数据类型 .整型:bigint.int.smallint.tinyint .小数:decim ...
- Sql Server数据的加密与解密
Sql Server数据的加密与解密 在sql server中,我们如何为数据进行加密与解密,避免使用者窃取机密数据? 对于一些敏感数据,如密码.卡号,一般不能使用正常数值来存储.否则会有安全隐患.以 ...
随机推荐
- js 监听ios手机键盘弹起和收起的事件
document.body.addEventListener('focusin', () => { //软键盘弹起事件 console.log("键盘弹起") }) docu ...
- How Javascript works (Javascript工作原理) (二) 引擎,运行时,如何在 V8 引擎中书写最优代码的 5 条小技巧
个人总结: 一个Javascript引擎由一个标准解释程序,或者即时编译器来实现. 解释器(Interpreter): 解释一行,执行一行. 编译器(Compiler): 全部编译成机器码,统一执行. ...
- LightOJ-1236 Pairs Forming LCM 唯一分解定理
题目链接:https://cn.vjudge.net/problem/LightOJ-1236 题意 给一整数n,求有多少对a和b(a<=b),使lcm(a, b)=n 注意数据范围n<= ...
- layui框架下的摸索与学习
一.table表格内的查询 1.单个条件查询: 主要代码: <%-- Created by IntelliJ IDEA. User: Administrator Date: 2019/1/14 ...
- (51) magento集成增加到款通知
这篇主要讲述如何二开增加自己的功能,我没有继承方式二开,习惯是不好的,直接改了原来的模块. 达到效果就这样,当在网站支付成功,会同步到ERP系统中.下面来讲述实现过程 建立文件 payment_not ...
- Python学习————集合的增删查
可变的数据类型,他里面的元素必须是不可变的数据类型.无序,内容不能重复.应用于去重 增加:set1.add('元素')--->将元素无序的插入集合set1中set1.update("元 ...
- IdentityServer4-前后端分离之Vue
原文:IdentityServer4-前后端分离之Vue 前言 之前文章讲到如何使用Node.js+Express构建JavaScript客户端,实现前后端分离.本节将介绍如何使用Vue实现前后端分离 ...
- mysql给某字段随机赋特定范围的整数值
[引] mysql中随机生成一些范围内的整数有时候是很有用的,用到了2个函数 1.floor(f) 返回一个不大于f的最大整数 2.rand(),rand(n) 返回一个随机浮点值 v ,范围在 0 ...
- IIS Express加入MIME映射
近期在用Grid Report做Web报表的时候,碰到一件非常挠头的事. 本地用VS2010写的代码,调试的时候Web报表无法显示,用24.248server上VS2013相同仍是无法显示.最后把项目 ...
- 建筑建模学习笔记2——3DMax房屋框架建模
以下这幅图是用3DMax做出的大体的框架 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I ...