簡體   English   中英

在觸發器內執行動態准備語句

[英]Execute dynamic prepared statement inside a trigger

我想將觸發器用於記錄目的-每次用戶插入內容或進行更新時, 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;
               ^

那么,我在做什么錯,我該如何解決?

您正在將PL / pgSQL (一種用於在數據庫中編寫函數的語言)和ecpg (一種用於將數據庫訪問嵌入到C客戶端代碼中)混合在一起。

正確的解決方案如下所示:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM