Postgres触发函数:在插入或更新之前替换值

时间:2018-01-03 13:15:00

标签: postgresql function syntax triggers plpgsql

我几乎查阅了关于这个问题的所有内容,但我仍然不明白这个触发器有什么问题:

CREATE OR REPLACE FUNCTION func_SubstitutePostLatLng_Upt()
RETURNS trigger AS
$BODY$
BEGIN
    IF OLD.post_latlng IS NULL AND NEW.post_latlng IS NULL AND NEW.place_guid IS NOT NULL THEN
    raise notice 'SELECT';
    SELECT place.geom_center, place.city_guid 
            INTO NEW.post_latlng, NEW.city_guid 
    FROM public.place 
    WHERE (place.origin_id, place.place_guid) IN (VALUES (NEW.origin_id,NEW.place_guid));
    raise notice 'Value db_geom: %', NEW.post_latlng;
    raise notice 'Value db_city_guid: %', NEW.city_guid;
    IF NEW.post_latlng IS NOT NULL THEN
            NEW.post_geoaccuracy = 'place';
            IF NEW.city_guid IS NOT NULL THEN
                SELECT country_guid INTO NEW.country_guid
                FROM public.city WHERE (origin_id, city_guid) IN (VALUES (NEW.origin_id,NEW.city_guid));
            END IF;            
    END IF;
    END IF;   
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

DROP TRIGGER IF EXISTS trig_SubstitutePostLatLng_Upd on public.post;
CREATE TRIGGER trig_SubstitutePostLatLng_Upd
BEFORE UPDATE
ON public.post
FOR EACH ROW
WHEN (pg_trigger_depth() < 1)
EXECUTE PROCEDURE func_SubstitutePostLatLng_Upt()

(我有第二个类似的插入触发器)

代码应该执行以下操作: 在表“post”上更新时,检查是否没有提交post_latlng(= NULL),如果是,则从表位(geom_center)替换post_latlng(如果可用)。

但是,无论我做什么,我在更新表格“post”中的条目时会得到以下内容(=触发上述触发器):

NOTICE:  SELECT 
NOTICE:  Value db_geom: <NULL> 
NOTICE:  Value db_city_guid: <NULL> 
INSERT 0 1

Query returned successfully in 47 msec.

place_guid,geom_center等的测试数据绝对可用且两者兼而有之        raise notice 'Value db_geom: %', NEW.post_latlng;        raise notice 'Value db_city_guid: %', NEW.city_guid; 不应该输出NULL。

1 个答案:

答案 0 :(得分:0)

有几个较小的问题,它现在有效。这是一个更清晰的代码,它使用两者之间的变量:

CREATE OR REPLACE FUNCTION func_SubstitutePostLatLng_Upt()
RETURNS trigger AS
$BODY$
DECLARE
    db_geom_center text;
    db_city_guid text;
    db_country_guid text;
BEGIN
    IF OLD.post_latlng IS NULL AND NEW.post_latlng IS NULL AND NEW.place_guid IS NOT NULL THEN
        SELECT place.geom_center, place.city_guid 
                INTO db_geom_center, db_city_guid
        FROM public.place 
        WHERE (place.origin_id, place.place_guid) IN (VALUES (NEW.origin_id,NEW.place_guid));
        IF db_geom_center IS NOT NULL THEN
                NEW.post_latlng = db_geom_center;
                NEW.post_geoaccuracy = 'place';
        END IF;
        IF db_city_guid IS NOT NULL THEN
            NEW.city_guid = db_city_guid;
            SELECT city.country_guid 
                INTO db_country_guid
            FROM public.city
            WHERE (city.origin_id, city.city_guid) IN (VALUES (NEW.origin_id,db_city_guid));
            NEW.country_guid = db_country_guid;
        END IF;            
    END IF;   
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;