我有这些表:
CREATE EXTENSION citext; CREATE EXTENSION "uuid-ossp"; CREATE TABLE cities ( city_id serial PRIMARY KEY,city_name citext NOT NULL UNIQUE ); INSERT INTO cities(city_name) VALUES ('New York'),('Paris'),('Madrid'); CREATE TABLE etags ( etag_name varchar(128) PRIMARY KEY,etag_value uuid ); INSERT INTO etags(etag_name,etag_value) VALUES ('cities',uuid_generate_v4());
我想在城市表更改时更新城市etag.如果插入,更新或删除语句没有影响行,我想避免更改城市etag,所以我编写了以下语句级别触发器:
CREATE OR REPLACE FUNCTION update_etag() RETURNS trigger AS $BODY$ DECLARE record_count integer; vetag_name varchar(128); BEGIN GET DIAGNOSTICS record_count = ROW_COUNT; vetag_name := TG_ARGV[0]; RAISE NOTICE 'affected %:%',vetag_name,record_count; IF record_count = 0 THEN RETURN NULL; END IF; UPDATE etags SET etag_value = uuid_generate_v4() WHERE etag_name = vetag_name; RETURN null; END; $BODY$ LANGUAGE plpgsql VOLATILE; CREATE TRIGGER update_cities_etag_trigger AFTER INSERT OR UPDATE OR DELETE ON cities FOR EACH STATEMENT EXECUTE PROCEDURE update_etag('cities');
但是GET DIAGNOSTICS record_count = ROW_COUNT;对我不起作用,因为它总是返回0.
如果我执行以下操作:
DELETE FROM cities;
输出如下:
NOTICE: affected cities:0 Query returned successfully: 3 rows
affected,47 msec execution time.
有没有办法弄清楚在Postgresql语句级触发器中触发触发器的语句会影响多少行?
版本10
... [ REFERENCING { { OLD | NEW } TABLE [ AS ] transition_relation_name } [ ... ] ] ...
https://www.postgresql.org/docs/current/static/release-10.html
Add AFTER trigger transition tables to record changed rows (Kevin
Grittner,Thomas Munro)Transition tables are accessible from triggers written in server-side
languages.
解决它:
CREATE OR REPLACE FUNCTION update_etag() RETURNS trigger AS $BODY$ DECLARE record_count integer; vetag_name varchar(128); begin IF (TG_OP = 'DELETE') or (TG_OP = 'UPDATE') THEN select count(*) from oldtbl into record_count ; ELSE select count(*) from newtbl into record_count ; END IF; vetag_name := TG_ARGV[0]; RAISE NOTICE 'affected %:%:%',TG_OP,record_count; IF record_count = 0 THEN RETURN NULL; END IF; UPDATE etags SET etag_value = uuid_generate_v4() WHERE etag_name = vetag_name; RETURN null; END; $BODY$ LANGUAGE plpgsql VOLATILE; CREATE TRIGGER update_ins_cities_etag_trigger AFTER INSERT ON cities REFERENCING NEW TABLE AS newtbl FOR EACH STATEMENT EXECUTE PROCEDURE update_etag('cities'); CREATE TRIGGER update_upd_cities_etag_trigger AFTER UPDATE ON cities REFERENCING OLD TABLE AS oldtbl FOR EACH STATEMENT EXECUTE PROCEDURE update_etag('cities'); CREATE TRIGGER update_del_cities_etag_trigger AFTER DELETE ON cities REFERENCING OLD TABLE AS oldtbl FOR EACH STATEMENT EXECUTE PROCEDURE update_etag('cities'); so=# INSERT INTO cities(city_name) VALUES so-# ('New York'),('Madrid'); NOTICE: affected cities:INSERT:3 INSERT 0 3 so=# select * from etags; etag_name | etag_value -----------+-------------------------------------- cities | dc7d1525-eea7-4822-b736-5141a20764f8 (1 row) so=# insert into cities(city_name) values ('Budapest'); NOTICE: affected cities:INSERT:1 INSERT 0 1 so=# select * from etags; etag_name | etag_value -----------+-------------------------------------- cities | df835f44-dada-4a94-bb62-5890f2316103 (1 row) so=# delete from cities where city_id > 42; NOTICE: affected cities:DELETE:0 DELETE 0 so=# select * from etags; etag_name | etag_value -----------+-------------------------------------- cities | df835f44-dada-4a94-bb62-5890f2316103 (1 row)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。