编写SQL触发器以查找列中出现的数字是否超过X次?

时间:2013-11-18 19:27:51

标签: sql postgresql triggers plpgsql

我想写一个Postgres SQL触发器,基本上可以找到一个数字在列中出现5次或更多次。如果它出现第五次,我想抛出异常。表格如下:

create table tab(
first integer not null constraint pk_part_id primary key,
second integer constraint fk_super_part_id references bom,
price integer);

insert into tab values(1,NULL,100), (2,1,50), (3,1,30), (4,2,20), (5,2,10), (6,3,20);

以上是表中的原始插入。将更多值插入表格后,将触发我的触发器。

基本上,如果在插入表格后,“第二”列中出现的数字超过4次,我想引发异常。这是我尝试编写触发器:

create function check() return trigger as '
begin
    if(select first, second, price
          from tab
          where second in (
            select second from tab
            group by second
            having count(second) > 4)
) then
raise exception ''Error, there are more than 5 parts.'';
end if;
return null;
end 
'language plpgsql;

create trigger check
after insert or update on tab
for each row execute procedure check();

有人可以帮帮我吗?如果是这样那将是伟大的!谢谢!

1 个答案:

答案 0 :(得分:0)

CREATE FUNCTION trg_upbef()
  RETURN trigger as
$func$
BEGIN
IF (SELECT count(*) 
    FROM   tab
    WHERE  second = NEW.second ) > 3 THEN

   RAISE EXCEPTION 'Error: there are more than 5 parts.';
END IF;

RETURN NEW;  -- must be NEW for BEFORE trigger

END
$func$ LANGUAGE plpgsql;

CREATE TRIGGER upbef
BEFORE INSERT OR UPDATE ON tab
FOR EACH ROW EXECUTE procedure trg_upbef();

重点

  • 关键字为RETURNS,而不是 RETURN

  • 使用special variable NEW来引用新插入/更新的行。

  • 使用BEFORE触发器。如果出现异常,最好尽早跳过。

  • 不要为你的测试计算所有,只需要你需要的。 很多更快。

  • 使用dollar-quoting。让您的生活更轻松。

  • 并发:
    如果你想绝对确定,你必须在计数之前对桌子进行独占锁定。否则,并发插入/更新可能会在繁重的并发负载下相互错过。虽然这不太可能,但这是可能的。