sql-server - 违反 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 的事务中,但我不知道解析器如何
解决方案
我不同意你的解决方案,但如果我们想解决你遇到的问题,我有几件事要告诉你。
1:您有主键违规,因为您在数据流中有两次插入命令。
2:我建议您使用类似的东西,而不是您的数据流。
在您的控制流中添加三个数据流任务。
我们在第一个中转移所有插入。
然后我们将传输所有更新命令。您可以通过仅选择每个 sourceId 命令的最后更新而不是选择所有更新的标签来改进此步骤的选择命令。
最后一步是删除数据。
但我认为您应该使用此解决方案而不是您的解决方案。
1:在目标数据库中使用与源数据库中相同的模式创建一个临时表。
2:每次截断这个表。
3:将所有来自源服务器的数据带到目标数据库中的临时表中。(全部插入全部更新)
4:使用 T/SQL 合并命令合并临时表和目标表。
5:运行Delete命令删除destination中的行。
注意:如果源表中有两个字段为 (InsertedDate/UppdatedDate),则不需要在表中触发插入和更新。您可以将这些列与上次传输日期一起使用(您必须在每次传输数据时将其注册到某个位置)
推荐阅读
- rest - rest wcf 中的匿名身份验证
- c# - 如何访问文档文件夹 (UWP)
- c++ - return 语句中的构造函数语法?
- sql-server - 无法在 ForEach 循环中获得约束以处理 SQL 任务
- docker - 无法使用 docker 命令启动服务器 - 挂载目录 -OCI 运行时错误
- visual-studio - 如何解释 Visual Studio 我的源代码在另一个目录中?
- javascript - 找不到模块 'babel-core' 但已安装 @babel/core
- python - 通过 ssh 捕获文件中的流量
- sharepoint - 自定义列表 SharePoint Online 中的自动编号
- ksqldb - 您可以为 KSQL 中的表指定嵌套键吗?