SQLServer數據實時同步至PostgreSQL
前言:
為迎合工作需求有時候傳送的數據保存在SQLServer中但由於工作需要需要保存到PostgreSQL中進行處理,本文主要通過在SQLServer中設置觸發器和存儲過程的方式完成數據的同步
系統環境說明
軟件 | 版本 | 說明 |
---|---|---|
SQLServer | 2008R2_X64 | X64位 |
PostgreSQL | 9.5_X64 | |
odbc | 9.5_X64 |
postgre_odbc下載安裝
odbc主要是讓PostgreSQL與SQLServer之間建立橋梁利於數據傳輸下載地址
PostgreSQL_odbc選擇要下載的版本
演示環境下載的9.5版本隨本機安裝Postgre數據庫
下載完成解壓得到Psqlodbc_x64.msi,雙擊運行安裝默認即可
安裝完成后通過系統自帶的ODBC數據源配置系統DNS
點擊添加打開需要添加的數據源,這里選擇PostgreSQL ANSIx64
添加PostgreSQL連接
DataSource:連接名稱 ,后續在SQLServer中會用到
Database: 要連接的數據庫
Server: Posgresql服務地址,也可以是IP
Port: 服務端口號
User Name:用戶登錄名
Password:登錄密碼
輸入連接參數后點擊Test 測試是否成功 成功后點擊Save 保存即可
添加鏈接服務器方法1——用操作界面添加
- SQLServer中添加服務器對象
打開SQLServer數據庫連接,找到服務器對象->鏈接服務器->鼠標右鍵選擇新建鏈接服務器
常規
1.設置連接對象名稱
2.選擇訪問接口,這里先連接本地所以選擇如圖,當添加ODBC時會有所不同
3.輸入產品名稱,這里隨意填寫(不能為null),測試單詞中有空格添加失敗
4.數據源名稱,這里為SQL Server服務器連接IP,本地連接故以“.”代替
安全性
當切換到安全性選項卡時,默認
- [x] 不使用安全上下文連接(N)
這里切換到 使用此安全上下文建立連接 使用SQLServer登錄用戶名登陸即可
服務器選項
將RPC 設置為 True 默認為False
將RPC Out 設置為 True 默認為False
將為RPC 啟動針對分布式事務升級 設置為 false 默認為 true
設置完成后單擊確定即可完成設置
添加PostgreSQL 連接服務器
添加PostgreSQL 鏈接服務器與 SQLServer 步驟類似
區別在於:
訪問接口-> Microsoft OLE DB Provider for ODBC Drivers
數據源 -> 為ODBC鏈接對象DataSource 名稱
安全性輸入填寫 PostgreSQL 的登陸賬號、密碼即可
服務器選項相同
添加鏈接服務器方法2————用T-SQL命令添加
use master
go
/****** Object: LinkedServer [LOCALHOSTSQL]
判斷是否存在 LOCALHOSTSQL 名稱的LinkedServer 如果有則刪除
******/
IF EXISTS (SELECT srv.name FROM sys.servers srv WHERE srv.server_id != 0 AND srv.name = N'LOCALHOSTSQL')EXEC master.dbo.sp_dropserver @server=N'LOCALHOSTSQL', @droplogins='droplogins'
GO
/****** Object: LinkedServer [LOCALHOSTSQL]
添加本地鏈接 調用存儲過程 master.dbo.sp_addlinkedserver
******/
EXEC master.dbo.sp_addlinkedserver
@server = N'LOCALHOSTSQL', --鏈接服務器
@srvproduct=N'SQlServer', --產品名稱
@provider=N'SQLNCLI', --訪問接口
@datasrc=N'.\SQL08R2' --數據源
/*
安全性添加 調用存儲過程 master.dbo.sp_addlinkedsrvlogin
*/
EXEC master.dbo.sp_addlinkedsrvlogin
@rmtsrvname=N'LOCALHOSTSQL', --鏈接服務器
@useself=N'False', --
@locallogin=NULL, --本地登陸
@rmtuser=N'sa', --遠程登陸用戶
@rmtpassword='########' --遠程登陸密碼 改成實際用戶名密碼
GO
/*
服務器選項 調用存儲過程 master.dbo.sp_serveroption 這里服務器選項操作很多,這里只選擇需要的配置,其他為默認選項
*/
EXEC master.dbo.sp_serveroption
@server=N'LOCALHOSTSQL', --鏈接服務器
@optname=N'rpc out', --操作 rpc out選項
@optvalue=N'true' --選項值
GO
EXEC master.dbo.sp_serveroption
@server=N'LOCALHOSTSQL', --鏈接服務器
@optname=N'rpc', --操作rpc選項
@optvalue=N'true' --選項值
GO
EXEC master.dbo.sp_serveroption
@server=N'LOCALHOSTSQL',
@optname=N'remote proc transaction promotion', --rpc 事務選項
@optvalue=N'false'
GO
/*
判斷是否有 名稱為 POSTGRESQL 的鏈接服務器 如果有則刪除
*/
IF EXISTS (SELECT srv.name FROM sys.servers srv WHERE srv.server_id != 0 AND srv.name = N'POSTGRESQL')EXEC master.dbo.sp_dropserver @server=N'POSTGRESQL', @droplogins='droplogins'
GO
/****** 常規 ******/
EXEC master.dbo.sp_addlinkedserver
@server = N'POSTGRESQL', --鏈接服務器
@srvproduct=N'PostgreSQL', --產品名稱
@provider=N'MSDASQL', --驅動
@datasrc=N'PostgreSQL95' --數據源
/* POSTGRESQL 安全性配置 */
EXEC master.dbo.sp_addlinkedsrvlogin
@rmtsrvname=N'POSTGRESQL', --鏈接服務器
@useself=N'False', --
@locallogin=NULL, --本地登陸
@rmtuser=N'postgres', --登陸賬號
@rmtpassword='########' --登陸密碼 改為實際密碼
GO
/*服務器選項*/
EXEC master.dbo.sp_serveroption
@server=N'POSTGRESQL', --鏈接服務器
@optname=N'rpc out', --操作選項
@optvalue=N'true' --選項值
GO
EXEC master.dbo.sp_serveroption
@server=N'POSTGRESQL', --鏈接服務器
@optname=N'rpc', --操作選項
@optvalue=N'true' --選項值
GO
EXEC master.dbo.sp_serveroption
@server=N'POSTGRESQL',
@optname=N'remote proc transaction promotion',
@optvalue=N'false'
GO
利用T-SQL添加數據源 鏈接服務器名稱可小寫 大小寫混合,利用窗口添加 鏈接服務器名稱默認大寫。未找到更好兼容解決方案 ,看個人習慣選擇即可
檢查鏈接服務器是否正常顯示數據源,展開剛添加的數據源對象,查看目錄下是否有鏈接數據庫名稱
准備測試數據結構
在SQLServer Books數據庫中新建書單信息表、並添加測試數據
use Books
go
--判斷是否有存在表
if OBJECT_ID('dbo.books','U') is not null drop table dbo.books
go
--創建表存儲
create table books(
id int identity(1,1) primary key,
name varchar(150) not null,
price float not null,
stock int not null
)
go
--添加數據
insert into books(name,price,stock)values
('Access入門實戰',49.5,999),
('T-SQL性能調優秘笈',49.0,999),
('.NET MVC5 高級變成',79.8,999),
('Python 入門實戰',89.00,999);
--檢查添加數據
select * from books;
postgreSQL中添加同結構數據表
編寫存儲過程
use Books
GO
if OBJECT_ID('Insert_Books','P') is not null drop procedure dbo.Insert_Books
go
--添加插入存儲過程
CREATE PROCEDURE Insert_Books
@name varchar(100),@price float,@stock int
AS
BEGIN
SET NOCOUNT ON;
insert openquery(POSTGRESQL,'select name,price,stock from books where 1=0')(name,price,stock) values
(@name,@price,@stock);
SET NOCOUNT ON;
END
GO
添加觸發器
--創建添加觸發器
CREATE TRIGGER insert_trigger
ON Books.dbo.books
AFTER INSERT
AS
BEGIN
declare @name varchar(150),@price float,@stock int
select @name=name,@price=price,@stock=stock from inserted
SET NOCOUNT ON;
exec LOCALHOSTSQL.[books].[dbo].[Insert_Books] @name,@price,@stock
-- Insert statements for trigger here
END
測試效果
同步SQLServer 數據庫中的 數據至PostgreSQL
insert openquery(POSTGRESQL,'select name,price,stock from books where 1=0')
select name,price,stock from books
postgresql數據中
測試添加數據
insert into books(name,price,stock) values('代碼整潔之道',56.3,623)
select * from books
可以看到當在SQLServer中數據后,PostgreSQL數據庫中的數據也隨之增加了,證明此方法測試運行成功
遇到的問題:
1.無法執行該操作,因為鏈接服務器 "XXX" 的 OLE DB 訪問接口 "SQLNCLI10" 無法啟動分布式事務。
在組件服務中->本地DTC->屬性->安全 配置
重啟msdtc 服務 net start msdtc
net stop msdtc
2.Microsoft 分布式事務處理協調器(MS DTC)已停止此事務。
檢查連接服務器配置 ,rpc、rpc out 、rpc 分布式事務連接