tôi đã tạo ra một cái gì đó như thế này:
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;
Ý tưởng chính là phải có một kích hoạt trên 'trước bản cập nhật cho mỗi hàng' tạo (nếu cần) một bảng tạm thời (có nghĩa là giảm tại kết thúc giao dịch). Trong bảng này chỉ có một hàng với một giá trị, đó là số hàng được cập nhật trong giao dịch hiện tại. Đối với mỗi cập nhật, giá trị được tăng lên. Nếu giá trị lớn hơn 4, giao dịch sẽ bị dừng.
Nhưng tôi nghĩ rằng đây là giải pháp sai cho vấn đề của bạn. Có vấn đề gì khi chạy truy vấn sai mà bạn đã viết về, hai lần, vì vậy bạn sẽ có 8 hàng thay đổi. Điều gì về xóa hàng hoặc cắt xén chúng?
Nguồn
2010-04-01 20:51:40
Tôi xem xét sử dụng truy vấn bình thường + rollback nếu hàng bị ảnh hưởng lớn hơn max và dường như có giá trị tốt nhất như tôi thấy. Vâng trong 99% + sẽ có các truy vấn tốt (4 hàng được cập nhật tối đa) nhưng đây chỉ là bảo mật bổ sung cho hệ thống. Bảng với 'vấn đề' này là khá lớn và quan trọng đối với hệ thống để khôi phục lại nó sau khi truy vấn sai lầm như vậy có thể là đau đớn cho tất cả mọi người. Cảm ơn tất cả các bạn đã trả lời. Không biết cái nào để chấp nhận bởi vì tất cả chúng đều hữu ích :) – sbczk
Tại sao bạn muốn làm điều đó? Có lẽ có nhiều cách dễ dàng hơn để làm điều đó hơn một truy vấn lạ. Còn gì nữa ... sử dụng số đếm (nếu có thể) sẽ chậm hơn trong khi bảng phát triển. –
Vì vậy, bạn nghĩ rằng khi bạn có tối đa 4 hàng thay đổi truy vấn không thể được nhập sai? Điều này nghe giống như một loại cảm giác an toàn giả. –