仅当 tupel 满足条件时才触发插入

时间:2021-06-03 12:03:16

标签: sql postgresql triggers

我想创建一个触发器,在插入之前检查应该插入的 tupel 是否具有特定条件(这也取决于另一个表)。

例如:

create trigger or replace check_tupel
before insert on A
for each row
execute
   if exists (select x,y from B where B.x = A.x and B.y = A.y)

哦,我使用的是 postgreSQL 13。

编辑:是的,我知道我可以在没有触发器的情况下执行此操作,但是我出于某种原因要求使用触发器的解决方案。

我希望有办法做到这一点...我的另一个想法是创建一个在插入之前调用的 UDF,但我不知道如何检查此 UDF 中的条件,并且仅在函数返回 true 时才插入。

2 个答案:

答案 0 :(得分:0)

如果您只是想在使用用户定义函数将记录插入到基于表 function String getParam(String name){ return name.equals("x") ? "xValue" : "yValue"; } ..... /// call it in you rule as below ..... rule "my rule" when then System.out.println(getParam("x")); end 的表 A 之前自动验证记录,则根本不需要触发器。考虑添加一个简单的 CHECK CONSTRAINT

B

演示:db<>fiddle

CREATE TABLE a (
  x int,
  y int,
 CONSTRAINT exists_in_b CHECK (NOT myfunc(x,y))
);

现在,如果我们尝试插入我们的函数未验证的值,则会引发异常:

CREATE TABLE b (x int,
                y int);
INSERT INTO b VALUES (42,42);

CREATE OR REPLACE FUNCTION myfunc(x int, y int) 
RETURNS BOOLEAN AS $BODY$
 SELECT EXISTS (SELECT 1 FROM b WHERE b.y =$1 AND b.x=$2 )
$BODY$
LANGUAGE sql;

CREATE TABLE a (
  x int,
  y int,
 CONSTRAINT exists_in_b CHECK (NOT myfunc(x,y)) -- here the magic happens
);

编辑(见评论):使用触发器的解决方案

INSERT INTO a VALUES (42,42);

ERROR:  new row for relation "a" violates check constraint "exists_in_b"
DETAIL:  Failing row contains (42, 42).
SQL state: 23514

演示:db<>fiddle

答案 1 :(得分:0)

所以你需要一个触发解决方案,听起来像是一个家庭作业。那么问题就变成了你想不想:

  1. 中止整个操作
  2. 稍微挤压该行,但继续操作的其余部分。

下面是第二个:(见demo

create or replace 
function check_b_has_a() 
 returns trigger 
 language plpgsql
as $$
begin 
    if exists 
        ( select null 
            from b 
           where (b.x,b.y) = 
                 (new.x, new.y)
        ) 
    then 
       return null; 
    else 
       return new; 
    end if;
end; 
$$; 

create trigger a_bir
   before insert 
       on a 
      for each row 
      execute function check_b_has_a();