一些反对意见:
- 您不需要第一个(插入前)触发器
-
new 和 old 值前面应该有冒号,即 :new 和 :old
- PL/SQL 中没有
set 命令(至少,我对此一无所知)。如果你想设置一个变量到某个值,你可以使用my_variable := :new.rate_star;
- 我没用过
delimiter;不知道你打算用它做什么。标准分隔符是分号和斜线,我建议你使用它们
这就是我会如何做你想做的事。
表格优先:
SQL> create table fanrating
2 (mov_id number(10),
3 rate_avg number,
4 rate_sum number,
5 rate_count number
6 );
Table created.
SQL> create table rating
2 (mov_id number(10),
3 userid varchar(20),
4 rev_star number,
5 primary key(mov_id,rev_star)
6 );
Table created.
触发器使用merge 命令,它也被称为“upsert”,因为它使用update(如果有匹配,我会这样做)或insert(如果没有匹配):
SQL> create or replace trigger ai_rating_trg
2 after insert on rating
3 for each row
4 begin
5 merge into fanrating f
6 using (select :new.rev_star rev_star,
7 :new.mov_id mov_id
8 from dual
9 ) x
10 on (f.mov_id = x.mov_id)
11 when matched then update set
12 f.rate_sum = f.rate_sum + :new.rev_star,
13 f.rate_count = f.rate_count + 1,
14 f.rate_avg = round((f.rate_sum + :new.rev_star) /
15 (f.rate_count + 1), 2)
16 when not matched then insert values
17 (:new.mov_id, :new.rev_star, :new.rev_star, 1);
18 end;
19 /
Trigger created.
测试:
SQL> insert into rating (mov_id, userid, rev_star) values (1, 'Little', 3);
1 row created.
SQL> select * From fanrating;
MOV_ID RATE_AVG RATE_SUM RATE_COUNT
---------- ---------- ---------- ----------
1 3 3 1
SQL> insert into rating (mov_id, userid, rev_star) values (1, 'Foot', 1);
1 row created.
SQL> select * From fanrating;
MOV_ID RATE_AVG RATE_SUM RATE_COUNT
---------- ---------- ---------- ----------
1 2 4 2
SQL> insert into rating (mov_id, userid, rev_star) values (1, 'Scott', 4);
1 row created.
SQL> select * From fanrating;
MOV_ID RATE_AVG RATE_SUM RATE_COUNT
---------- ---------- ---------- ----------
1 2,67 8 3
SQL> insert into rating (mov_id, userid, rev_star) values (2, 'Foot', 5);
1 row created.
SQL> select * From fanrating;
MOV_ID RATE_AVG RATE_SUM RATE_COUNT
---------- ---------- ---------- ----------
1 2,67 8 3
2 5 5 1
SQL>
[编辑:过程 + 触发器]
如果它必须是一个过程,那么 - 正如我所评论的 - 将 MERGE 移入其中,使用您插入的值作为参数。方法如下:
程序:
SQL> create or replace procedure p_mrg
2 (par_mov_id in number,
3 par_userid in varchar2,
4 par_rev_star in number
5 )
6 as
7 begin
8 merge into fanrating f
9 using (select par_rev_star rev_star,
10 par_mov_id mov_id
11 from dual
12 ) x
13 on (f.mov_id = x.mov_id)
14 when matched then update set
15 f.rate_sum = f.rate_sum + par_rev_star,
16 f.rate_count = f.rate_count + 1,
17 f.rate_avg = round((f.rate_sum + par_rev_star) /
18 (f.rate_count + 1), 2)
19 when not matched then insert values
20 (par_mov_id, par_rev_star, par_rev_star, 1);
21 end;
22 /
Procedure created.
Trigger 现在调用过程(而不是运行MERGE 本身):
SQL> create or replace trigger ai_rating_trg
2 after insert on rating
3 for each row
4 begin
5 p_mrg (:new.mov_id, :new.userid, :new.rev_star);
6 end;
7 /
Trigger created.
附加测试:
SQL> insert into rating (mov_id, userid, rev_star) values (2, 'Mike', 2);
1 row created.
SQL> select * from fanrating;
MOV_ID RATE_AVG RATE_SUM RATE_COUNT
---------- ---------- ---------- ----------
1 2,67 8 3
2 3,5 7 2
SQL>