2016-08-09 9 views
0


Ich bin seit Tagen mit Triggern auf PostgreSQL (und Mysql sowie fest). Ich möchte nur neu gefüllte Zeilen in eine andere Tabelle einfügen. Die Originaldaten stammen von einem externen Formular (OpenDataKit) und gehen zu "Zwischen" -Tabellen. Ich kann nicht verstehen, warum das Formular die Daten nicht mehr senden kann, sobald der Auslöser erstellt wurde ... Beachten Sie, dass alle Aktionen ohne den Auslöser funktionieren, wenn ich die Einfügungen von Hand mache. Ich wäre sehr dankbar für einige Hilfe, um zu verstehen, was ich falsch mache.
Ich teste jetzt mit Postgresql 9.5, aber ich habe ein ähnliches Problem mit MySQL 5.1.Postgresql Trigger zum Einfügen von Zeilen

-- 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(); 

Also, wenn die ODK Form neue Zeilen in FORMULAIRE_NATOBS_REPEAT_LOC Einsätze (für die ich eine serielle ID erstellt haben, die SQL-Abfragen zu erleichtern), versuche ich diese Zeile einzufügen (in Kombination mit Informationen aus anderen Zwischen Tabellen) in Tabelle "lieu" für die erste Aktion des Triggers und in Tabelle i_lieu_observation (bestehend aus einem doppelten Primärschlüssel) für die zweite Aktion. Ich habe auch mit einem Trigger getestet, der nur aus der ersten Aktion besteht, funktioniert aber auch nicht. Die Android-App, die das Formular sendet, stürzt ab, bis ich den Auslöser entferne.
Vielen Dank im Voraus!

+1

Anstatt 'MAX (id_loc) FROM FORMULAIRE _...' zu verwenden, sollten Sie 'new.xxx' verwenden, um nach der Zeile zu suchen, die den Trigger ausgelöst hat. – joop

+0

Es würde helfen, wenn Sie die Definitionen für alle referenzierten Tabellen zu der Frage hinzugefügt haben. Für mich sieht es so aus, als gäbe es eine 1: N Beziehung zwischen den beiden Tabellen lieu und i_lieu_observateurs. Und es würde sicherlich helfen, wenn Sie JOIN-Syntax verwenden würden. – wildplasser

Antwort

1

Sie müssen die spezielle NEW-Variable im Trigger verwenden, um auf die neu eingefügten Daten zuzugreifen. Sie müssen also so etwas wie:

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(); 

Weil ich weiß nicht, welche aus welchen Tabellen kommen Feldern kann ich nicht die oben völlig richtig machen. Genauso wie ich new.id_loc geschrieben habe, müssen Sie new.field_name für alle Felder aus der Tabelle formulaire_natobs_repeat_loc eingeben.

HTH

+0

Danke, aber es hat nicht funktioniert. Aber siehe meinen Kommentar zu @Paarth – RemiC

+0

Ich habe gerade meinen Code bearbeitet. Ich habe vergessen, neu zu kommen! –

+0

Ich nehme an, dass FORMULAIRE_NATOBS_CORE und FORMULAIRE_NATOBS_REPEAT_OBSERVATEUR Werte haben, die dem neuen entsprechen. "TOP_LEVEL_AURI"? –

0

Try this

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(); 

es Hoffnung für Sie arbeiten.

+0

Danke! Es geht besser in dem Sinne, dass das Formular jetzt die "FORMULAIRE_xx" -Tabellen des ODK füllt, aber der Trigger gibt nichts zurück. Tabellen "lieu" und "i_lieu_observateurs" sind noch leer ... Haben Sie noch weitere Tipps? – RemiC

+0

Check Trigger ist aktiviert oder nicht. Wenn der Trigger aktiviert ist und ein Triggerfehler auftritt, wird die Tabelle "FORMULAIRE_NATOBS_REPEAT_LOC" ebenfalls nicht gefüllt. Trigger prüfen. – Paarth

+0

Wenn der Trigger in Ordnung ist, versuchen Sie, eine Abfrage mit einigen Dummy-Daten für die Tabellen "lieu" und "i_lieu_observateurs" einzufügen. Funktioniert der Einsatz für bestimmte Tabellen? – Paarth

Verwandte Themen