sql - SQL Server 约束强制在几秒钟内被违反
问题描述
我有一个表,大约有 2100 万行,有一个主键约束,当我搜索那个表时,没有重复。此表位于不断移动的 OLTP 应用程序数据库中。
我在 Azure 中有完全相同的表,它具有相同的主键约束。此表不是应用程序表,它只是本地表的副本(目标是将此表用于临时查询,作为其他系统的源等)。
当我使用 Azure 数据工厂从本地表中选择all_columns到 Azure 中的表时,它返回违反主键约束。无论我运行这个数据工厂管道多少次,它都会返回重复键的主键冲突(尽管键总是在变化)。
所以我放弃了 Azure 中的主键约束,再次运行管道,果然存在重复。
经调查,内部部署数据库似乎正在插入新记录,然后更新旧记录以使其无效。因此,在几分之一秒内,ADF 正在抓取两个活动行,然后尝试将其插入 Azure 中的表中,这当然会因为主键重复而失败。
现在据我所知,这应该是不可能的。您不能插入违反主键约束的新行。但是 ADF 似乎正在抓取所有数据,其中一些行在插入发生的飞行中,并且尚未发生使旧行无效的更新。
对于那些好奇的人,插入发生并且旧行的更新发生在不到一秒的时间内……通常是 10-20 微秒。我不知道这是怎么可能的,也不知道如何解决(因为我无法修改应用程序代码)。本地数据库的数据库是 SQL Server 2000 数据库,Azure SQL 是 Azure SQL 数据库。
解决方案
需要在管道 Azure 数据工厂中启用容错
将数据从 Source SQL 复制到 Sink SQL 数据库。主键在接收 SQL 数据库中定义,但在源 SQL 服务器中没有定义这样的主键。源中存在的重复行无法复制到接收器。复制活动仅将源数据的第一行复制到接收器中。包含重复主键值的后续源行被检测为不兼容并被跳过。
要配置 Json 定义,请跳过复制活动中的不兼容行"enableSkipIncompatibleRow": true
请参考:https ://docs.microsoft.com/en-us/azure/data-factory/copy-activity-fault-tolerance
EXISTS()
如果可以修改您的应用程序,需要在插入或更新使用函数之前检查主键约束。
例子:
IF EXISTS(SELECT * FROM Table_Name WHERE primary key condition)
BEGIN
UPDATE Table_Name
SET Col_Name= value
WHERE condition
END
ELSE
BEGIN
INSERT INTO Table_Name ( col_Name1,col_Name2,,.. )
VALUES ( ‘’,’’,’’,….)
END
推荐阅读
- vue.js - '透明'包装的输入组件中的Vue双向绑定
- ios - 在 WKWebView DecidePolicy 中获取表单发布响应正文
- mobile - Threejs 轨道控制在触摸设备上无法正常工作
- python - 从另一个模块导入时,Python 枚举类与自身不匹配
- linux - Linux Bash Shell 读取日志文件将每一行与文件的重置进行比较
- java - Selenium - Gherkin - Java:验证必填字段上的文本
- webpack - Webpack 4 配置在同一 /src 中构建多个 Aurelia 应用程序共享公共模块
- regex - 具有一系列 unicode 字符的 mongodb 正则表达式
- php - 获取主页上显示的最后一篇 Wordpress 帖子?
- oracle - 查询以比较Oracle中多个表中的列