我正在开发音乐收藏数据库项目,我被困在这个TRIGGER代码上。有一个Album表,触发器的任务是检查输入的相册是否已经存在于表中。如果是这样,它应该复制已经存在于专辑的表格中的评级,而不管用户输入的新评级。 (我使用的是Oracle 11g)
我设法获得的触发器是:
CREATE OR REPLACE TRIGGER album_constraints BEFORE INSERT ON Album
DECLARE
a_id int;
a_title varchar(50);
a_duration varchar(6);
a_number_of_tracks int;
a_recorded date;
a_rating int;
BEGIN
SELECT album_id,
album_title,
album_duration,
album_number_of_tracks,
album_recorded,
album_rating
INTO a_id,
a_title,
a_duration,
a_number_of_tracks,
a_recorded,
a_rating
FROM Album
WHERE album_title = new.album_title and
album_duration = new.album_duration and
album_number_of_tracks = new.album_number_of_tracks and
album_recorded = new.album_recorded and
rownum = 1;
IF new.album_title = a_title and
new.album_duration = a_duration and
new.album_number_of_tracks = a_number_of_tracks and
new.album_recorded = a_recorded
THEN
new.album_rating := a_rating;
END IF;
END;
有人可以帮助我实现这个目标吗?我收到多个错误,例如“PL-SQL:Statement ignored”
答案 0 :(得分:0)
实际上,有一种方法可以使用单个表执行您要执行的操作。它只是没有涉及触发器。这是一个代码片段,显示了insert语句:
begin
insert into Album( id, title, duration, number_of_tracks, recorded, rating )
values( v_id, v_title, v_duration, v_number_of_tracks, v_recorded, v_rating );
exception
when DUP_VAL_ON_INDEX then
update Album
set rating = v_rating
where id = v_id;
end;
这假设ID是PK,它类似于ISPN号码,它唯一地标识每个已发布的专辑,而不是顺序值。如果表中不存在相册,则Insert语句将正常执行。如果相册已存在,则Insert语句失败,捕获异常并执行更新。
如果你真的,真的想要使用一个触发器,那么用一个视图在桌子前面创建一个"而不是"触发视图。为避免在应用程序代码中进行任何更改,请将视图Album和表命名为其他内容。 (我的惯例是调用表"专辑_"。尾随下划线告诉我不允许直接访问表,并且没有下划线的视图可以进行所有访问。您可以使用任何约定你当然想要。)
CREATE OR REPLACE TRIGGER album_constraints
instead of INSERT ON Album
for each row
begin
insert into Album_( id, title, duration, number_of_tracks, recorded, rating )
values( :new.id, :new.title, :new.duration, :new.number_of_tracks, :new.recorded, :new.rating );
exception
when DUP_VAL_ON_INDEX then
update Album_
set rating = :new.rating
where id = :new.id;
end;
这是我必须向Sql Server提供帽子提示的地方。它允许"而不是"表格上的触发器通过"传递通过"查看不必要的。