Аннотация:
При разработке программ, работающих с БД, важным моментом является обработка ошибочных ситуаций и информативность сообщений, предназначенных для конечного пользователя. При сложной структуре БД формирование таких сообщений для каждой отдельной ситуации может требовать довольно значительных усилий. Обработка ошибок, основанная на анализе структуры БД, и с учётом различных специфических ситуации позволит уменьшить трудозатраты и повысить качество программного обеспечения.
Re: Общий метод формирования сообщений об ошибках [...]
А для чего сообщать пользователю в каком столбце, какой таблицы произошла попытка нарушить уникальность данных, вместо того, что-бы отловить код ошибки и по нему внятно сказать ЧТО здесь нельзя делать? У меня, например, есть уникальность на данные по расчетным счетам и при попытке добавить существующий счет, я просто говорю, что "такой р/счет существует", а не "Значение поля “расчетный счет” в таблице “Счетов” должно быть уникальным." причем делаю это без дополнительных запросов к БД.
А как быть с пользовательскими исключениями?
А если программа работает на диалапе и лишний запрос может и не ответить никогда?
и т.д. и т.п.
Вообщем
Re: Общий метод формирования сообщений об ошибках [...]
Здравствуйте, Лихачёв Владимир Николаевич, Вы писали:
я — упертый сторонник НЕ передачи нижних exceptions пользователю.
считаю, что надо обрабатывать максимально, что можно, и показывать пользователю яснопонятные сообщения.
точно знаю, что этот взгляд противоречит религии многих моих коллег.
ЛВН>При разработке программ, работающих с БД, важным моментом является обработка ошибочных ситуаций и информативность сообщений, предназначенных для конечного пользователя.
совершенно согласен.
ЛВН>При сложной структуре БД формирование таких сообщений для каждой отдельной ситуации может требовать довольно значительных усилий.
гм... не понял. фишка в том, что часть моей работы — именно вот эти "значительные усилия" по созданию яснопонятного интерфейса пользователя. в том числе — дружественные (или хотя бы понятные для не программиста) сообщения об ошибках.
ЛВН>Обработка ошибок, основанная на анализе структуры БД, и с учётом различных специфических ситуации позволит уменьшить трудозатраты и повысить качество программного обеспечения.
опять же — совершенно согласен.
Чтобы пользователю был понятен смысл ошибок и их причина, в сообщениях об ошибках необходимо указывать именно те названия полей и таблиц, которые используются им при работе с программным обеспечением.
давайте честно скажем, что это облегчит работу саппорта, но не пользователя.
в приложении с несколькими тысячами обьектов в базе данных, информация о таблице-поле для пользователя — сродни заклинанию. можно прочитать по телефону саппорту, и они чет сделают. шаманы, не меньше. а если саппорт за хорошую деньгу?
Для исключения неоднозначности при определении таблицы, к которой относится поле, необходимо чтобы названия полей таблиц были уникальными в пределах всей БД, а не только для таблицы.
здасьте! а как же fk? всю жизнь были одинаковые в таблицах.
кстати. оракл например возвращает совершенно понятные сообщения об ошибках, на которых саппорт работает влегкую. так вот именно сокрытие ответа оракла — одна из задач _безопастности_ проекта. во
Re[2]: Общий метод формирования сообщений об ошибках [...]
Здравствуйте, bastrakov, Вы писали:
B>кстати. оракл например возвращает совершенно понятные сообщения об ошибках, на которых саппорт работает влегкую.
ну да, знаем мы эти сообщения — "ORA-00942: table or view does not exist" да "ORA-00904: invalid column name"
Re[2]: Общий метод формирования сообщений об ошибках [...]
От:
Аноним
Дата:
20.05.09 08:30
Оценка:
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. На клиенте хранить пустую копию рабочей БД для работы запросов к системным таблицам.
Конечно, каждый из вариантов имеет некоторые недостатки. Но это, все-таки, скорее всего уже вопрос реализации предложенного с статье механизма.
Re[2]: Общий метод формирования сообщений об ошибках [...]
От:
Аноним
Дата:
20.05.09 09:37
Оценка:
B>здасьте! а как же fk? всю жизнь были одинаковые в таблицах.
Речь идет о том, что в сообщении “NOT NULL” сервер указывает только название поля таблицы, для которого нарушено ограничение. Имя таблицы, к которой относится поля, в сообщении от сервера не указывается. Поэтому, если для одного из этих полей будет нарушено ограничение уникальности, то определить, в какой именно таблице было нарушено ограничение, будет невозможно (если имеется только код ошибки и текст ошибки от сервера).
Re[2]: Общий метод формирования сообщений об ошибках [...]
B>давайте честно скажем, что это облегчит работу саппорта, но не пользователя. B>в приложении с несколькими тысячами обьектов в базе данных, информация о таблице-поле для пользователя — сродни заклинанию. можно прочитать по B>телефону саппорту, и они чет сделают. шаманы, не меньше. а если саппорт за хорошую деньгу?
На основе данных о причине ошибки могут быть сформированы сообщения различного содержания. Например, при нарушении ограничения уникальности поля “Название” таблицы “Товары” можно сформировать сообщения (это только примеры!):
*Значение поля “Название” таблицы “Товары” должно быть уникальным !
*Товар с таким названием уже зарегистрирован ! Исправьте название товара !
*В справочнике товаров не могут быть товары с одинаковыми названиями ! Измените название товара !
Хотя эти сообщения и различаются, но во всех этих сообщениях указывается информация об объекте БД, для которого нарушено ограничение уникальности – это поле “”Название” таблицы “Товары”. Если сравнить эти сообщения, то можно заметить, что формирование первого сообщения является наиболее простым вариантом (который и используется в статье). Для формирования двух других сообщений наверняка потребуется лексический синтез сообщения об ошибке, а не просто подстановка пользовательских названий таблиц и их полей в сообщение об ошибке.
Если сравнить эти сообщения с точки зрения пользователя, то можно предположить, что последние два сообщения будут для пользователя оказаться более понятными, и позволят ему понять причину ошибку и её исправить.
Конечно же, в этом случае встает вопрос о лексическом синтезе – но это уже отдельная тема.
Re[2]: Общий метод формирования сообщений об ошибках [...]
B>гм... не понял. фишка в том, что часть моей работы — именно вот эти "значительные усилия" по созданию яснопонятного интерфейса пользователя. в том B>числе — дружественные (или хотя бы понятные для не программиста) сообщения об ошибках.
Целью описываемого в статье метода как раз и является уменьшение этих "значительных усилий".
Re[3]: Общий метод формирования сообщений об ошибках [...]
стараюсь не отвечать анонимам, но судя по стилю, Владимир Николаевич — это вы.
B>>здасьте! а как же fk? всю жизнь были одинаковые в таблицах. А>Речь идет о том, что в сообщении “NOT NULL” сервер указывает только название поля таблицы, для которого нарушено ограничение. Имя таблицы, к которой относится поля, в сообщении от сервера не указывается. Поэтому, если для одного из этих полей будет нарушено ограничение уникальности, то определить, в какой именно таблице было нарушено ограничение, будет невозможно (если имеется только код ошибки и текст ошибки от сервера).
я понял о чем идет речь. никаких претензий к сообщению или к процессу поиска у меня нет.
еще раз — это просто разный подход к "жизни" exception. куча народу пишет свои, и показывает заранее определенный текст на ui, и куча народу готова их за это пристрелить и бьется грудью за передачу всех exceptions через все уровни наверх.
просто огласите свое мнение на тему одинаковых наименований полей для разных таблиц, если это связанные поля (FK).
взято прямо из проекта:
ORG_UNIT_SNAP_CONTACT_DETAILS.CONTACT_DETAILS_USAGE_TYPE_ID внешний ключ для (как понятно из названия) CONTACT_DETAILS_USAGE_TYPE таблицы, где CONTACT_DETAILS_USAGE_TYPE_ID ключ.
а как бы вы предложили назвать поля?
я даже обещаю ничего не комментировать.
мне просто интересен взгляд и доводы, которые используются для создания уникальных названий полей при fk.
2:Odi$$ey. пристрелите ваших разработчиков.
я — гуманный человек, но "ORA-00942: table or view does not exist" для саппорта (т.е. в процессе использованя) — это 5! во
Re[4]: Общий метод формирования сообщений об ошибках [...]
оракл например возвращает совершенно понятные сообщения об ошибках, на которых саппорт работает влегкую
а когда я привожу слово-в-слово пару оракловских сообщений, то уже прямо противоположное:
B>2:Odi$$ey. пристрелите ваших разработчиков. B>я — гуманный человек, но "ORA-00942: table or view does not exist" для саппорта (т.е. в процессе использованя) — это 5! во
Если уж кого и надо пристрелить за такие сообщения — так это разработчиков оракла
Re[4]: Общий метод формирования сообщений об ошибках [...]
B>стараюсь не отвечать анонимам, но судя по стилю, Владимир Николаевич — это вы.
Извините, поторопился и не залогинился.
B>я понял о чем идет речь. никаких претензий к сообщению или к процессу поиска у меня нет. B>еще раз — это просто разный подход к "жизни" exception. куча народу пишет свои, и показывает заранее определенный текст на ui, и куча народу готова B>их за это пристрелить и бьется грудью за передачу всех exceptions через все уровни наверх.
Описываемый метод может быть применим для любого из этого подходов. Пользовательские исключения могут передаваться без изменения пользователю. А для ошибок ограничений могут формироваться или "универcальные" или специальные сообщения.
B>просто огласите свое мнение на тему одинаковых наименований полей для разных таблиц, если это связанные поля (FK). B>взято прямо из проекта: B>ORG_UNIT_SNAP_CONTACT_DETAILS.CONTACT_DETAILS_USAGE_TYPE_ID внешний ключ для (как понятно из названия) CONTACT_DETAILS_USAGE_TYPE таблицы, где CONTACT_DETAILS_USAGE_TYPE_ID ключ. B>а как бы вы предложили назвать поля? B>я даже обещаю ничего не комментировать. B>мне просто интересен взгляд и доводы, которые используются для создания уникальных названий полей при fk.
Для описываемого в статье метода уникальные названия полей таблиц в пределах БД критичны только для ошибки "not null". Формирование сообщений о других ошибках ограничений может быть выполнено и в случае, если поля различных таблиц будут иметь одинаковые имена.
Re[2]: Общий метод формирования сообщений об ошибках [...]
B> так вот именно сокрытие ответа оракла — одна из задач _безопастности_ проекта. во
Описываемый метод может использоваться для решения и таких задач. Если, например, не выдавать сообщение для пользователя в случае, если при формировании сообщения выяснится, что одна из таблиц, которая, является причиной ошибки, не имеет описания (или не имеет описание поле таблицы). Так же можно сделать таблицу аналогичную таблице специальных сообщений, но только с противоположной целью. Если ошибка зарегистрирована в этой таблице, то сообщение для пользователя не должно выдаваться.
Re[5]: Общий метод формирования сообщений об ошибках [...]
Здравствуйте, Odi$$ey, Вы писали:
OE>не понял. Сначала ты пишешь, что OE>
OE>оракл например возвращает совершенно понятные сообщения об ошибках, на которых саппорт работает влегкую
вот прямо из терминала. по моему можно прямо саппортеру диктовать, че делать.
Error report:
SQL Error: ORA-00001: unique constraint (SC_P4_ADMIN.FEATURE_UK) violated
00001. 00000 - "unique constraint (%s.%s) violated"
*Cause: An UPDATE or INSERT statement attempted to insert a duplicate key.
For Trusted Oracle configured in DBMS MAC mode, you may see
this message if a duplicate entry exists at a different level.
*Action: Either remove the unique restriction or do not insert the key.
OE>а когда я привожу слово-в-слово пару оракловских сообщений, то уже прямо противоположное:
вы приводите ошибку, при которой надо прибивать команду разработки или деплоймента.
B>>2:Odi$$ey. пристрелите ваших разработчиков. B>>я — гуманный человек, но "ORA-00942: table or view does not exist" для саппорта (т.е. в процессе использованя) — это 5! во
OE>Если уж кого и надо пристрелить за такие сообщения — так это разработчиков оракла
а что может сообщить база, если вы ищите обьект, которого у нее нет? она именно это и говорит. во
Re[6]: Общий метод формирования сообщений об ошибках [...]
Здравствуйте, bastrakov, Вы писали:
B>вот прямо из терминала. по моему можно прямо саппортеру диктовать, че делать. B>
B>Error report:
B>SQL Error: ORA-00001: unique constraint (SC_P4_ADMIN.FEATURE_UK) violated
B>00001. 00000 - "unique constraint (%s.%s) violated"
B>*Cause: An UPDATE or INSERT statement attempted to insert a duplicate key.
B> For Trusted Oracle configured in DBMS MAC mode, you may see
B> this message if a duplicate entry exists at a different level.
B>*Action: Either remove the unique restriction or do not insert the key.
B>
хз, что там у тебя за терминал, я вижу ошибки, которые возвращаются виндовым оракловским клиентом программам, которые его дергают, "ORA-00942: table or view does not exist" всегда без имени таблицы, а "ORA-00904: invalid column name" без имени отсутствующей колонки
Re[7]: Общий метод формирования сообщений об ошибках [...]
One error saving changes to table "SC_P4_ADMIN"."ROLE":
Row 2: ORA-02292: integrity constraint (SC_P4_ADMIN.R_FP_FK01) violated - child record found
мой поинт был, что у оракла очень (временами избыточно) информативные сообщения об ошибках.
я не сравниваю с другими базами. это пример. и это пример достаточного для саппорта сообщения.
OE>хз, что там у тебя за терминал, я вижу ошибки, которые возвращаются виндовым оракловским клиентом программам, которые его дергают, "ORA-00942: table or view does not exist" всегда без имени таблицы, а "ORA-00904: invalid column name" без имени отсутствующей колонки
мой поинт был, что если вы это видите на работающем приложении, то его надо останавливать и переделоить.
вне зависимости от названия таблиц и полей. если потеряли что-то одно, то нет никакой гарантии, что не потеряли что-то еще.
не надо разбиратся, что потеряли. надо пересобрать проект с нуля и полностью.
ну неужели я не прав?!..
зюыю если вы не заметили, то вы точно в моей парадигме не показа юзеру ошибок с нижних уровней. во