我试图达到的目的是基本上覆盖更新的0行,如果在表中不存在实际的PK / UK值的情况下发出UPDATE,这就是我所做的:
实际表格:
CREATE TABLE fdrgiit.vereine(
team numeric(10) primary key,
punkte int not null,
serie int not null
);
虚拟表:
CREATE TABLE fdrgiit.dummyup
(
id numeric(1) PRIMARY KEY,
datetest timestamp
);
在两个表中插入记录:
insert into vereine(team,punkte,serie) values(1, 50, 1);
insert into vereine(team,punkte,serie) values(2, 30, 1);
insert into vereine(team,punkte,serie) values(3, 25, 1);
insert into vereine(team,punkte,serie) values(4, 37, 2);
insert into dummyup values(1, now());
创建了以下函数并触发:
create or replace function updateover()
returns trigger as
$BODY$
begin
if EXISTS (select 1 FROM vereine WHERE team = new.team ) then
RETURN NEW;
else
UPDATE fdrgiit.dummyup set datetest=now() where id=1;
RETURN NULL;
end if;
end;
$BODY$
LANGUAGE plpgsql;
create trigger update_redundancy
before update on vereine
for each row
execute procedure updateover() ;
但是当我在上执行这样的UPDATE时,我仍然会受到 0行影响
update vereine set punkte=87 where team=5;
请仔细检查,并建议是否可以这样做。
答案 0 :(得分:1)
您不能使用不会影响行的UPDATE来触发任何操作,因为仅对受影响的行触发触发器。
但是您可以将替代项UPDATE
包装到一个函数中
CREATE OR REPLACE FUNCTION updateover()
RETURNS int AS
$func$
UPDATE dummyup
SET datetest = now()
WHERE id = 1
RETURNING 2;
$func$ LANGUAGE sql;
...并运行这样嵌套的UPDATE
:
WITH upd AS (
UPDATE vereine
SET punkte = 87
WHERE team = 5 -- does not exist!
RETURNING 1
)
SELECT 1 FROM upd
UNION ALL
SELECT updateover()
LIMIT 1;
db <>提琴here
如果没有行符合UPDATE
的条件,则第一个外部SELECT 1 FROM upd
不返回任何行,Postgres继续处理第二个SELECT updateover()
。但是,如果至少有一行受到影响,则最后的SELECT
将永远不会执行。正是您想要的。
如果dummyup
上的UPDATE
不影响任何行,则更新vereine
一次 时间;从来没有几次。但这没关系,因为在交易期间now()
是STABLE
。
相关: