我在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);
我还有关联的表
CREATE TABLE movies OF t_movie
CREATE TABLE videos OF t_video
如果我从电影表中删除一个元组,那么我将在另一个表中有一些元组,其中引用了不再存在的对象。如何避免这种情况?我认为触发器是必要的,但我不知道如何实现。谁能帮我吗?
谢谢。
编辑:
我尝试过这样的触发器:
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
答案 0 :(得分:1)
Oracle Objection Developer's documentation谈论防止悬挂裁判:
REF
列可能受REFERENTIAL
约束的约束,类似于对外键的规范。
不幸的是,文档没有提供有关此操作的实际示例。 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
投掷。
触发器永远不是在常规表或对象表上强制外键约束的正确解决方案。因为
答案 1 :(得分:0)
请改为使用更好的外键进行级联删除。
参照如下的t_movie或t_video表创建约束:
ALTER TABLE child_table
ADD CONSTRAINT fk_delete
FOREIGN KEY (type)
REFERENCES t_video (type)
ON DELETE CASCADE;
从现在开始,对t_video的每次删除都会导致删除子表中的关联行。这就是你的目标。
如果您需要更多详细信息,请查看:https://www.techonthenet.com/oracle/foreign_keys/foreign_delete.php