【问题标题】:ORACLE Trigger Check Table and delete rowORACLE 触发检查表并删除行
【发布时间】:2014-08-02 02:18:12
【问题描述】:

嘿,我在数据库中创建触发器时遇到了一点问题。

我有一个名为“已定位”的表格,其中包含:

  • 国家
  • 城市
  • 大海
  • 河流

所以 Lake、Sea 和 River 是外键。

我创建了这三个约束:

ALTER TABLE located
ADD CONSTRAINT locatedLake
        FOREIGN KEY (lake)
        REFERENCES Lake(name)
        ON DELETE SET NULL;

ALTER TABLE located
ADD CONSTRAINT locatedRiver
        FOREIGN KEY (river)
        REFERENCES River(name)
        ON DELETE SET NULL;

ALTER TABLE located
ADD CONSTRAINT locatedSea
        FOREIGN KEY (sea)
        REFERENCES Sea(name)
        ON DELETE SET NULL;

所以每次我删除一个湖泊、河流或海洋时,它都会被设置为 NULL。

现在我尝试创建这个触发器:

CREATE OR REPLACE TRIGGER deleteFromLocated
AFTER UPDATE ON located
FOR EACH ROW
BEGIN
        DROP FROM located WHERE sea IS NULL AND river IS NULL AND lake IS NULL;
END;
/

然后我得到一个 MUTATING ERROR。

目标是删除这三项为空的每个元组。

也许有人可以帮助我?

提前致谢

【问题讨论】:

  • 为什么要在触发器中执行此操作?假设您关心性能的生产系统,这将需要三个触发器和一个包(或临时表)或具有多个部分的 11g 复合触发器。这通常是一个糟糕的解决方案。您能否创建一个约束以防止所有三列都为 NULL,然后修改应用程序以在从父表中删除 located 行时删除它?
  • 这是一个讲座我们必须解决的任务。数据库是固定的,需要使用触发器。我们可能会用 3 个触发器来解决这个任务。但是,如果您知道我的意思,这个解决方案有点令人不满意......

标签: sql database oracle triggers mutating-table


【解决方案1】:

首先,FOR EACH ROW 在这里对您没有帮助,因为您没有使用 :new:old 来处理正在更新的特定行。您可以尝试删除FOR EACH ROW。 (抱歉,我现在没有可以测试的环境)

真的,这似乎不是很好地使用触发器。你可以改为:

  • 始终使用DELETE FROM located WHERE sea IS NULL AND river IS NULL AND lake IS NULL; 关注湖、河和海表删除
  • 创建过程 delete_lake 等,从湖表中删除,然后从定位中删除。
  • 实际上,更有效的是,您应该使用这两种方法中的任何一种,但首先删除行 (DELETE FROM located WHERE sea {theSeaBeingDeleted} AND river IS NULL AND lake IS NULL;)。这样一来,您就不会更新您将要删除的一堆行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-27
    • 1970-01-01
    • 1970-01-01
    • 2020-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多