2016-08-09 16 views
0


私はPostgreSQL(およびMysqlも同様)のトリガーで数日間立ち往生します。私はちょうど別のテーブルに新たに充填された行を挿入したい。元のデータは外部フォーム(OpenDataKit)から取得し、「中間」テーブルに移動します。トリガーが作成された後にフォームがデータを送信できない理由を理解できません...手動で挿入すると、トリガーなしですべてのアクションが機能することに注意してください。私が間違っていることを理解する助けに感謝します。
私はPostgreSQL 9.5でテストしていますが、MySQL 5.1と同様の問題があります。 ODK形態が(私はSQLクエリを容易にするためのシリアルIDを作成しているため)FORMULAIRE_NATOBS_REPEAT_LOCに新しい行を挿入するときPostgresql行を挿入するためのトリガー

-- CREATE procedure: 
CREATE OR REPLACE FUNCTION proc_natobs() RETURNS TRIGGER AS 
$BODY$ 
DECLARE 
BEGIN 
INSERT INTO lieu (id_lieu, wgs_lat, wgs_lon, date_obs, geom)  
    SELECT id_loc,"GPS_TEL_LAT", "GPS_TEL_LNG", "DATE_OBS", ST_SetSRID(ST_POINT("GPS_TEL_LNG","GPS_TEL_LAT"), 4326) 
    FROM "FORMULAIRE_NATOBS_REPEAT_LOC", "FORMULAIRE_NATOBS_CORE" 
    WHERE "FORMULAIRE_NATOBS_CORE"."_URI" = "FORMULAIRE_NATOBS_REPEAT_LOC"."_TOP_LEVEL_AURI" 
    AND "FORMULAIRE_NATOBS_REPEAT_LOC".id_loc IN (SELECT max(id_loc) FROM "FORMULAIRE_NATOBS_REPEAT_LOC"); 

INSERT INTO i_lieu_observateurs (id_lieu, id_auteur) 
    SELECT id_loc, CAST("AUTEUR" AS integer) 
    FROM "FORMULAIRE_NATOBS_CORE", "FORMULAIRE_NATOBS_REPEAT_LOC" 
    WHERE "FORMULAIRE_NATOBS_REPEAT_LOC"."_TOP_LEVEL_AURI" = "FORMULAIRE_NATOBS_CORE"."_URI" 
    AND id_loc IN (SELECT max(id_loc) FROM "FORMULAIRE_NATOBS_REPEAT_LOC") 
    UNION 
    SELECT id_loc, CAST("OBSERVATEURS" AS integer) 
    FROM "FORMULAIRE_NATOBS_REPEAT_LOC", "FORMULAIRE_NATOBS_REPEAT_OBSERVATEUR" 
    WHERE "FORMULAIRE_NATOBS_REPEAT_LOC"."_TOP_LEVEL_AURI" = "FORMULAIRE_NATOBS_REPEAT_OBSERVATEUR"."_TOP_LEVEL_AURI" 
    AND id_loc IN (SELECT max(id_loc) FROM "FORMULAIRE_NATOBS_REPEAT_LOC") 
    ; 
END; 
$BODY$ 
LANGUAGE 'plpgsql'; 

-- CREATE the trigger: 
CREATE TRIGGER trigger_natobs AFTER INSERT 
ON "FORMULAIRE_NATOBS_REPEAT_LOC" 
FOR EACH ROW 
EXECUTE PROCEDURE proc_natobs(); 

だから、私に(他の中間のテーブルからの情報と組み合わせる)は、この行を挿入しようトリガの最初のアクションのためのテーブル "lieu"と、2番目のアクションのためのテーブルi_lieu_observation(ダブルプライマリキーで構成されたテーブル)へのポインタです。最初のアクションだけで構成されたトリガーもテストしましたが、どちらも機能しません。トリガーを削除するまで、フォームを送信するAndroidアプリがクラッシュします。
ありがとうございます!

+1

'MAX(id_loc)FROM FORMULAIRE _...'の代わりに、 'new.xxx'を使用してトリガを起動した行を確認する必要があります。 – joop

+0

参照されたすべてのテーブルの定義を質問に追加すると役立ちます。私には、2つの表の間にlieuとi_lieu_observateursの間に1:Nの関係があるように見えます。また、JOIN構文を使用すると確かに役立ちます。 – wildplasser

答えて

1

新しく挿入されたデータにアクセスするには、トリガーで特別なNEW変数を使用する必要があります。したがって、あなたは次のようなものが必要です:

CREATE OR REPLACE FUNCTION proc_natobs() RETURNS TRIGGER AS 
$BODY$ 
DECLARE 
BEGIN 
INSERT INTO lieu (id_lieu, wgs_lat, wgs_lon, date_obs, geom)  
    SELECT new.id_loc,"GPS_TEL_LAT", "GPS_TEL_LNG", "DATE_OBS", ST_SetSRID(ST_POINT("GPS_TEL_LNG","GPS_TEL_LAT"), 4326) 
    FROM "FORMULAIRE_NATOBS_CORE" 
    WHERE "FORMULAIRE_NATOBS_CORE"."_URI" = new."_TOP_LEVEL_AURI"; 

INSERT INTO i_lieu_observateurs (id_lieu, id_auteur) 
    SELECT new.id_loc, CAST("AUTEUR" AS integer) 
    FROM "FORMULAIRE_NATOBS_CORE" 
WHERE new."_TOP_LEVEL_AURI" = "FORMULAIRE_NATOBS_CORE"."_URI" 
    UNION 
    SELECT new.id_loc, CAST("OBSERVATEURS" AS integer) 
    FROM "FORMULAIRE_NATOBS_REPEAT_OBSERVATEUR" 
    WHERE new."_TOP_LEVEL_AURI" = "FORMULAIRE_NATOBS_REPEAT_OBSERVATEUR"."_TOP_LEVEL_AURI"; 
RETURN new; 
END; 
$BODY$ 
LANGUAGE 'plpgsql'; 

-- CREATE the trigger: 
CREATE TRIGGER trigger_natobs AFTER INSERT 
ON "FORMULAIRE_NATOBS_REPEAT_LOC" 
FOR EACH ROW 
EXECUTE PROCEDURE proc_natobs(); 

私はどのフィールドがどのテーブルから来るのかわからないので、上記を完全に正しくすることはできません。 new.id_locを書いたのと同じように、formulaire_natobs_repeat_locテーブルから来るすべてのフィールドにnew.field_nameを入れる必要があります。

HTH

+0

ありがとうございますが、動作しませんでした。しかし、私のコメントを@Paarthに見てください – RemiC

+0

私のコードを編集しました。私は新しいものを忘れてしまった! –

+0

私は、FORMULAIRE_NATOBS_COREとFORMULAIRE_NATOBS_REPEAT_OBSERVATEURは、新しい "TOP_LEVEL_AURI"と同じ値を持っていると思いますか? –

0

この

CREATE OR REPLACE FUNCTION proc_natobs() RETURNS TRIGGER AS 
$BODY$ 

BEGIN 

IF(TG_OP = 'INSERT') THEN 

INSERT INTO lieu (id_lieu, wgs_lat, wgs_lon, date_obs, geom)  
    SELECT id_loc,"GPS_TEL_LAT", "GPS_TEL_LNG", "DATE_OBS", ST_SetSRID(ST_POINT("GPS_TEL_LNG","GPS_TEL_LAT"), 4326) 
    FROM "FORMULAIRE_NATOBS_REPEAT_LOC" loc, "FORMULAIRE_NATOBS_CORE" core 
    WHERE core."_URI" = loc."_TOP_LEVEL_AURI" 
    AND loc.id_loc =new.id_loc; 

INSERT INTO i_lieu_observateurs (id_lieu, id_auteur) 
    SELECT id_loc as id, 
    CAST("AUTEUR" AS integer) as auteur 
    FROM "FORMULAIRE_NATOBS_CORE" core, "FORMULAIRE_NATOBS_REPEAT_LOC" loc 
    WHERE loc."_TOP_LEVEL_AURI" = core."_URI" 
    AND loc.id_loc =new.id_loc; 
    UNION 
    SELECT id_loc as id, 
    CAST("OBSERVATEURS" AS integer) as auteur 
    FROM "FORMULAIRE_NATOBS_REPEAT_LOC" loc, "FORMULAIRE_NATOBS_REPEAT_OBSERVATEUR" obs 
    WHERE loc."_TOP_LEVEL_AURI" = obs."_TOP_LEVEL_AURI" 
    AND loc.id_loc =new.id_loc; 
    END IF; 

    Return new; 
END; 
$BODY$ 
LANGUAGE 'plpgsql'; 

-- CREATE the trigger: 
CREATE TRIGGER trigger_natobs AFTER INSERT 
ON "FORMULAIRE_NATOBS_REPEAT_LOC" 
FOR EACH ROW 
EXECUTE PROCEDURE proc_natobs(); 

を試してみて、それがあなたのために働く願っています。

+0

ありがとう!フォームがODKの "FORMULAIRE_xx"テーブルを満たしているという意味ではうまくいくが、トリガーは何も返さない。テーブル「lieu」と「i_lieu_observateurs」はまだ空です...追加のヒントはありますか? – RemiC

+0

チェックトリガーが有効かどうか。トリガーが有効で、トリガーにエラーがある場合、 '' FORMULAIRE_NATOBS_REPEAT_LOC "'テーブルも満たされません。チェックトリガー。 – Paarth

+0

トリガーがOKの場合は、テーブル "lieu"と "i_lieu_observateurs"のダミーデータを挿入してクエリを挿入してみてください。指定されたテーブルに対して、insertが動作しているかどうか。 – Paarth

関連する問題