PostgreSQL:检查触发器函数中的 NEW 和 OLD

PostgreSQL: Checking for NEW and OLD in a function for a trigger

我想创建一个触发器来计算行数并更新另一个 table 中的字段。我当前的解决方案适用于 INSERT 语句,但在我删除一行时失败。

我当前的功能:

 CREATE OR REPLACE FUNCTION update_table_count()
RETURNS trigger AS
$$
DECLARE updatecount INT;
  BEGIN
      Select count(*) into updatecount 
        From source_table 
       Where id = new.id;
      Update dest_table set count=updatecount 
       Where id = new.id;
RETURN NEW;
END;
$$
LANGUAGE 'plpgsql';

触发器是一个非常基本的触发器,看起来像。

CREATE TRIGGER count_trigger
AFTER INSERT OR DELETE
ON source_table
FOR EACH ROW
EXECUTE PROCEDURE update_table_count();

当我执行 DELETE 语句时,出现以下错误:

ERROR: record "new" is not assigned yet

DETAIL: The tuple structure of a not-yet-assigned record is indeterminate.

我知道一种解决方案是只为 DELETE 创建一组触发器和函数,为 INSERT 语句创建一组。但我想做得更优雅一点,想知道是否有解决方案来检查当前上下文中是否存在 NEW 或 OLD,并只实现一个 IF ELSE 块。但是我不知道如何检查这个上下文相关的项目。

感谢您的帮助

根据触发器的触发方式使触发器函数执行不同操作的通常方法是通过 TG_OP

检查触发器操作
CREATE OR REPLACE FUNCTION update_table_count()
RETURNS trigger AS
$$
DECLARE 
  updatecount INT;
BEGIN
  if tg_op = 'UPDATE' then 
    select count(*) into updatecount from source_table where id = new.id;
    update dest_table set count=updatecount where id = new.id;
  elsif tg_op = 'DELETE' then 
    ... do something else
  end if;
  RETURN NEW;
END;
$$
LANGUAGE plpgsql;

无关,但是:语言名称是一个标识符。不要使用单引号引用它。

来自PostgreSQL's documentation

Data type RECORD; variable holding the new database row for INSERT/UPDATE operations in row-level triggers. This variable is null in statement-level triggers and for DELETE operations.

Data type RECORD; variable holding the old database row for UPDATE/DELETE operations in row-level triggers. This variable is null in statement-level triggers and for INSERT operations.

因此,例如,如果 NEW 为 NULL,则在 DELETE 时调用触发器。