Триггер продолжает не компилироваться. Таблица заявок не найдена, когда таблица существует - PullRequest
0 голосов
/ 19 марта 2020

Все вызываемые таблицы точно существуют. Я дважды проверил орфографию. Ошибки, которые дает sqldeveloper, не очень полезны, и я не могу понять, почему это не удается. Я пытаюсь создать триггер, который обновляет таблицу top5restaurants при поступлении нового отзыва. У меня есть процедура, которая анализирует обзор и добавляет его в таблицу рейтинга. Стол top5restaurant поддерживает рестораны с 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 создан.

Таблица TOP5RESTAURANTS удалена.

Таблица TOP5RESTAURANTS создано.

вставлено 5 строк.

Просмотр TOP5REST удален.

Просмотр создан TOP5REST.

Триггер скомпилирован TOP5_TRIGGER

LINE / COL ОШИБКА


7/5 PL / SQL: SQL Оператор игнорируется 7/17 PL / SQL: ORA-00942: таблица или представление не существует 11/5 PL / SQL: SQL Оператор игнорируется 11/17 PL / SQL: ORA-00942: таблица или представление не существует 18/5 PL / SQL: SQL Оператор игнорируется 18/40 PL / SQL: ORA -00984: столбец здесь запрещен. Ошибки: проверьте журнал компилятора

1 Ответ

2 голосов
/ 19 марта 2020

Вы не insert into скалярная переменная. Вы можете сделать select into. Оператор

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

синтаксически действителен. Но это почти наверняка неверно. Предположительно, вы хотите выбрать название ресторана, а не рид

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

Если вы объявите переменную %rowtype, то вы захотите ввести 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 (что делает ваше представление) из триггера уровня строки в rating таблица. Это не разрешено. Это почти гарантирует, что у вас есть проблемы в вашей логике c. В этом случае, кажется, нет необходимости в отдельной таблице для хранения 5 лучших ресторанов. Реально, ваше мнение должно просто сделать этот расчет, если вам нужны результаты в режиме реального времени, или вы должны создать материализованное представление, которое периодически обновляется, если вам не нужно сразу видеть изменение общего рейтинга ресторана при добавлении новых рейтингов. Таким образом, вам, вероятно, не нужен триггер на всех.

...