2017-05-19 37 views
0

我正在使用PostgreSQL 9.5。在plpgsql触发器函数中用“array_to_string”填充变量

我在PL/pgSQL中创建一个触发器,当在第二个表(operation_poly)上执行INSERT与其他表数据时,表中会添加一条记录(synthese_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 ...),没有任何工作。 你看到会发生什么?

+0

触发功能的文本排序结合实际的***触发器***,这是缺少的。 –

+0

谢谢你的建议。我添加了触发器。 –

回答

1

我的猜测:你有BEFORE INSERT ON bdtravaux.operation_poly触发。而operation_id是其serial 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触发。

整个功能可能更简单,大概可以用一个查询来完成。

+0

谢谢你的回答。不幸的是,我的触发器是“后触发器”(我最初没有发布它)。 由于你的建议,我现在要简化我的代码,然后我会继续寻找我的空变量。 –

+0

非常感谢。这实际上是一个“时间”问题,但在我的Python程序中。 它填充了“operation_poly”表,然后启动触发器并填充其他表。所以,当触发器启动时,其他表仍然是空的。对不起,噪音。 : - | –

1

使用array_agg

您可以

string_agg(DISTINCT oper.operateurs,'; ') 

取代array_to_string(array_agg(DISTINCT oper.operateurs),'; '),您可以通过使用为了在agregate需要考虑

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

啊,是的,string_agg ...我听说过il,但还没有使用。谢谢。 –