我必须写一个触发器来阻止河流穿过另一条河流。我真的很挣扎,任何帮助都会受到赞赏。 myriver
是包含河流所有信息的表格。因此,如果新河流穿过现有的河流,我会在insert
处遇到错误。这就是我所拥有的:
CREATE FUNCTION river_check() RETURNS TRIGGER AS $river_check$
BEGIN
-- Check that gid is given
IF NEW.gid IS NULL THEN
RAISE EXCEPTION 'river gid cannot be null';
END IF;
NEW.the_geom = (SELECT r.the_geom FROM myriver as r
WHERE ST_CROSSES(NEW.the_geom, r.the_geom));
IF NEW.the_geom THEN
RAISE EXCEPTION 'a river cannot cross another river';
END IF;
RETURN NEW;
END;
$river_check$ LANGUAGE plpgsql;
-- Function river_check is linked to a TRIGGER of same name:
CREATE TRIGGER river_check
BEFORE INSERT OR UPDATE ON myriver
FOR EACH ROW EXECUTE PROCEDURE river_check();
答案 0 :(得分:2)
您正在使用要插入/更新的行(NEW.the_geom
)的列作为临时变量。所以你要么覆盖那个列变量(给新行一个虚假的值),要么在你的IF
检查中得到一个不相关的结果(因为NEW.the_geom
在触发器运行之前还有数据)。
另请注意,Postgres和pl / pgsql是严格类型的,因此您不能在IF
语句中使用任意值来查看它是否为“空”,就像在脚本语言中一样像PHP一样。
您需要添加a DECLARE
block以提供适当的临时变量,并检查它是否为IS NULL
;或者直接使用EXISTS
检查:
IF EXISTS (
SELECT r.the_geom FROM myriver as r
WHERE ST_CROSSES(NEW.the_geom, r.the_geom)
)
THEN
RAISE EXCEPTION 'a river cannot cross another river';
END IF;