Триггер Oracle: raise_application_error

Я хочу использовать процедуру raise_application_error, чтобы остановить процесс входа в систему. Я написал триггер, который проверяет строку TERMINAL, если он правильный (я знаю, что это не совсем безопасно, но сначала этого достаточно), поэтому триггер работает нормально и делает то, что я хочу, но raise_application_error вызывает откат и отправляет не то исключение, которое я хочу. Когда я вхожу в БД с моим приложением, raise_application_error не останавливает приложение. Первый вопрос: это правильный способ остановить вход в базу данных с неправильным приложением? Второй вопрос: если да, что не так?

create or replace
TRIGGER after_logon_on_database 
AFTER LOGON ON DATABASE
BEGIN
IF sys_context('USERENV', 'TERMINAL')='IAS' THEN
  INSERT INTO event_log
  (event_date, event_time, username, event_case, event_comment)
  VALUES
  (SYSDATE, to_char(sysdate, 'hh24:mi:ss'), USER, 'LOGON-SUCCESS', sys_context('USERENV', 'TERMINAL'));
ELSE
  INSERT INTO event_log
  (event_date, event_time, username, event_case, event_comment)
  VALUES
  (SYSDATE, to_char(sysdate, 'hh24:mi:ss'), USER, 'LOGON-FAILURE', sys_context('USERENV', 'TERMINAL'));
  RAISE_APPLICATION_ERROR(-20001, 'Access denied!');
END IF;
END after_logon_on_database;

Ответов (2)

Прочтите эту тему: http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:3236035522926

Во второй части IF / ELSE добавьте фиксацию; оператор между Insert и Raise. Это гарантирует, что сообщение об ошибке входа в систему будет правильно вставлено в базу данных.

Вы знаете, что триггер входа в систему не остановит пользователя от входа в систему, если он является администратором баз данных (имеет роль DAB). Это функция, гарантирующая, что кто-то всегда сможет получить доступ к базе данных для исправления сбоя триггера при входе в систему.

Вы также правы в том, что триггер не вызовет (как первое сообщение об ошибке, возвращаемое Oracle) ошибку -20001. Вместо этого он вернет -604 (ORA-00604: ошибка на уровне рекурсивного SQL 1). Вы не запускаете триггер напрямую при входе в систему, он выполняется на нескольких удаленных шагах. Вам нужно, чтобы ваше приложение правильно обрабатывало эту ошибку.