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

时间:2017-05-19 14:06:56

标签: postgresql variables triggers plpgsql postgresql-9.5

我正在使用PostgreSQL 9.5。

我在PL / pgSQL中创建一个触发器,当在第二个表(synthese_poly)上执行INSERT时,会向表(operation_poly)添加记录,与其他表数据。

触发器效果很好,除了一些未填充的变量(特别是我尝试填充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表中的相应字段。)

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

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

2 个答案:

答案 0 :(得分:2)

使用array_agg

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

string_agg(DISTINCT oper.operateurs,'; ')

您可以使用顺序对agregate中的文字进行排序

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

答案 1 :(得分:1)

我有根据的猜测:你有BEFORE INSERT ON bdtravaux.operation_poly的触发器。 operation_idserial PK列。

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

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触发器。

整个功能可能更简单,可以通过单个查询完成。