在触发器

时间:2016-11-16 09:56:49

标签: postgresql

我想使用触发器进行日志记录 - 每次,当用户插入内容或进行更新时,我的history表中都会出现一个新行。我已经有了一个触发器,效果很好。现在它每次都会运行,当我插入时。这就是它的样子:

CREATE OR REPLACE FUNCTION public.trigger_history_insert()
    RETURNS trigger AS
$BODY$ 
DECLARE 
    ...
BEGIN
    ... it does a lot of things here and works absolutely correctly
END; 
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION public.trigger_history_insert()
OWNER TO postgres;

现在我想在此触发器中添加日志记录。我试着遵循这两个官方教程([1][2]),但最终以失败告终。这是我的第一次尝试:

DECLARE
    ...
BEGIN
    ... everything remains unchanged except this part
    EXEC SQL BEGIN DECLARE SECTION;
    const char *stmt = 'INSERT INTO history (field1) VALUES (?)';
    EXEC SQL END DECLARE SECTION;        
    EXEC SQL PREPARE mystmt FROM :stmt;
    EXEC SQL EXECUTE mystmt USING new.field1;
END;

在这种情况下,我得到指向这行代码的语法错误:

EXEC SQL BEGIN DECLARE SECTION;
^

这是我的第二次尝试:

BEGIN
    ... everything remains unchanged except this part
    BEGIN DECLARE SECTION;
    const char *stmt = 'INSERT INTO history (field1) VALUES (?)';
    END DECLARE SECTION;        
    PREPARE mystmt FROM :stmt;
    EXECUTE mystmt USING new.field1;
END;

现在,我收到一条指向此行的错误消息:

BEGIN DECLARE SECTION;
^

这是我的第三次尝试:

$BODY$
DECLARE
    ...
    const char *stmt = 'INSERT INTO history (field1) VALUES (?)'
BEGIN
    ...
    PREPARE mystmt FROM :stmt;
    EXECUTE mystmt USING new.field1;
END

现在我收到一条指向此行的错误消息:

const char *stmt = 'INSERT INTO history ...
^

这是我的最后一次尝试:

$BODY$
DECLARE
    ...
    stmt text := 'INSERT INTO history (field1) VALUES (?)'
BEGIN
    ...
    PREPARE mystmt FROM :stmt;
    EXECUTE mystmt USING new.field1;
END

在最后一种情况下,错误消息指向此行:

PREPARE mystmt FROM :stmt;
               ^

那么,我做错了什么以及如何解决?

1 个答案:

答案 0 :(得分:1)

您正在混合使用PL/pgSQL(一种用于在数据库中编写函数的语言)和ecpg,它用于在C客户端代码中嵌入数据库访问。

正确的解决方案如下所示:

INSERT INTO history (field1) VALUES (NEW.field1);