创建触发器以检查状态,

时间:2019-02-13 19:51:11

标签: postgresql

我有一张包含公司的表格,其中一列是其状态,可以作为A激活,也可以作为D停用,我正在尝试触发一个触发条件,以检查公司是否处于活跃状态,以便他们可以纳税或停用,它们不会被打扰。

CREATE TRIGGER StatusCheck
  BEFORE INSERT
  ON Companies C
REFERENCING NEW AS N --row to be added
FOR EACH ROW
WHEN c.status <> 'A' or c.status <>'D';
ABORT TRANSACTION

这显然是行不通的,但是我该怎么做,因为我对此已经考虑过多,现在我认为我需要一些帮助。

1 个答案:

答案 0 :(得分:0)

实现这种要求的正确,最有效的方法是check constraint

alter table companies
   add constraint check_status check (status in ('A', 'D'));

如果您被迫使用触发器:

您创建触发器语句有两个错误:

第一个是语法错误:[abort transaction] [1]语句中没有create trigger选项。

第二个错误是逻辑错误:条件c.status <> 'A' or c.status <>'D'本质上始终为true。您想要的是一个AND条件:“ 如果状态值不同于A 不同于D ... 。”

但是,Postgres中完整的触发器定义由trigger functioncreate trigger语句组成,该语句将该函数附加到表触发器。

在函数内部,您将需要引发异常以中止事务:

create function check_company_status()
  returns trigger
as
$$
begin
  if not new.status in ('A', 'D') then 
    raise 'Invalid valid for status specified';
  end if;
  return new;
end;
$$
language plpgsql;

现在有了触发器功能,我们可以将其附加到表上的触发器:

create trigger check_status_trigger
   before insert or update
   on companies
   for each row
   execute procedure check_company_status();

将其定义为BEFORE触发器很重要。


请注意,这些解决方案都不会在该列中阻止NULL值。如果您还想防止NULL,则该列应定义为NOT NULL