我试图找到一种在表每次执行插入或更新操作时从SQL Server 2014和2017复制数据的方法。我正在尝试实时地将这些值插入PostgreSQL中的另一个表中。我探索的选项很少有使用以下工具进行批处理的:
Talend ETL工具
PostgreSQL中使用cron作业触发的外来数据包装器 每小时执行一次插入和更新PostgreSQL表的过程 使用SQL Server表中的数据。
我不确定如何从SQL Server实时获取事件,我是否可以与诸如Kafka甚至Python微服务之类的链接,或者是否有更好的方法。
答案 0 :(得分:2)
使用触发器
创建SQL Server和Postgresql表:
-- SQL Server
create table test (id int identity(1,1) not null primary key, name varchar(25), description varchar(1000))
go
-- Postgresql:
CREATE TABLE public.test
(
id integer,
name character varying(25) COLLATE pg_catalog."default",
description character varying(1000) COLLATE pg_catalog."default"
)
在SQL Server中创建与Postgresql服务器的链接服务器。
然后在您的SQL Server表上创建触发器:
create trigger iu_trigger_name on test
after insert, update
as
begin
UPDATE [SQLAuth_PG].[DefaultDB].[public].[test]
SET name = t.name, description = t.description
FROM [SQLAuth_PG].[DefaultDB].[public].[test] p
INNER JOIN inserted t ON p.id = t.id
INSERT INTO [SQLAuth_PG].[DefaultDB].[public].[test]
([id]
,[name]
,[description])
SELECT t.id, t.name, t.description
FROM inserted t
WHERE NOT EXISTS (
SELECT * FROM [SQLAuth_PG].[DefaultDB].[public].[test]
WHERE id = t.id
)
end
go
create trigger d_trigger_name on test
after delete
as
begin
delete p
FROM [SQLAuth_PG].[DefaultDB].[public].[test] p
inner join deleted d on p.id = d.id
end
go
测试:
insert into test (name, description) select 'Name1', 'Name 1 description'
go
select * from [SQLAuth_PG].[DefaultDB].[public].[test]
--output
--id name description
--1 Name1 Name 1 description
update test set description = 'Updated description!' where name = 'Name1'
go
select * from [SQLAuth_PG].[DefaultDB].[public].[test]
-- output
--id name description
--1 Name1 Updated description!
delete from test
go
select * from [SQLAuth_PG].[DefaultDB].[public].[test]
go
-- postgresql table is empty
此示例中的触发器处理批处理插入和更新。这是触发器的唯一真正陷阱-假设“插入”表中只有一条记录。批量插入或更新后,将使用所有新的/已修改的记录填充插入的表。
答案 1 :(得分:1)
如果要走Kafka路线,有几种方法可以将数据从SQL Server移入Kafka:
对于基于日志的CDC:
对于基于查询的CDC:
一旦数据进入Kafka,您就可以使用kafka-connect-jdbc接收器将其流式传输到Postgres(或任何其他数据库)。