SQL Update在约束索引上触发

时间:2017-04-25 16:21:06

标签: sql postgresql

我在表格中有一列可以采用以下三个值中的一个:'past', 'present', 'future'

但是只有一行可以拥有'呈现'值。这是通过一个简单的唯一约束索引来检查的。尽管如此,我还是希望有时候有人手动创造一个未来的“未来”。排到'现在'行,触发一个函数。创建触发器并尝试通过手动更新未来'来测试它。排到'现在'行,正如预期的那样我得到以下错误:

ERROR: duplicate key value violates unique constraint "semester_status_present" DETAIL: Key (semester_status)=(present) already exists.

认为它有一分钟是完全合乎逻辑的,但在这种情况下我能做些什么?指数不合适吗?

这是索引约束:

CREATE UNIQUE INDEX semester_status_present
ON public."Semester"
USING btree
(semester_status)
WHERE semester_status = 'present'::semester_status;

提前感谢!

编辑!!!!:触发器也将前一个当前行转换为过去行!但是触发器是after update on "Semester",因为它避免了无限更新循环

2 个答案:

答案 0 :(得分:2)

使用before触发器,以便在更新尝试创建第二个当前行并中断约束之前,可以将现有的当前行更改为过去的行。

触发功能。

create function swap_present() returns trigger as $$
begin
  update "Semester" set semester_status = 'past' 
  where semester_status = 'present'::semester_status and id != new.id;
  return new;
end;
$$
language plpgsql;

我已经检查了new.id,以便触发器不会更改您正在更改的行。将其替换为桌子上的唯一ID。

触发定义。

create trigger semester_trigger before insert or update on "Semester"
for each row 
when (new.semester_status = 'present'::semester_status)
execute procedure swap_present();

when条款意味着我们只会在您更改或插入当前行时担心。

答案 1 :(得分:1)

由于它是后触发器,因此当将来成为当前行但在当前行尚未更改为过去之前,会出现重复值。

尝试将触发器更改为之前。这意味着会有一个时刻没有“现在”。行(当前更改为过去,未来尚未更改为现在)。

我希望您希望每个语句而不是每行运行它。您可能希望添加一个条件,仅在将后续行更改为当前行时触发。这样,添加新的未来行或更改当前/过去的行将不会应用触发器。