项目要求SQLSERVER数据库增加数据的时候同步数据到mysql数据库。
这里用到了存储过程与触发器的混合使用。
因为要同步到MySQL数据库所以首先下载MySQL的ODBC驱动 ↓
https://dev.mysql.com/downloads/connector/odbc/
最好是下载那个MSI自动安装的,安装后打开电脑自带的ODBC配置 ↓
添加刚才安装的驱动 ,记住这个名字 ↓
然后编写sql ↓
--新建链接服务器
EXEC sp_addlinkedserver
@server='mysqlServer', --ODBC里面data source name 上图记住的名字
@srvproduct='', --自己随便
@provider='MSDASQL', --固定这个
@datasrc=NULL,
@location=NULL,
@provstr='DRIVER={MySQL ODBC 8.0 ANSI Driver};SERVER=172.19.128.38;DATABASE=remotemedical;UID=zhangxuechen;PORT=3306;',
--这里面的参数,分别是驱动名称,比如我的是MySQL ODBC 8.0 一般只改下版本号就可以,后面是数据库地址,数据库名,UID就是唯一标识这个自己起就行,最后的是数据库端口号
@catalog = NULL
---创建连接mysql数据库的账号及密码
exec sp_addlinkedsrvlogin
@rmtsrvname='mysqlServer' ,----ODBC里面data source name 跟上面的一样
@useself='false' ,
@rmtuser='root' ,---mysql账号
@rmtpassword='123456' ;--mysql账号其密码
这两步骤执行后理应就可以调通了,可以执行下面的语句测试是否可以链接查看数据 ↓
select * from openquery(mysqlServer,'SELECT * FROM t_texttable; ')
--openquery是执行链接服务器的语句,里面的参数分别是 刚才ODBC的名字即上面填的那俩名字,要查询的mysql中的表名
如果有问题的话可以检查是否创建链接的过程是否出现了问题可以执行如下两个SQL ↓
Exec sp_helpserver;
select * from sys.servers;
结果如下,如果可以查询到就说明创建成功了。如果有问题比如创建的参数有问题需要修改需要进行删除服务 ↓
删除服务语句 ↓
--分别是删除服务语句和删除服务链接信息
Exec sp_dropserver 'mysqlServer'
Exec sp_droplinkedsrvlogin 'mysqlServer',Null
然后再新建几个服务 ,虽然我也不知道意义是啥↓
-----建立允许远程访问连接操作
USE [ReportServer] --本地数据库名,下面的操作我认为是数据库绑定服务连接吧,server名和连接名改成你自己的别的都一样就行
GO
EXEC ReportServer.dbo.sp_serveroption @server =N'mysqlServer' , @optname= N'rpc out', @optvalue=N'TRUE'
GO
EXEC ReportServer.dbo.sp_serveroption @server =N'mysqlServer' , @optname= N'remote proc transaction promotion', @optvalue =N'false'
GO
--建立LOOPBACK 服务器链接 这里固定写就行
EXEC sp_addlinkedserver @server = N'loopback' , @srvproduct = N' ' , @provider = N'SQLNCLI',
@datasrc = @@SERVERNAME
go
--设置服务器链接选项,阻止SQL Server 由于远过程调用而将本地事务提升为分布事务(重点)
USE [ReportServer] --这里跟上面的那个一样只有server名不同
GO
EXEC ReportServer.dbo.sp_serveroption @server =N'loopback' , @optname= N'rpc out', @optvalue=N'TRUE'
GO
EXEC ReportServer.dbo.sp_serveroption @server =N'loopback' , @optname= N'remote proc transaction promotion', @optvalue =N'false'
GO
如果以上都没有问题且能跨库查询出数据就可以写存储过程与触发器了,如下 ↓
CREATE PROCEDURE mysqlInsert @bitch INT AS --这里的mysqlInsert是自己起的存储过程名称,@bitch是一个变量,为一会触发器传参
BEGIN
SET NOCOUNT ON
INSERT OPENQUERY (mysqlServer,'select * from t_texttable')(bitch)
values(@bitch);
--这里可以理解链接服务器执行插入,虽然里面的参数也是select。
SET NOCOUNT OFF
END
触发器↓
CREATE TRIGGER MSSInsert ON Batch FOR INSERT --这里创建本地mysqlserver的触发器,在新增插入的时候触发
AS
DECLARE @bitch INT --声明变量,这个变量是要传给存储过程的,注意参数类型
SELECT
@bitch = Parent --这里的意思是把INSERTED即刚插入的数据的parent值拿出来赋值给@bitch
FROM
INSERTED;
BEGIN
EXEC loopback.ReportServer.dbo.mysqlInsert @bitch;
--然后执行这个存储过程,用loopback这个服务做引用
END
如果存储过程和触发器出现问题要删除后重新执行,存储过程在库下,触发器在表下。
打开sqlserver manager 如下
然后就完事了
如果A表触发B表进行操作的时候B表失败了,A表也不会成功。而且报错也看不出来是哪个表报错,很坑爹。
参考
https://www.cnblogs.com/zhaowenzhong/p/5165522.html