Ошибка запуска Oracle «ORA-00942: таблица или представление не существует»

#sql #oracle #triggers

#sql #Oracle #триггеры

Вопрос:

это мой триггер :

     create trigger tampone_trigger
after insert on tamponi.numerotelpaziente
for each row
begin
    IF ( :new.numerotelpaziente not in ( 
    select numtel 
    from users))
    then 
    insert into spaiati values (new.numtel);
    end if;
end;
  

Таблица «Tamponi» действительно существует, и «numerotelpaziente» является одним из столбцов…
Таблица «ПОЛЬЗОВАТЕЛИ» также существует, и «numtel» является одним из ее столбцов…
С какой стати выдает мне эту ошибку?
Предполагается, что триггер ищет этот новый номер мобильного телефона, вставленный в «Tamponi», и проверяет, существует ли этот номер в «Users», если нет, его нужно добавить в отдельную таблицу «spaiati», где для него есть столбец..
Он отлично подключен к моей личной базе данных (я запускаю на нем свое приложение JavaFX, и оно работает нормально, мне просто нужно создать несколько триггеров).

     Report error -
ORA-00942: table or view does not exist
00942. 00000 -  "table or view does not exist"
*Cause:    
*Action:
  

Если я использую «on Tamponi» вместо того, чтобы указывать столбец, ошибка становится такой :

 Report error -
ORA-04082: NEW or OLD references not allowed in table level triggers
04082. 00000 -  "NEW or OLD references not allowed in table level triggers"
*Cause:    The trigger is accessing "new" or "old" values in a table trigger.
*Action:   Remove any new or old references.
  

если я использую «on tamponi», ошибка теперь выглядит так :

 2/5       PL/SQL: Statement ignored
2/40      PLS-00405: subquery not allowed in this context
Errori: controllare il log del compilatore
  

Ответ №1:

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

 CREATE TRIGGER tampone_trigger
    AFTER INSERT
    ON tamponi
    FOR EACH ROW
BEGIN
    INSERT INTO spaiati
        SELECT :new.numerotelpaziente
          FROM DUAL
         WHERE NOT EXISTS
                   (SELECT 1
                      FROM users u
                     WHERE u.numtel = :new.numerotelpaziente);
END;
/
  

Комментарии:

1. Да! Это работает, но у меня есть вопрос: когда вы выполняете «Из двойного», а затем выбираете 1, что именно происходит?

2. DUAL это фиктивная таблица, которая всегда возвращает одну строку, и при выборе определенного значения это значение всегда будет возвращаться. EXISTS Функция проверяет, возвращаются ли какие-либо строки вообще, независимо от значения, для запроса в () . Выбор 1 приведет к тому же результату, что и выбор NUMTEL или любое другое значение. Наиболее эффективно использовать значение, которое не нужно искать в базе данных.

Ответ №2:

Вы можете попробовать это —

 create trigger tampone_trigger
after insert on tamponi
for each row
declare
  v_flag  boolean := false;  
begin

for c in (select numtel from users)
loop
if :new.numerotelpaziente = c.numtel 
    then 
    v_flag := true;
    exit;
     end if;
  exit when no_data_found;
 end loop;
    insert into spaiati values (new.numtel);
end;
  

Комментарии:

1. теперь эта ошибка: 2/5 PL / SQL: оператор игнорируется 2/40 PLS-00405: подзапрос не разрешен в этом контексте Ошибка: controllare il log del compilatore

2. и да, это тоже работает и дало мне больше информации о триггерах, спасибо

Ответ №3:

В настоящее время у меня нет доступного клиента DB, но это должно быть близко к тому, что вы хотите:

 create trigger tampone_trigger
  after insert on tamponi for each row
declare
    v_exists number;
begin
    select count(*) into v_exists from users u where u.numtel = :new.numerotelpaziente;
    if (v_exists = 0) then
        insert into spaiati values(:new:numerotelpaziente);
    end if;
end;
  

Комментарии:

1. Да, кто-то уже ответил, использование переменной флага действительно помогает, спасибо