#oracle #plsql
#Oracle #plsql
Вопрос:
Я пытаюсь использовать столбец из :new (входящая новая строка) для сравнения с датой в другой таблице, а затем вызвать ошибку, если условия выполнены.
Я попробовал два решения:
CREATE OR REPLACE TRIGGER trigger_example BEFORE INSERT ON STATION FOR EACH ROW DECLARE d1 DATE; d2 DATE; BEGIN SELECT JOUR INTO d1 FROM ELECTION; SELECT DATEOUVERTURE INTO d2 FROM NEW; IF d1 = d2 THEN RAISE_APPLICATION_ERROR(-20001,'damn'); end if; end;
Это тот случай, когда я выбираю DATEOUVERTURE из NEW и получаю эту ошибку.
[2021-12-09 01:33:45] 6:39:PL/SQL: ORA-00942: table or view does not exist [2021-12-09 01:33:45] 6:5:PL/SQL: SQL Statement ignored
Но таблица существует, и у меня есть соответствующие права на чтение/запись
Второе решение:
CREATE OR REPLACE TRIGGER trigger_example BEFORE INSERT ON STATION FOR EACH ROW DECLARE d1 DATE; d2 DATE; BEGIN SELECT JOUR INTO d1 FROM ELECTION; SELECT DATEOUVERTURE INTO d2 FROM :NEW; IF d1 = d2 THEN RAISE_APPLICATION_ERROR(-20001,'damn'); end if; end;
Это тот, из которого я выбираю :НОВЫЙ вместо НОВОГО. Но я получаю эту ошибку.
[2021-12-09 01:36:56] 6:39:PLS-00049: bad bind variable 'NEW' [2021-12-09 01:36:56] 6:43:PL/SQL: ORA-00903: invalid table name [2021-12-09 01:36:56] 6:5:PL/SQL: SQL Statement ignored
Есть идеи, где все пошло не так? Я искал несколько часов и не могу найти ни единой вещи.
Комментарии:
1. Что вы получаете всякий раз , когда запрос
SELECT * FROM user_tables WHERE table_name ='NEW'
, не возвращает ли он строку ?2. Он не возвращает ни одной строки. В данном случае я не пытаюсь получить информацию из таблицы под названием NEW. Я пытаюсь получить конкретную колонку во входящей вставке.
3. Вот это и есть причина для возвращения
ORA-00942
.
Ответ №1:
Вы не можете использовать :NEW
это так. Следующий пример должен сработать, если вы замените
date_column_on_station_table
к столбцу, который вы хотите сравнить с внутренней STATION
таблицей
CREATE OR REPLACE TRIGGER trigger_example BEFORE INSERT ON STATION FOR EACH ROW DECLARE d1 DATE; d2 DATE; BEGIN SELECT JOUR INTO d1 FROM ELECTION; IF d1 = :NEW.date_column_on_station_table THEN RAISE_APPLICATION_ERROR(-20001,'damn'); end if; end;
Изменить: Если DATEOUVERTURE
это имя столбцов для сравнения , то оно должно быть таким:
CREATE OR REPLACE TRIGGER trigger_example BEFORE INSERT ON STATION FOR EACH ROW DECLARE d1 DATE; BEGIN SELECT JOUR INTO d1 FROM ELECTION; IF d1 = :NEW.DATEOUVERTURE THEN RAISE_APPLICATION_ERROR(-20001,'damn'); end if; end;
Комментарии:
1. Когда я пробую это решение, я получаю ошибку: Не удается разрешить столбец «DATEOUVERTURE», Чтобы отметить, что столбец «DATEOUVERTURE» находится в таблице под названием СТАНЦИЯ и что я пытаюсь получить входящую ДАТУ(я пытаюсь проверить перед вставкой, совпадает ли новая дата с d1)
2. хм , это должно сработать, не могли бы вы, пожалуйста, проверить, нет ли опечатки в DATEOUVERTURE — может быть, пропущенная буква и т. Д. ?
3. Значение ДАТЫ указано правильно.
4. я протестировал его на своей базе данных oracle, и он работает … я удалю ответ через некоторое время, так как он не работает для вас
5. Для меня ваш 2-й код выглядит нормально. Хотя,
d2
может быть удален, и неизвестноselect
, вызовет ли исключение (в нынешнем виде эта таблица содержит только одну строку — остерегайтесь TOO_MANY_ROWS или даже NO_DATA_FOUND). Но дело не в этом — я действительно считаю, что этот код должен работать в отношении информации, опубликованной операцией. @Angry_sLmon, пожалуйста, отредактируйте исходный код, который вы опубликовали, и покажите описания таблиц.