您不需要为fanrating
表创建这样的触发器,但是需要在创建过程中定义默认值,例如:
我必须添加电影的收视率的平均值和总数!以下是我的餐桌和老虎!请改进此代码!
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!
一些反对意见:
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>
您不需要为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
。
您不需要为fanrating
表创建这样的触发器,但是需要在创建过程中定义默认值,例如: