【问题标题】:Data Flow Violation of PRIMARY KEY违反 PRIMARY KEY 的数据流
【发布时间】:2019-01-31 03:22:44
【问题描述】:

我有一个在 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 的事务中,但我不知道如何解析器

【问题讨论】:

  • 问题是概念性的,您正在将历史操作表移动到具有 ID 主键的生产性操作表。您在目标表上实际需要什么?如果您还删除了该特定 ID,会发生什么?您仍希望在目标表中保留该记录吗?
  • 我真正需要的是按顺序完成,更新后插入,并且查找可以在第二次执行时在我的表目标中找到记录。如果在我的目标表中发生记录类型删除应该执行删除(已经做了)。我不知道问题是否在查找中,但我找不到任何这些。
  • 对于这个特定的设计模式,您可以将UPDATE 记录插入到临时表中,然后使用执行 SQL 任务调用存储过程,该过程将根据中的内容处理更新适当的记录暂存表。 SSIS 实际上并不擅长更新。我认为您的条件拆分应该基于Transaction 列的值。
  • @user11890 你不能只复制生产表而不是历史操作吗? SSIS 无法处理这样的有序操作,您应该加载历史表的副本,然后使用过程来影响按顺序进行的更改。或者考虑在实例之间进行实时复制。
  • 感谢您的回答。我相信我需要其他桌子。同时添加图片数据流。

标签: sql-server ssis


【解决方案1】:

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

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

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

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

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

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

最后一步是删除数据。

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

1:在目标数据库中创建一个与源数据库相同架构的临时表。

2 : 每次截断此表。

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-17
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多