如何在PostgreSQL 8.2中动态使用TG_TABLE_NAME?
我试图在PostgreSQL 8.2中编写一个触发器函数,它将动态使用TG_TABLE_NAME来生成和执行SQL语句.我可以为PostgreSQL的更高版本找到各种各样的例子,但由于一些要求,我被困在8.2上.这是我的功能,因为它有效,但几乎没有动态:
CREATE OR REPLACE FUNCTION cdc_TABLENAME_function() RETURNS trigger AS $cdc_function$ DECLARE op cdc_operation_enum; BEGIN op = TG_OP; IF (TG_WHEN = 'BEFORE') THEN IF (TG_OP = 'UPDATE') THEN op = 'UPDATE_BEFORE'; END IF; INSERT INTO cdc_test VALUES (DEFAULT,DEFAULT,op,OLD.*); ELSE IF (TG_OP = 'UPDATE') THEN op = 'UPDATE_AFTER'; END IF; INSERT INTO cdc_test VALUES (DEFAULT,NEW.*); END IF; IF (TG_OP = 'DELETE') THEN RETURN OLD; ELSE RETURN NEW; END IF; END; 这是当前编写的方式,我将不得不为每个表编写一个单独的触发器函数.我想使用TG_TABLE_NAME来动态构建我的INSERT语句,并在其前面加上’cdc_’,因为所有表都遵循相同的命名约定.然后我可以让每个表调用的每个触发器只有一个函数.
几年前我一直在寻找同样的东西.一个触发器功能来统治它们!我问过usenet列表,尝试了各种方法,但无济于事.关于此事的共识是无法做到的. PostgreSQL 8.3或更早版本的缺点.
Since PostgreSQL 8.4你可以: EXECUTE 'INSERT INTO ' || TG_RELID::regclass::text || ' SELECT ($1).*' USING NEW; 使用第8.2页,您有一个问题: >无法动态访问NEW / OLD列.你得知道 然而,有一个技巧. 系统中的每个表名都可以作为同名的复合类型.因此,您可以创建一个将NEW / OLD作为参数并执行该功能的函数.您可以在每个触发事件上动态创建和销毁该函数: 触发功能: CREATE OR REPLACE FUNCTION trg_cdc() RETURNS trigger AS $func$ DECLARE op text := TG_OP || '_' || TG_WHEN; tbl text := quote_ident(TG_TABLE_SCHEMA) || '.' || quote_ident(TG_TABLE_NAME); cdc_tbl text := quote_ident(TG_TABLE_SCHEMA) || '.' || quote_ident('cdc_' || TG_TABLE_NAME); BEGIN EXECUTE 'CREATE FUNCTION f_cdc(n ' || tbl || ',op text) RETURNS void AS $x$BEGIN INSERT INTO ' || cdc_tbl || ' SELECT op,(n).*; END $x$LANGUAGE plpgsql'; CASE TG_OP WHEN 'INSERT','UPDATE' THEN PERFORM f_cdc(NEW,op); WHEN 'DELETE' THEN PERFORM f_cdc(OLD,op); ELSE RAISE EXCEPTION 'Unknown TG_OP: "%". Should not occur!',TG_OP; END CASE; EXECUTE 'DROP FUNCTION f_cdc(' || tbl || ',text)'; IF TG_OP = 'DELETE' THEN RETURN OLD; ELSE RETURN NEW; END IF; END $func$ LANGUAGE plpgsql; 触发: CREATE TRIGGER cdc BEFORE INSERT OR UPDATE OR DELETE ON my_tbl FOR EACH ROW EXECUTE PROCEDURE trg_cdc(); 表名必须像用户输入一样对待.使用quote_ident()来防止SQL注入. 但是,这样您就可以为每个触发事件创建和删除一个函数.相当大的开销,我不会那样做.你将不得不抽真空一些目录表. 中间地带 PostgreSQL支持function overloading.因此,每个具有相同基本名称(但不同参数类型)的表的一个函数可以共存.通过在创建触发器的同时为每个表创建一次f_cdc(..),您可以占据中间位置并显着降低噪声.这是每张桌子的一个小功能.您必须观察表定义的更改,但表不应经常更改.从触发器功能中删除CREATE和DROP FUNCTION,达到一个小巧,快速和优雅的触发器. 我可以看到自己在第8.2页中这样做.除了我不能再看到自己在第8.2页做任何事情.它有reached end of life in December 2011.也许你可以以某种方式升级. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |