我是使用SSIS包从SQL Server复制数据到Oracle,我希望通过增量更新来提高复制的性能。
我的想法是:
代码:
drop table A1
drop table A2
--Old Table
create Table A1(id int,
a1 int, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int)
--New Table
create Table A2(id int,
a1 int, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int)
insert into A1 (id, a1, a2, a3, a4, a5, a6, a7, a8)
values (1,1,2,3,4,5,6,7,8), (2,2,2,5,4,2,6,2,8), (3,3,2,5,4,5,4,3,8),
(4,3,1,3,4,5,7,3,8)
insert into A2 (id, a1, a2, a3, a4, a5, a6, a7, a8)
values (1,2,2,3,4,5,6,7,8), (2,2,2,5,4,2,6,2,8), (3,3,2,5,4,5,4,3,8)
--1) Changed values
select * from a2
except
select * from a1;
--2) "Deleted" Values. If I Have primary key in A1,A2 the result is simply get by query
select a1.*
from A1
left join A2 on a2.id = a1.id
where a2.id is null
但在我的实际情况中,我的桌子上没有主键。如何在没有主键加入的情况下以另一种方式实现2点?
查询结果:
id a1 a2 a3 a4 a5 a6 a7 a8
1 2 2 3 4 5 6 7 8
id a1 a2 a3 a4 a5 a6 a7 a8
4 3 1 3 4 5 7 3 8
答案 0 :(得分:2)
使用MERGE语句,您可以执行INSERT,UPDATE&在单个操作中删除,它是增量负载的理想选择。
示例代码:
MERGE A2 AS target
USING (SELECT * FROM A1) AS source
ON (target.Id = source.Id AND target.a1 = Source.a1...) -- More join condition
WHEN MATCHED THEN
UPDATE SET a2 = source.a2, a3 = source.a3 ------ more columns
WHEN NOT MATCHED THEN
INSERT (Id, A1, a1, a2....)
VALUES (source.Id, source.a1, source.a2.....)
WHEN NOT MATCHED BY SOURCE
THEN DELETE
END;
MERGE语句还提供了捕获插入,删除和更新记录的灵活性(如果您需要它们用于记录目的),但在您确实需要该信息之前我不建议使用它们。
在上面的查询中,您可以保留要比较的列
ON(target.Id = source.Id AND target.a1 = Source.a1 ...) - 更多加入
在SSIS
您可以使用LOOKUP转换查找匹配和无匹配记录,然后插入或删除记录。 任何情况下,如果您正在考虑将源表与目标和更新进行比较中的所有列都没有意义。
答案 1 :(得分:0)
您可以使用基于日志文件而不是查询的CDC或其他日志传送机制。如果您仍想将SSIS用于查询 -
您是否曾尝试在SQL Server上使用 rowversion 来查找差异,但肯定会比 更快 。
从a2中选择*,其中rowversion> @lastmaxrowversion;
要找到删除是一项艰巨的任务,您可以做的最好的事情是
从不存在的a1中选择a1.id(从a2中选择前1 1) a1.id = a2.id);
如果你可以添加一个for delete触发器并将id保存在一个非常好的表中。