在 plpgsql 触发器函数中用 "array_to_string" 填充变量

Fill a variable with "array_to_string" in a plpgsql trigger function

我正在使用 PostgreSQL 9.5。

我正在 PL/pgSQL 中创建一个触发器,它在 table (synthese_poly) 中添加一条记录,当 INSERT 在第二个 table (operation_poly),与其他 tables 数据。

触发器运行良好,除了一些未填充的变量(尤其是我尝试使用 array_to_string() 函数填充的变量)。

这是代码:

-- Function: bdtravaux.totablesynth_fn()
-- DROP FUNCTION bdtravaux.totablesynth_fn();

CREATE OR REPLACE FUNCTION bdtravaux.totablesynth_fn()
  RETURNS trigger AS
$BODY$

 DECLARE 
    varoperateur varchar;
    varchantvol boolean;

BEGIN
IF (TG_OP = 'INSERT') THEN
varsortie_id := NEW.sortie;
varopeid := NEW.operation_id;

--The following « SELECT » queries take data in third-party tables and fill variables, which will be used in the final insertion query.

SELECT array_to_string(array_agg(DISTINCT oper.operateurs),'; ')
INTO varoperateur
FROM bdtravaux.join_operateurs oper INNER JOIN bdtravaux.operation_poly o ON (oper.id_joinop=o.id_oper) 
WHERE o.operation_id = varopeid;

SELECT CASE WHEN o.ope_chvol = 0 THEN 'f' ELSE 't' END as opechvol INTO varchantvol 
FROM bdtravaux.operation_poly o WHERE o.operation_id = varopeid;

-- «INSERT» query
INSERT INTO bdtravaux.synthese_poly (soperateur, schantvol)  SELECT  varoperateur, varchantvol;

RAISE NOTICE  'varoperateur value : (%)', varoperateur;
RAISE NOTICE  'varchantvol value : (%)', varchantvol;

END IF;
RETURN NEW;
END;

$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION bdtravaux.totablesynth_fn()
  OWNER TO postgres;

这就是触发器:

-- Trigger: totablesynth on bdtravaux.operation_poly
-- DROP TRIGGER totablesynth ON bdtravaux.operation_poly;

CREATE TRIGGER totablesynth
  AFTER INSERT
  ON bdtravaux.operation_poly
  FOR EACH ROW
  WHEN ((new.chantfini = true))
  EXECUTE PROCEDURE bdtravaux.totablesynth_fn();

varchantvol 变量已正确填充,但 varoperateur 仍然空无一物(NULL 值)(synthese_poly table 中的相应字段以此类推) .

注:
SELECT array_to_string(…) ... 查询本身(使用 pgAdmin 启动,没有 INTO varoperateur 并用值替换 varopeid)运行良好,returns 一个字符串。

我尝试更改 array_to_string() 函数和变量的数据类型(使用 ::varchar::text …),没有任何效果。 你知道会发生什么吗?

我有根据的猜测:你有一个触发器 BEFORE INSERT ON bdtravaux.operation_poly。而operation_id就是它的serialPK栏目。

在这种情况下,带有 WHERE o.operation_id = varopeid 的查询 (其中 varopeid 已填充 NEW.operation_id)永远找不到任何行,因为该行不在 table 中。

array_agg()在此没有任何作用。

可以使用触发器 AFTER INSERT ON bdtravaux.operation_poly。但是如果 id_oper 来自同一个插入行,你可以简化为:

SELECT array_to_string(array_agg(DISTINCT oper.operateurs),'; ')
INTO   varoperateur
FROM   bdtravaux.join_operateurs oper
WHERE  oper.id_joinop = NEW.id_oper;

并保留 BEFORE 触发器。

整个功能可能会更简单,一个查询就可以完成。

使用array_agg

您可以将 array_to_string(array_agg(DISTINCT oper.operateurs),'; ') 替换为

string_agg(DISTINCT oper.operateurs,'; ')

您可以使用 order by 对聚合中的文本进行排序

string_agg(DISTINCT oper.operateurs,'; ' ORDER BY oper.operateurs)