在程序触发器内动态插入记录

Posted

技术标签:

【中文标题】在程序触发器内动态插入记录【英文标题】:Insert record dynamically inside of Procedural Trigger 【发布时间】:2015-01-30 18:48:08 【问题描述】:

我们正在寻求将我们的数据库转换为我没有经验的 Postgres (9.3.5),并且我正在尝试启动并运行我们的审计表。我知道每个表都需要自己的触发器,但所有触发器都可以调用一个函数。

表上的触发器正在传递需要审核的列列表,因为我们的某些列没有被跟踪。

以下是我关注的一些帖子: - https://***.com/a/7915100/229897 - http://www.postgresql.org/docs/9.3/static/plpgsql-statements.html - http://www.postgresql.org/docs/9.4/static/plpgsql-trigger.html

当我运行此程序时,我收到错误:错误:“$1”或附近的语法错误

DROP TABLE IF EXISTS people;
DROP TABLE IF EXISTS a_people;

CREATE TABLE IF NOT EXISTS people (
  record_id  SERIAL PRIMARY KEY NOT NULL,
  first_name VARCHAR NOT NULL,
  last_name VARCHAR NOT NULL,
  last_updated_on TIMESTAMP NOT NULL DEFAULT  CURRENT_TIMESTAMP 
);

CREATE TABLE IF NOT EXISTS a_people (
  record_id  SERIAL PRIMARY KEY NOT NULL,
  a_record_id INT,
  first_name VARCHAR NULL,
  last_name VARCHAR NULL,
  last_updated_on TIMESTAMP
);
/******************************************************/
--the function
CREATE OR REPLACE FUNCTION audit_func()
RETURNS TRIGGER AS 
$BODY$  
    DECLARE 
        audit   TEXT := TG_TABLE_SCHEMA || '.a_' || TG_TABLE_NAME;
        cols    TEXT := TG_ARGV[0];
    BEGIN
        EXECUTE format('INSERT INTO %1$s(a_%2$s) SELECT %2$s FROM ($1)',  audit, cols) USING OLD;   
        NEW.last_updated_on = CURRENT_TIMESTAMP;
        RETURN NEW;
    END;
$BODY$
LANGUAGE plpgsql;
/******************************************************/
--the trigger calling the function to update inbound records
CREATE TRIGGER build_user_full_name_trg 
BEFORE UPDATE
ON people 
FOR EACH ROW WHEN (OLD.* IS DISTINCT FROM NEW.*)
EXECUTE PROCEDURE audit_func('record_id,first_name,last_name');
/******************************************************/
INSERT INTO people (first_name, last_name) VALUES ('George','Lincoln');
UPDATE people SET last_name = 'Washington' WHERE first_name = 'George';
SELECT * FROM people;

欢迎您的帮助(和耐心)!

【问题讨论】:

【参考方案1】:

这个子选择应该可以工作:

EXECUTE format('INSERT INTO %1$s(a_%2$s) SELECT %2$s FROM (select ($1).*) XX',  audit, cols) USING OLD;   

【讨论】:

以上是关于在程序触发器内动态插入记录的主要内容,如果未能解决你的问题,请参考以下文章

在 Oracle 触发器中动态评估伪记录 (:OLD, :NEW)

使用AFTER INSERT触发器将实体框架插入表中

Oracle中触发器内的select语句出现错误的绑定变量错误

插入数据库表中一条记录同时也插入另一个表中的SQL语句怎么写

是否可以创建一个触发器,该触发器在将记录插入一个数据库但最终插入另一个数据库时执行?

数据库触发器或代码中的常用方法?