计算触发器更新前要受影响的行数

sbc*_*czk 8 postgresql

我想知道每个语句触发器中将受UPDATE查询影响的行数BEFORE.那可能吗?

问题是我想只允许最多4行的查询.如果受影响的行数为5或更多,我想提出错误.

我不想在代码中执行此操作,因为我需要在db级别上进行此检查.这是可能吗?

提前感谢任何线索

Szy*_*ski 2

我创建了这样的东西:

begin;

create table test (
    id integer
);

insert into test(id) select generate_series(1,100);


create or replace function trg_check_max_4_updated_records() 
returns trigger as $$
declare
    counter_ integer := 0;
    tablename_ text := 'temptable';
begin
    raise notice 'trigger fired';
    select count(42) into counter_ 
        from pg_catalog.pg_tables where tablename = tablename_;
    if counter_ = 0 then
        raise notice 'Creating table %', tablename_;
        execute 'create temporary table ' || tablename_ || ' (counter integer) on commit drop';
        execute 'insert into ' || tablename_ || ' (counter) values(1)';

        execute 'select counter from ' || tablename_ into counter_;
        raise notice 'Actual value for counter= [%]', counter_;
    else
        execute 'select counter from ' || tablename_ into counter_;
        execute 'update ' || tablename_ || ' set counter = counter + 1';
        raise notice 'updating';
        execute 'select counter from ' || tablename_ into counter_;
        raise notice 'Actual value for counter= [%]', counter_;

        if counter_ > 4 then
            raise exception 'Cannot change more than 4 rows in one trancation';
        end if;

    end if;
    return new;
end; $$ language plpgsql;


create trigger trg_bu_test before 
  update on test 
  for each row
  execute procedure trg_check_max_4_updated_records();

update test set id = 10 where id <= 1;
update test set id = 10 where id <= 2;
update test set id = 10 where id <= 3;
update test set id = 10 where id <= 4;
update test set id = 10 where id <= 5;

rollback;
Run Code Online (Sandbox Code Playgroud)

主要思想是在“每行更新之前”创建一个触发器,该触发器创建(如果需要)一个临时表(在事务结束时删除)。在这个表中只有一行有一个值,即当前事务中更新的行数。对于每次更新,该值都会递增。如果该值大于4,则交易停止。

但我认为这对你的问题来说是一个错误的解决方案。运行您所写的错误查询两次会出现什么问题,因此您将更改 8 行。删除行或截断行怎么样?