触发器一直无法编译。当 table 存在时找不到声明 table

Trigger keeps failing to compile. Claims table not found when table exists

所有被调用的table肯定存在。我也仔细检查了拼写。 sqldeveloper 给出的错误不是很有帮助,我似乎无法弄清楚为什么会失败。我正在尝试创建一个触发器,在收到新评论时更新 top5restaurants table。我有一个程序可以解析评论并将它们添加到评级 table。 top5restaurant table 保留了评分最高的 5 家餐厅。

drop view bestratings_rest;
create view bestratings_rest(rid, rate) as 
(select distinct rid, max(stars) from rating
group by rid);



drop table top5restaurants;
create table top5restaurants(rid int);

insert into top5restaurants rid
    select rid from
            (select rid, rate from bestratings_rest r
            order by r.rate asc)
        where rownum <=5;
drop view top5rest;

create view top5rest as  
select rid, best from(    
    select t.rid, best from top5restaurants t
    inner join (select distinct rid, max(stars) as best from rating
    group by rid) b
    on t.rid = b.rid);


create or replace trigger top5_trigger
    after insert on rating
    for each row
    declare
    minrow top5rest%rowtype;
    restrid restaurant.rid%type;
    restname restaurant.name%type;
    begin

    insert into minrow
    select rid, min(best) from top5rest;


    insert into restname
    select rid from restaurant
    where :new.rid = restaurant.rid;

    if :new.stars > minrow.best  then
    DELETE FROM top5restaurants
    where top5restaurants.rid = :new.rid;
    insert into top5restaurants values(rid);
    end if;

    end;
    /
--    
--
begin
update_reviews('Jade Court','Sarah M.', 4, '08/17/2017');

update_reviews('Shanghai Terrace','Cameron J.', 5, '08/17/2017');

update_reviews('Rangoli','Vivek T.',5,'09/17/2017');

update_reviews('Shanghai Inn','Audrey M.',2,'07/08/2017');

update_reviews('Cumin','Cameron J.', 2, '09/17/2017');

end;
/    
select * from top5restaurants;

sqldeveloper 输出:

视图 BESTRATINGS_REST 已删除。

视图 BESTRATINGS_REST 已创建。

Table 排名前 5 的餐厅下降。

Table 创建了 TOP5 餐厅。

已插入 5 行。

查看 TOP5REST 已删除。

查看已创建的 TOP5REST。

触发TOP5_TRIGGER编译

LINE/COL错误


7/5 PL/SQL: SQL 语句被忽略 7/17 PL/SQL: ORA-00942: table 或视图不存在 11/5 PL/SQL:SQL 语句被忽略 11/17 PL/SQL: ORA-00942: table 或视图不存在 18/5 PL/SQL:SQL 语句被忽略 18/40 PL/SQL: ORA-00984: 此处不允许列 错误:检查编译器日志

您没有 insert into 标量变量。你可以做一个select into。声明

select rid 
  into restname
  from restaurant
 where :new.rid = restaurant.rid;

在句法上是有效的。但这几乎可以肯定是不正确的。据推测,您想要 select 餐厅名称而不是 rid

select name 
  into restname
  from restaurant
 where :new.rid = restaurant.rid;

如果您声明了一个 %rowtype 变量,那么您想对该变量执行一个 select *。否则,如果有人添加或删除列,您将来会遇到编译错误。您必须添加一个谓词来指定您想要 select 的行。我的猜测是你想要这样的东西来给出最低 best 分数的行(或者最低 rid 的行,如果有两个具有相同的低分数

 select *
  into minrow
  from top5rest low
 where not exists( select 1
                     from top5rest high
                    where low.best > high.best )
   and not exists( select 1
                     from top5rest same
                    where low.best = same.best
                      and low.rid > same.rid )

但是,更根本的是,即使您纠正了语法错误,如果您尝试查询 rating table,您也会遇到运行时变异 table 错误(您的视图所做的)来自 rating table 上的行级触发器内部。那是不允许的。这几乎可以保证你的逻辑有问题。在这种情况下,似乎不需要单独的 table 来存储前 5 家餐厅。实际上,如果您需要实时结果,您的视图应该只进行该计算,或者如果您不需要在添加新评级时立即看到餐厅的整体评级变化,您应该创建一个定期刷新的物化视图。所以你可能根本不需要触发器。