触发器创建但执行时显示一些错误==> ORA-04091:, ORA-06512:, ORA-04088:
trigger created but when executed showing some errors==> ORA-04091:, ORA-06512:, ORA-04088:
我有一个名为 movie_cast 的 table。
SQL> select * from movie_cast;
ACT_ID MOV_ID ROLE
---------- ---------- --------------------------------------------------
101 901 John Scottie Ferguson
102 902 Miss Giddens
103 903 T. E. Lawrence
104 904 Michael
105 905 Antonio Salieri
106 906 Rick Deckard
107 907 Alice Harford
108 908 McManus
109 909 J. J. Gittes
110 910 Eddie Adams
111 911 Alvy Singer
112 912 San
113 913 Adny Dufresne
114 914 Lester Burnham
115 915 Rose DeWitt Bukater
116 916 Sean Maguire
117 917 Ed
118 918 Renton
119 919 Alfred Borden
120 920 Elizabeth Darko
121 921 Older Jamal
122 922 Ripley
114 923 Bobby Darin
23 rows selected.
这个table已经有重复值(#114)。 act_id, mov_id
是外键。我在 movie_cast table 上创建了一个名为 trg1.
的触发器
SQL> CREATE OR REPLACE TRIGGER trg1
2 after INSERT ON MOVIE_CAST
3 FOR EACH ROW
4 DECLARE
5 num NUMBER;
6 BEGIN
7 SELECT COUNT(act_ID)
8 INTO num
9 FROM movie_cast
10 WHERE mov_ID=:NEW.mov_ID;
11 if(num >= 1) then
12 dbms_output.put_line('Already cast assigned,same Actors cant cast more than once');
13 end if;
14 END;
15 /
Trigger created.
虽然创建了触发器,但执行后出现一些错误
(SQL> insert into movie_cast values(124, 921, 'abc');
insert into movie_cast values(124, 921, 'abc')
*
ERROR at line 1:
ORA-04091: table PROJECT_MOVIE_DATA.MOVIE_CAST is mutating, trigger/function may not see it
ORA-06512: at "PROJECT_MOVIE_DATA.TRG1", line 4
ORA-04088: error during execution of trigger 'PROJECT_MOVIE_DATA.TRG1')
我的任务是:我想允许在此 table 中输入,即;一个演员可以拍不止一部电影(act_id 可以是 repetitive/duplicate),但我不能为同一部电影选派同一个演员两次。
有人可以帮我吗?
我受够了过去两天的这个问题!
谢谢!
正如评论者所提到的,触发器不是防止重复的正确工具。您想要多列的唯一约束。
ALTER TABLE movie_cast ADD CONSTRAINT uk_movie_cast_actor UNIQUE (mov_id, act_id);
这将允许重复 MOV_ID 和 ACT_IDs,但不允许 MOV_ID + ACT_ID.
的重复组合
您收到 ORA-040 mutating
错误,因为您的触发器引用了它触发的 table。在 Oracle 中,您基本上不能这样做。处理此问题的正确方法是创建唯一常量,然后在异常发生时拦截并处理异常,无论是在 plsql 过程中还是在应用程序错误处理中。参见 demo。
create or replace
procedure generate_actor_movie_role(
actor_id_in movie_cast.act_id%type
, movie_id_in movie_cast.mov_id%type
, role_in movie_cast.role%type
)
is
begin
insert into movie_cast (act_id, mov_id, role)
values ( actor_id_in, movie_id_in, role_in);
exception
when dup_val_on_index then
begin
log_error( 'generate_actor_movie_role'
, dbms_utility.format_error_stack
);
raise_application_error ( -20001, 'Already cast assigned,same Actors cant cast more than once');
end ;
end generate_actor_movie_role;
注意:使用 dbms_output 实际上是没有用的,至少在生产环境中是这样,因为它从未见过。它实际上也将异常转换为自定义错误,但仍然作为异常。该演示还包含极简错误记录程序。
请注意@stickybit 的提交,因为演员在给定的电影中扮演多个角色。也许你的约束应该包括 role
.
我有一个名为 movie_cast 的 table。
SQL> select * from movie_cast;
ACT_ID MOV_ID ROLE
---------- ---------- --------------------------------------------------
101 901 John Scottie Ferguson
102 902 Miss Giddens
103 903 T. E. Lawrence
104 904 Michael
105 905 Antonio Salieri
106 906 Rick Deckard
107 907 Alice Harford
108 908 McManus
109 909 J. J. Gittes
110 910 Eddie Adams
111 911 Alvy Singer
112 912 San
113 913 Adny Dufresne
114 914 Lester Burnham
115 915 Rose DeWitt Bukater
116 916 Sean Maguire
117 917 Ed
118 918 Renton
119 919 Alfred Borden
120 920 Elizabeth Darko
121 921 Older Jamal
122 922 Ripley
114 923 Bobby Darin
23 rows selected.
这个table已经有重复值(#114)。 act_id, mov_id
是外键。我在 movie_cast table 上创建了一个名为 trg1.
SQL> CREATE OR REPLACE TRIGGER trg1
2 after INSERT ON MOVIE_CAST
3 FOR EACH ROW
4 DECLARE
5 num NUMBER;
6 BEGIN
7 SELECT COUNT(act_ID)
8 INTO num
9 FROM movie_cast
10 WHERE mov_ID=:NEW.mov_ID;
11 if(num >= 1) then
12 dbms_output.put_line('Already cast assigned,same Actors cant cast more than once');
13 end if;
14 END;
15 /
Trigger created.
虽然创建了触发器,但执行后出现一些错误
(SQL> insert into movie_cast values(124, 921, 'abc');
insert into movie_cast values(124, 921, 'abc')
*
ERROR at line 1:
ORA-04091: table PROJECT_MOVIE_DATA.MOVIE_CAST is mutating, trigger/function may not see it
ORA-06512: at "PROJECT_MOVIE_DATA.TRG1", line 4
ORA-04088: error during execution of trigger 'PROJECT_MOVIE_DATA.TRG1')
我的任务是:我想允许在此 table 中输入,即;一个演员可以拍不止一部电影(act_id 可以是 repetitive/duplicate),但我不能为同一部电影选派同一个演员两次。 有人可以帮我吗? 我受够了过去两天的这个问题! 谢谢!
正如评论者所提到的,触发器不是防止重复的正确工具。您想要多列的唯一约束。
ALTER TABLE movie_cast ADD CONSTRAINT uk_movie_cast_actor UNIQUE (mov_id, act_id);
这将允许重复 MOV_ID 和 ACT_IDs,但不允许 MOV_ID + ACT_ID.
的重复组合您收到 ORA-040 mutating
错误,因为您的触发器引用了它触发的 table。在 Oracle 中,您基本上不能这样做。处理此问题的正确方法是创建唯一常量,然后在异常发生时拦截并处理异常,无论是在 plsql 过程中还是在应用程序错误处理中。参见 demo。
create or replace
procedure generate_actor_movie_role(
actor_id_in movie_cast.act_id%type
, movie_id_in movie_cast.mov_id%type
, role_in movie_cast.role%type
)
is
begin
insert into movie_cast (act_id, mov_id, role)
values ( actor_id_in, movie_id_in, role_in);
exception
when dup_val_on_index then
begin
log_error( 'generate_actor_movie_role'
, dbms_utility.format_error_stack
);
raise_application_error ( -20001, 'Already cast assigned,same Actors cant cast more than once');
end ;
end generate_actor_movie_role;
注意:使用 dbms_output 实际上是没有用的,至少在生产环境中是这样,因为它从未见过。它实际上也将异常转换为自定义错误,但仍然作为异常。该演示还包含极简错误记录程序。
请注意@stickybit 的提交,因为演员在给定的电影中扮演多个角色。也许你的约束应该包括 role
.