我必须添加电影的平均收视率和总数!以下是我的餐桌和老虎!请改进此代码!
create table fanrating
(
mov_id number(10),
rate_avg number(1,1),
rate_sum number,
rate_count number
);
create table rating
(
mov_id number(10) references movie(mov_id),
userid varchar(20),
rev_star number,
primary key(mov_id,rev_star)
);
delimiter $$
create or replace trigger bi_rating_trg
before insert on fanrating
for each row
begin
set rate_sum = 0;
set rate_count = 0;
set rate_avg = null;
end;
$$
create or replace trigger ai_rating_trg
after insert on rating
for each row
begin
update fanrating
set rate_sum = rate_sum + new.rev_star,
rate_count = rate_count + 1,
rate_avg = rate_sum / rate_count
where mov_id = new.mov_id;
end;
$$ delimiter;
它在触发器中的所有3个set命令中都显示错误,并且还遇到称为符号$$的错误,我正在使用Oracle SQL Delevepor!
答案 0 :(得分:1)
一些反对意见:
new
和old
值前应加冒号,即:new
和:old
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.
触发器现在调用过程(而不是运行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>
答案 1 :(得分:1)
您无需为fanrating
表创建这样的触发器,但是需要在创建过程中定义默认值,例如:
create table fanrating
(
mov_id number(10),
rate_avg number(1,1),
rate_sum number default 0,
rate_count number default 0
);
并为insert or update
表创建rating
触发器:
create or replace trigger ai_rating_trg
after insert or update on rating
for each row
begin
update fanrating
set rate_sum = nvl(rate_sum,0) + nvl(:new.rev_star,0),
rate_count = nvl(rate_count,0) + 1,
rate_avg = nvl(rate_sum,0) / nvl(rate_count,1)
where mov_id = :new.mov_id;
end;
/
其中nvl(..,0)
用于将null
的值转换为zero
。