Как создать произвольную ошибку с помощью RDBMS DML

#java #oracle #postgresql #error-handling #dbunit

#java #Oracle #postgresql #обработка ошибок #dbunit

Вопрос:

Предыстория

  • Я пишу Java-приложение, работающее с RDBMS.
  • Приложение использует Oracle и PostgreSQL в качестве хранилища данных.

Проблема

Сейчас я тестирую процедуру обработки ошибок для некоторого SQLException. Например, я хочу рассматривать ORA-00001 (нарушение уникального ограничения) или ORA-00054 (не удалось получить эксклюзивную блокировку) как исправляемую ошибку. С другой стороны, я хочу рассматривать ORA-00060 (взаимоблокировку) как ошибку, не подлежащую восстановлению.

Сейчас я пытаюсь написать тестовые примеры JUnit для этой процедуры обработки ошибок. Чтобы сделать тестовые примеры максимально переносимыми, я ищу способ генерировать произвольные ошибки (ORA-00001, ORA-00054, …) с помощью простого DML типа SELECT RAISE_ERROR(-54) FROM DUAL . Кроме того, я хочу избежать издевательства над самим SQLException в тестовых примерах, потому что содержимое SQLException может быть изменено в зависимости от версии RDBMS.

Вопрос

Есть ли какой-либо способ создать произвольные ошибки SQL с помощью DML в RDBMS (особенно Oracle и PostgreSQL)? Или, есть ли какая-либо платформа тестирования, такая как DBUnit, которая имеет функцию для создания произвольного исключения SQLException? Желательно, если может возникнуть ошибка без конкретных таблиц и записей.

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

1. postgresql.org/docs/current/plpgsql-errors-and-messages.html Посмотрите на sqlstate варианты. Наиболее компактная форма: do $$ begin raise sqlstate '23503'; end$$;

2. Спасибо за комментарий. Это было бы полезно, когда я тестирую код с PostgreSQL.

Ответ №1:

Не существует переносимого способа искусственно вызвать данную ошибку в SQL, вам придется писать код для каждой базы данных.

Но я хочу дать вам несколько общих советов:

  • Используйте стандартизированный SQLSTATE, а не специфичный для системы код ошибки, такой как Oracle ORA-xxxxx numbers. Это должно быть переносимым.

    У всех RDBMS должен быть способ получения SQLSTATE для сообщения об ошибке.

  • Я не знаю, что вы имеете в виду под «исправляемой ошибкой», но взаимоблокировка явно не является постоянной ошибкой — если вы повторите транзакцию, она, вероятно, будет успешной.

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

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

1. Спасибо за ваш ответ. Что я имею в виду под «восстанавливаемым», так это то, что пользователь приложения может устранить причину ошибки и продолжить свою деятельность (например, когда пользователь пытается зарегистрировать какую-либо службу, а его идентификатор пользователя не уникален, он может попробовать с другим идентификатором. С другой стороны, пользователь не может разрешить взаимоблокировку в RDBMS с помощью своей операции).