【问题标题】:PL/pgSQL trigger to stop a river crossing another riverPL/pgSQL 触发器阻止一条河流穿过另一条河流
【发布时间】:2015-07-14 06:26:18
【问题描述】:

我必须编写一个触发器来阻止一条河流穿过另一条河流。我真的很挣扎,任何帮助将不胜感激。 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();

【问题讨论】:

    标签: sql postgresql postgis plpgsql spatial


    【解决方案1】:

    您正在使用要插入/更新行 (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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-25
      • 1970-01-01
      • 2012-02-19
      • 1970-01-01
      • 1970-01-01
      • 2014-03-12
      • 2014-09-21
      • 2017-11-22
      相关资源
      最近更新 更多