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
if OBJECT_ID('update_Books','P') is not null drop procedure dbo.update_Books
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 分散式事務連線