首页 > 解决方案 > 违反 PRIMARY KEY 的数据流

问题描述

我有一个在 2 个数据库之间进行 ETL 的包。为了获取数据库源的数据,我在表中使用触发器,所以我的数据保存在与事务类型一致的新表中:插入、更新和删除。

例子:

Id IdTableSource Transaction
1  1000          'Insert'   
2  1001          'Update'
3  1003          'Delete'
4  1000          'Update'

如果 wacth 行号 1 和 4 是相同的 IdTableSource。在我的数据流中,我使用一个组件进行条件和搜索,如果记录存在于目标表中,但是当发生上面的示例时,2 行具有相同的记录但类型不同的事务我收到错误“违反主键”

我的流程是:

对于第一条记录(例如编号 1)在我的表中找不到记录,然后执行命令插入。

对于第二条记录(例如第 4 条)也无法在我的表中找到该记录,然后执行命令插入(我收到错误“违反主键”)。

我相信这发生在 SSIS 的事务中,但我不知道解析器如何

示例数据流

标签: sql-serverssis

解决方案


我不同意你的解决方案,但如果我们想解决你遇到的问题,我有几件事要告诉你。

1:您有主键违规,因为您在数据流中有两次插入命令。

在此处输入图像描述

2:我建议您使用类似的东西,而不是您的数据流。

在此处输入图像描述

在您的控制流中添加三个数据流任务。

我们在第一个中转移所有插入。

在此处输入图像描述

然后我们将传输所有更新命令。您可以通过仅选择每个 sourceId 命令的最后更新而不是选择所有更新的标签来改进此步骤的选择命令。

在此处输入图像描述

最后一步是删除数据。

在此处输入图像描述

但我认为您应该使用此解决方案而不是您的解决方案。

1:在目标数据库中使用与源数据库中相同的模式创建一个临时表。

2:每次截断这个表。

3:将所有来自源服务器的数据带到目标数据库中的临时表中。(全部插入全部更新)

4:使用 T/SQL 合并命令合并临时表和目标表。

5:运行Delete命令删除destination中的行。

注意:如果源表中有两个字段为 (InsertedDate/UppdatedDate),则不需要在表中触发插入和更新。您可以将这些列与上次传输日期一起使用(您必须在每次传输数据时将其注册到某个位置)


推荐阅读