更改受更新影响的行数

时间:2019-07-11 08:00:27

标签: sql postgresql database-design plpgsql

我试图达到的目的是基本上覆盖更新的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; 

请仔细检查,并建议是否可以这样做。

1 个答案:

答案 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

相关: