ORA-24344: 编译错误成功 - 触发 APEX
Posted
技术标签:
【中文标题】ORA-24344: 编译错误成功 - 触发 APEX【英文标题】:ORA-24344: success with compilation error - Trigger APEX 【发布时间】:2016-05-23 13:48:42 【问题描述】:我一直在处理这个触发器,当我运行脚本时,它会告诉我之前的错误消息。我似乎无法弄清楚为什么它不能正确编译,每个 pl/sql 触发器教程似乎都有我的触发器的结构。代码如下:
create
or replace trigger new_artist before insert
on
Artist referencing new as nvartist declare counter number;
begin select
count( * ) into
counter
from
Performer
where
Stage_name = nvartist.Stage_name;
if counter > 0 then signal sqlstate '45000';
else insert
into
Artist
values(
nvartist.Stage_name,
nvartist.Name
);
insert
into
Performer
values(nvartist.Stage_name);
end if;
end;
它检查新艺术家是否已经存在于它的超类型(Performer)中,如果确实存在,它会给出错误,如果它不插入艺术家(Stage_name varchar2,Name varchar2)和Performer(Stage_name)。 Performer 的另一个子类型(与 Artist 同级)是 Band(Stage_name),它又与 Artist 有关系。为什么编译器会因为这个触发器对我大喊大叫?
提前致谢
【问题讨论】:
当您尝试在同一个基础表中插入数据时,由于发生变异触发器错误,它应该在运行时无论如何都会失败 我读到过,我知道如果触发器与插入/更新的行混淆,如果它直接或间接删除触发器内的该行,则触发器将失败,我不认为它是案子。我的目标是在插入 Artist 之前检查 Stage_name 是否已经存在于 Performer 中。如果它确实存在(因为它们是不相交的 isa(Performer ISA Artist/Band)),它会给出错误,但如果它不存在,它会同时插入 Artist 和 Performer。我认为这会实现。 Oracle´ 中没有 SIGNAL 命令。这是mysql。此触发器不会编译。而不是 Signal 使用 raise_application_error。您不能在同一个表中插入,也不需要。删除“插入艺术家”命令。这将自动完成。 【参考方案1】:您可能想尝试这种变体(我稍微修改了您的表格名称)。 使用示例数据创建表:
CREATE table test_artist(
stage_name varchar2(100)
, name varchar2(100)
);
create table test_performer(
stage_name varchar2(100)
);
/*inserting test performer on which trigger will rise an error*/
insert into test_performer
select 'performer_1' from dual;
创建触发器:
create or replace trigger new_artist
before insert
on TEST_ARTIST
referencing new as nvartist
for each row
declare
counter number;
begin
select count(*)
into counter
from test_performer
where Stage_name = :nvartist.Stage_name;
if counter > 0 then
--signal sqlstate '45000' ;
raise_application_error( -20001, 'No insertion with existing Performer');
else
/*you cant update the same table, in other case you'll get
ora-04091 table mutating error.
But nevertheless this values will be inserted by sql triggered this trigger.*/
--insert into test_artist values(:nvartist.Stage_name, :nvartist.Name);
insert into test_performer values(:nvartist.Stage_name);
end if;
end new_artist;
之后此插入将起作用,因为'test_performer'表中没有'performer_2':
insert into test_artist
select 'performer_2', 'name_2' from dual;
这将失败:
insert into test_artist
select 'performer_1', 'name_1' from dual;
【讨论】:
感谢您的深入回答。我怀疑表发生了变异,但我不确定插入到 Artist 中是否仍然会发生。这里的“每一行”不是多余的吗?由于计数器将填充计数查询,我还需要检查每一行吗? 嗨,@朋克! “FOR EACH ROW 选项确定触发器是行触发器还是语句触发器。”您可以将每条语句插入许多行到“艺术家”表中,因此您似乎必须对每一特定行进行执行者存在检查。另一个:表级触发器中不允许使用 NEW 或 OLD 引用。以上是关于ORA-24344: 编译错误成功 - 触发 APEX的主要内容,如果未能解决你的问题,请参考以下文章
尝试创建一个触发器来跟踪用户对表所做的更改但不断收到错误 ORA-24344:编译错误成功