繁体   English   中英

PostgreSQL触发器插入行

[英]Postgresql Trigger to insert rows


我被Postgresql(以及Mysql)上的触发器困扰了好几天。 我只想将新填充的行插入另一个表。 原始数据来自外部表单(OpenDataKit),并进入“中间”表。 我不明白为什么一旦创建触发器,表单就无法再发送数据了。请注意,当我手动进行插入操作时,所有操作都无需触发器即可工作。 我将不胜感激一些帮助,以了解我在做什么错。
我现在正在使用Postgresql 9.5进行测试,但是MySQL 5.1遇到了类似的问题。

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

因此,当ODK表单在FORMULAIRE_NATOBS_REPEAT_LOC中插入新行(为此我创建了一个序列ID以便进行SQL查询)时,我会尝试将该行(与其他中间表的信息一起)插入表“ lieu”中,作为第一个触发器的动作,并进入第二个动作的表i_lieu_observation(由双主键组成)。 我还使用仅由第一个动作组成的触发器进行了测试,但是它也不起作用。 发送表单的Android应用程序崩溃,直到删除触发器为止。
提前致谢!

您需要在触发器中使用特殊的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。

高温超导

尝试这个

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

希望它为您工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM