Ich habe so etwas wie diese erstellt:
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;
Die Hauptidee ist es, einen Auslöser haben, auf ‚vor der Aktualisierung für jede Reihe‘, die (falls erforderlich) eine temporäre Tabelle erstellt (das bei dem abfall Ende der Transaktion). In dieser Tabelle gibt es nur eine Zeile mit einem Wert, das ist die Anzahl der aktualisierten Zeilen in der aktuellen Transaktion. Für jede Aktualisierung wird der Wert erhöht. Wenn der Wert größer als 4 ist, wird die Transaktion gestoppt.
Aber ich denke, dass dies eine falsche Lösung für Ihr Problem ist. Was ist ein Problem beim Ausführen einer solchen falschen Abfrage, über die Sie schon zweimal geschrieben haben, so dass Sie 8 Zeilen geändert haben? Was ist mit Löschzeilen oder deren Kürzung?
Ich dachte über normale Abfrage + Rollback, wenn betroffene Zeilen größer als max ist, und das scheint der beste Wert, wie ich sehe. Nun, in 99% + wird es gute Abfragen geben (4 aktualisierte Zeilen maximal), aber dies ist nur zusätzliche Sicherheit für das System. Die Tabelle mit diesem "Problem" ist ziemlich groß und kritisch für das System, so dass die Wiederherstellung nach einer solchen verfälschten Abfrage für alle schmerzhaft sein kann. Vielen Dank für die Antworten. Ich weiß nicht, welches man annehmen soll, weil alle hilfreich waren :) – sbczk
Warum willst du das machen? Vielleicht gibt es einen viel einfacheren Weg als eine so seltsame Abfrage. Was mehr ... Die Verwendung von count (wenn möglich) wird langsamer, während die Tabelle wächst. –
Sie denken also, dass wenn Sie maximal 4 Zeilen geändert haben, die Abfrage nicht falsch eingegeben werden konnte? Das klingt nach einer Art falschem Sicherheitsgefühl. –