删除时触发以避免悬空引用

Trigger on delete to avoid dangling references

我在 Oracle 中执行某些触发器时遇到问题。

我有两种类型 "t_movie" 和 "t_video" 定义为

CREATE TYPE t_movie AS OBJECT( 
name VARCHAR(20),
year INTEGER);

CREATE TYPE t_video AS OBJECT( 
type CHAR,
movie REF t_movie);

而且我还有关联的 tables

CREATE TABLE movies OF t_movie


CREATE TABLE videos OF t_video

如果我从 table 电影中删除一个元组,我将在另一个 table 中有一些元组引用不再存在的对象。我怎样才能避免这种情况?我认为触发器是必要的,但我不知道如何实现它。谁能帮帮我?

谢谢。

编辑:

我试过这样的触发器:

CREATE or REPLACE TRIGGER delete_movie_cascade 
  before delete on movies
  for each row
DECLARE
  movie_ref (REF t_movie);
BEGIN
  movie_ref = ref :old;
  dbms_output.put_line(deref(movie_ref).name);
  DELETE FROM videos WHERE movie = movie_ref;
END;

但是,正如预期的那样,我得到了错误

Error(6,13): PLS-00103: Encountered the symbol "(" when expecting one of the following:     
constant exception <an identifier>    <a double-quoted delimited-identifier> table long 
double ref    char time timestamp interval date binary national character    nchar

改为触发,使用更好的外键进行级联删除。

参考 t_movie 或 t_video table 创建约束,如下所示:

  ALTER TABLE child_table
  ADD CONSTRAINT fk_delete
  FOREIGN KEY (type)
  REFERENCES t_video (type)
  ON DELETE CASCADE;

从现在开始,t_video 上的每次删除都会导致删除子 table 中的关联行。这就是你的目标。

如果您需要更多详细信息,请查看:https://www.techonthenet.com/oracle/foreign_keys/foreign_delete.php

Oracle Objection Developer's documentation 关于防止悬挂引用的讨论:

A REF column may be constrained with a REFERENTIAL constraint similar to the specification for foreign keys.

遗憾的是,文档没有提供实际示例来说明如何做到这一点。 REFERENTIAL 的格式表明它是一个关键字,但结果却是转移注意力。

真正的解决方案是定义一个实际的外键,但改用对象引用。因此,使用您发布的代码,将 videos 的定义更改为:

CREATE TYPE t_video AS OBJECT( 
    type CHAR,
    movie REF t_movie
);
/
CREATE TABLE videos OF t_video (
    foreign key (movie) references movies
)
/

现在,如果您尝试删除被视频引用的电影,Oracle 将抛出 ORA-02292: integrity constraint


触发器永远不是对常规或对象 table 强制执行外键约束的正确解决方案。因为

  1. 在 FOR EACH ROW 触发器中查询引用 table 效率低下,尤其是对于多行删除。外键针对此任务进行了优化。
  2. 由于读提交隔离级别,该操作在多用户环境中不安全。当另一个用户在不同的会话中添加子行时,触发器将传递我们的删除。
  3. 外键约束是标准的。偏离标准是不好的做法,因为它使我们的代码更难维护。
  4. 触发器中强制执行的规则不会出现在数据字典中。这将使我们的同事感到困惑,阻止数据模型的逆向工程,并使优化器无法获得一些有用的信息来得出有效的执行计划。