#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. Да, кто-то уже ответил, использование переменной флага действительно помогает, спасибо