我有一張名為 movie_cast 的表。
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.
這個表已經有重復的值(#114)。act_id, mov_id是外鍵。我已經在名為 trg1 的 movie_cast 表上創建了一個觸發器。
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')
我的任務是:我想允許這個表中的條目,即;一個演員可以拍不止一部電影(act_id 可以是重復的/重復的),但我不能為同一部電影演員兩次。有人可以在這里幫助我嗎?我已經厭倦了過去 2 天的這個問題!謝謝!
uj5u.com熱心網友回復:
您收到ORA-040 mutating錯誤是因為您的觸發器參考了它觸發的表。在 Oracle 中,您基本上不能這樣做。處理此問題的正確方法是創建唯一常量,然后在例外發生時攔截并處理例外,無論是在 plsql 程序中還是在應用程式錯誤處理中。見演示。
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.
uj5u.com熱心網友回復:
正如評論者所提到的,觸發器不是防止重復的正確工具。您需要多列的唯一約束。
ALTER TABLE movie_cast ADD CONSTRAINT uk_movie_cast_actor UNIQUE (mov_id, act_id);
這將允許重復的 MOV_ID 和 ACT_ID,但不允許重復的 MOV_ID ACT_ID 組合。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/389872.html
上一篇:如何洗掉列中兩行之間的空格
