I_>А для чего сообщать пользователю в каком столбце, какой таблицы произошла попытка нарушить уникальность данных, вместо того, что-бы отловить код I_>ошибки и по нему внятно сказать ЧТО здесь нельзя делать? У меня, например, есть уникальность на данные по расчетным счетам и при попытке добавить I_>существующий счет, я просто говорю, что "такой р/счет существует", а не "Значение поля “расчетный счет” в таблице “Счетов” должно быть уникальным."
В статье приводятся лишь примеры возможных сообщений об ошибках. Об этом говорится неоднократно. В частности, в большинстве случаев перед приводимыми в статье вариантами сообщений используется фраза “например”, что говорит о том, что это всего-лишь один из вариантов возможной формулировки сообщения об ошибке.
Различные программы могут использовать различный стиль сообщений об ошибках, в статье используется вариант сообщений, которые информируют пользователя о причине ошибке.
В статье так же используется вариант сообщений, в которых отображается информация об ошибке в наиболее полном виде.
В Вашем примере, предполагается, что пользователь заполняет таблицу счетов интерактивно. То есть ему известно, какой из справочников он изменяет, поэтому, может быть, в этой ситуации информация об изменяемом справочнике (таблице) является избыточной. Выбор варианта сообщений остается в любом случае за разработчиком. В других же программах информация об изменяемой таблице может быть необходимой.
I_>причем делаю это без дополнительных запросов к БД.
Скорее всего, Вы имеете в виду, так называемый “локальный” вариант обработки ошибки.
Т е когда обрабатываются ошибки конкретной транзакции, например, изменения записи в таблицы расчётных счетов.
Целью статьи является рассмотрение возможности создания общего обработчика для всех ошибок,
в котором выполняется формирование сообщений об ошибках БД.
I_>А как быть с пользовательскими исключениями?
Firebird в пользовательских исключениях позволяет указывать произвольную строку, которая передается в клиентское приложение. Это позволяет в ряде случаев формировать сразу довольно информативные сообщения и поэтому такие сообщения можно сразу передавать пользователю без изменения. Например, вместо ограничения “CK_SALARY ” для таблицы “JOB” можно в триггере перед вставкой и обновлением записи выполнять необходимую проверку и генерировать сообщение для пользователя в уже “готовом” виде:
// удаляем ограничение
ALTER TABLE JOB DROP CONSTRAINT CK_SALARY;
// создаем исключение
CREATE EXCEPTION E_USER_ERROR '';
// создаем триггер
CREATE TRIGGER JOB_BI0 FOR JOB
ACTIVE BEFORE INSERT OR UPDATE POSITION 0
AS
begin
if (new.JOB_MIN_SALARY >= new.JOB_MAX_SALARY) then
exception E_USER_ERROR 'Для должности "'|| new.job_title ||'" максимальная заработная ('|| new.JOB_MAX_SALARY ||') плата должна быть больше минимальной ('|| new.JOB_MIN_SALARY ||')';
end
В этом случае клиентское приложение может сразу передавать сообщение пользователю, для выше приведенного примера оно может иметь, например, содержание:
Для должности "Директор" максимальная заработная (180.00) плата должна быть больше минимальной (200.00).
Такой вариант использования пользовательских исключений обсуждается в первом разделе статьи, в абзаце перед рисунком.
I_>А если программа работает на диалапе и лишний запрос может и не ответить никогда?
Можно предложить несколько решений:
1. Хранить необходимые информацию о системных таблицах локально. Если посмотреть на запросы, то их используется не так уж и много. Причем в большиснстве из них нужны не все данные, а только относящиеся к пользовательским объектам. Счистать эти данные можно при первом поключении к БД, а при последующих подключениях проверять из изменение, и считывать только изменения.
2. На клиенте хранить пустую копию рабочей БД для работы запросов к системным таблицам.
Конечно, каждый из вариантов имеет некоторые недостатки. Но это, все-таки, скорее всего уже вопрос реализации предложенного с статье механизма.