这主要是一个风格问题。
我有一个AFTER INSERT或UPDATE触发器。我想针对可用的新/旧记录中的任何一个运行相同查询。而不是让条件检查TG_OP并复制查询,有什么最简单的方法来确定哪些可用并循环它们?
示例代码:
CREATE FUNCTION myfunc() RETURNS TRIGGER AS $$
DECLARE
id int;
ids int[];
BEGIN
IF TG_OP IN ('INSERT', 'UPDATE') THEN
ids := ids || NEW.id;
END IF;
IF TG_OP IN ('UPDATE', 'DELETE') THEN
ids := ids || OLD.id;
END IF;
FOREACH id IN ARRAY ARRAY(SELECT DISTINCT UNNEST(ids))
LOOP
RAISE NOTICE 'myfunc called for % on id %', TG_OP, id;
/* RUN QUERY REFERENCING id */
END LOOP;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
是否有更短/更简单/更惯用的方法来实现这一目标?
答案 0 :(得分:1)
数组处理和单独的SELECT DISTINCT
似乎对于这项工作而言过于昂贵。这应该更便宜:
CREATE FUNCTION myfunc()
RETURNS TRIGGER AS
$func$
DECLARE
_id int;
BEGIN
CASE TG_OP
WHEN 'INSERT', 'UPDATE' THEN
_id := NEW.id;
WHEN 'DELETE' THEN
_id := OLD.id;
END CASE;
FOR i IN 1..2 -- max 2 iterations
LOOP
RAISE NOTICE 'myfunc called for % on id %', TG_OP, _id;
/* RUN QUERY REFERENCING _id */
EXIT WHEN TG_OP <> 'UPDATE' OR i = 2; -- only continue in 1st round for UPDATE
EXIT WHEN _id = OLD.id; -- only continue for different value
_id := OLD.id;
END LOOP;
RETURN NULL;
END
$func$ LANGUAGE plpgsql;
相关:
但我可能只是写一个单独的触发功能&amp;触发每个DML语句。而不是一个非常简单和快速的功能,而不是一个通用但复杂和较慢的功能。