我 想 防止 使用 约束 写入 数据 , 但 约束 很 复杂 。
我 有 3 列 :A 、 B 、 C
如果 A & B 与 现有 记录 匹配 , 且 A & C 与 现有 记录 匹配 , 则 记录 是 重复 的 , 但 B & C 与 现有 记录 匹配 是 有效 的 , 除非 A = 2 。
例如 , 假设 现有 记录
A=1,B=2,C=3
中 的 每 一 个
如果 我 插入
A=1,B=2,C=4
格式
我 应该 得到 一 个 错误
如果 我 插入
A=1,B=99,C=3
格式
我 应该 得到 一 个 错误
如果 我 插入 :
A=99,B=2,C=3
格式
那 就 成功 了 。
如果 我 插入 :
A=2,B=2,C=3
格式
我 应该 得到 一 个 错误 。
检查 必须 在 INSERT 时 完成 。 我 不能 先 执行 SELECT 然后 再 执行 INSERT , 因为 数据 可能 在 SELECT 和 INSERT 之间 发生 了 更改 。
思路 :
- 如果 我 把 逻辑 放在 一 个 TRIGGER 中 , 那 会 起 作用 吗 ? 我 不 确定 触发 器 是否 是 100% 原子 的 。
- TRANSACTION 是否 有效 ? 我 不 想 锁定 表 , 因为 其他 进程 将 不断 插入 数据 。
- 我 可以 添加 一 个 或 多 个 约束 吗 ? 是否 有 方法 在 INSERT 时 检查 约束 ?
3条答案
按热度按时间t9eec4r01#
对于列
A
&B
和A
&C
的唯一性的简单组合,可以使用唯一索引或唯一约束来解决这个问题。然而,对于后一个问题,这就不那么容易了。我在这里使用了
TRIGGER
,并检查是否找到了具有相同值B
和C
的匹配行(其中ID不同,否则行将与其自身匹配),并且其中插入的行具有A
的值2
,或者现有行具有A
的值。如果找到匹配,则错误为THROW
n,从而导致INSERT
/UPDATE
发生故障。显然,您可能希望更改错误号和消息,但我写了一些合理的内容。db<>fiddle
zzoitvuj2#
粗略地看,我认为您可以使用唯一筛选索引。
1.唯一:A、B --始终
1.唯一:A、C --始终
1.唯一B、C,其中A==2
5n0oy7gb3#
我会尝试使用公用表表达式并在插入语句中添加where子句。如果插入返回了零个更新的行,则认为插入失败?