Postgresql
創建約束以停止對錶的大規模更新
我想創建一個約束,以便如果表中超過 5 行正在使用
UPDATE
語句更新,它應該警告使用者/阻止查詢。
實現此目的的一種方法是使用觸發器並行更新臨時表(僅在同一會話中可見)。
使用 創建臨時表
ON COMMIT DROP
,以便它在事務期間存在。這樣,同一事務期間的所有更新都將計入最大值。展示表:
CREATE TABLE foo(id serial, txt text)
觸發功能:
CREATE OR REPLACE FUNCTION trg_foo_maxup() RETURNS trigger AS $func$ DECLARE _ct int; BEGIN IF EXISTS ( SELECT 1 FROM pg_catalog.pg_class WHERE relname = 'foo_maxup' AND relnamespace = pg_my_temp_schema() AND relkind = 'r' ) THEN UPDATE foo_maxup SET ct = ct + 1 RETURNING ct INTO _ct; IF _ct > 5 THEN -- your maximum here RAISE EXCEPTION 'Cannot update more than 5 rows in one transaction!'; END IF; ELSE CREATE TEMP TABLE foo_maxup ON COMMIT DROP AS SELECT 1 AS ct; END IF; RETURN NEW; END $func$ LANGUAGE plpgsql VOLATILE SET search_path = pg_temp;
扳機:
CREATE TRIGGER maxup BEFORE UPDATE ON foo FOR EACH ROW EXECUTE PROCEDURE trg_foo_maxup();
如果您想要整個會話的最大值,只需省略
ON COMMIT DROP
.我添加
SET search_path = pg_temp
到函式定義中以防止search_path
. 此觸發器僅在其search_path
. 這就是為什麼pg_catalog.pg_class
必須是表限定的。