2017-05-19 40 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,但還沒有使用。謝謝。 –