Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > MS SQL Server > Осмысленное сообщение об ошибке


Автор: Vit 2.9.2005, 18:26
Я накладываю на таблицу Constraint, no хочу чтобы в случае если пользователь вводит в таблицу что-то что противоречит назначенному Constraint вместо стандартной аббракадабры типа

Цитата
[Miscrosoft][ODBC MS SQL Driver][SQL SERVER] INSERT statement conflicted with COLUMN_CHECK constraint....


определить осмысленное сообщение об ошибке и чтобы именно это сообщение выдавалось клиенту. На уровне приложения делать обработку ошибок крайне не желательно, так как количество приложений, работающих с базой данных исчисляется сотнями, т.е. для переделки всех их потребуется минимум месяц работы, с другой стороны абсолютно неквалифицированный пользователь должен получить вполне удобочитаемое и понятное сообщение типа: "введение значения номера месяца больше 12 недопустимо"

Автор: Akina 2.9.2005, 20:13
Импоссибль - это сообщение выдает не сервер, а ODBC-драйвер на клиенте.

Пишите более внятные маны...

Автор: Vit 2.9.2005, 21:05
Цитата(Akina @ 2.9.2005, 11:13)
Импоссибль - это сообщение выдает не сервер, а ODBC-драйвер на клиенте.



Не уверен, по-моему, я где то видел что можно указать драйверу проверять constraint самому или поручить это серверу...



Цитата(Akina @ 2.9.2005, 11:13)
Пишите более внятные маны...



В том то и дело, как я говорил - таблицу использует несколько сот совершенно разных приложений, манов соответственно тоже сотни... Не то чтоб это было невозможно заменить всё, просто очень трудоёмко

Автор: Akina 2.9.2005, 21:36
Цитата(Vit @ 2.9.2005, 22:05)
манов соответственно тоже сотни...

ОДИН ман

"Возможные сообщения об ошибках, их причины и методы их устрания".

Автор: Vit 2.9.2005, 22:11
Цитата(Akina @ 2.9.2005, 12:36)
ОДИН ман

"Возможные сообщения об ошибках, их причины и методы их устрания".



Хех... не получится... Ну не можешь ты давать один ман для сотрудников моей корпорации которые работают с таблицей и его же для нескольких клиентов... Клиенты не должны видеть ошибки которые могут возникнуть только внутри корпорации, мало того так как таблицы толкьо частью пересекаются то клиенты не должны видеть ошибки которые могут возникнуть только для другого клиента. Это не допустимо: пример, ты представитель копорации Ford и в своём мануал наталкиваешься на возможную ошибку:

Table GeneralMotors_Portal does not match Chrysler_Production invoice_number

Представитель компании Ford вообще не должен знать о том что его прямые конкуренты General Motors и Chrysler тоже являются клиентами нашей корпорации, тем более что между General Motors и Chrysler есть какие-то сношения!

Некоторые сообщения об ошибках которые возможны только во внутренней сети компании или при прямом обращении к базам данных из компании могут серьёзно повредить репутации фирмы или снизить степень защиты данных. Конечный пользователь должен иметь список только тех ошибок которые его касаются. Все остальные должны быть идентифицированные просто как "Internal Error" с каким-то номером...

Автор: leniviy 3.9.2005, 11:03
чем after тригер плох?

Автор: Akina 3.9.2005, 20:37
Цитата(Vit @ 2.9.2005, 23:11)
Это не допустимо: пример, ты представитель копорации Ford и в своём мануал наталкиваешься на возможную ошибку:

Table GeneralMotors_Portal does not match Chrysler_Production invoice_number

Представитель компании Ford вообще не должен знать о том что его прямые конкуренты General Motors и Chrysler тоже являются клиентами нашей корпорации, тем более что между General Motors и Chrysler есть какие-то сношения!

Эк тебя заносит... пусть себе там General Motors и Chrysler сношаются... я тебе о чем? юзер видит:
Цитата
[Miscrosoft][ODBC MS SQL Driver][SQL SERVER] INSERT statement conflicted with COLUMN_CHECK constraint....

лезет в ""Возможные сообщения об ошибках, их причины и методы их устрания" и там читает:

Если на экране появилось окно с надписью:
Цитата
[Miscrosoft][ODBC MS SQL Driver][SQL SERVER] INSERT statement conflicted with COLUMN_CHECK constraint...
значит Вы ввели какую-то фигню, которая в таблице уже есть... думать надо, прежде чем что-то вносить... блин...


Ему надо объяснять, что привело к этому ТИПУ ошибки, и что он должен проверить прежде чем попытаться получить такое же сообщение еще раз.

Автор: SergeBS 5.9.2005, 14:00
Vit
Цитата

Triggers Compared to Other Data Integrity Methods
Microsoft® SQL Server™ provides two primary mechanisms for enforcing business rules and data integrity: constraints and triggers. Each has benefits that make them useful in special situations. The primary benefit of triggers is that they can contain complex processing logic that uses Transact-SQL code. Therefore, triggers can support all of the functionality of constraints; however, triggers are not always the best method for a given feature.

Делаешь триггер с заменой неверного значения на верное (по умолчанию). В инструкции пишешь: "Если введенное значение заменяется на другое, значит введено было неверное. Подумайте и повторите ввод." Все.


Автор: Vit 6.9.2005, 01:35
Цитата(Akina @ 3.9.2005, 11:37)
лезет в ""Возможные сообщения об ошибках, их причины и методы их устрания" и там читает:

Если на экране появилось окно с надписью:

Цитата
[Miscrosoft][ODBC MS SQL Driver][SQL SERVER] INSERT statement conflicted with COLUMN_CHECK constraint...

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



Не совсем так. Constraint могут ставится на достаточно сложные логические ошибки. Типа: "для компании "Ford" интервал сканирования данных согластно контракту не может быть более 5 минут" При этом для компании Крайслер такого ограничения нет даже теоретически. В зависимости от клиента логика ограничений может сильно варьировать. Невозможно указать осмысленное сообщение об ошибке без привязки к конкретному клиенту, а следовательно если делать справочник по всем кодам, то надо делать для каждого клиента отдельный. Кроме того - это живые данные клиентов: Завтра клиент звонит и требует чтоб добавили какое-то ограничение, а это будет означать не только в базе подправить, а подготовить новый ман и его всем разослать, эдак у меня на подготовку манов больше времени уйдёт...



Цитата(SergeBS @ 5.9.2005, 05:00)
Делаешь триггер с заменой неверного значения на верное (по умолчанию).


1. Заменять ничего нельзя! Ты что! За переправленной цифрой могут стоять семизначные суммы денег! Кто-то введёт что-то не то, на то что цифра изменила значение не посмотрит, локальный клиент запишет в лог что было введено то-то... В конеце месяца обнаружится что расходы корпорации-клиента составили вместо 10000 долларов - 1000000... От того что они в результате очень долгих поисков обнаружат этот триггер и по чьему заказу он был сделан легче не станет, корпорация уже потеряет большие деньги...

2. Триггер не хочу - он отрабатывает не до запроса а после запроса, на очень больших и загруженных таблицах как у меня десяток триггеров вполне способны угробить сервак, точнее снизить его производительность ниже требуемой, он и так задыхается... какие там ещё триггеры!

Автор: Alex 6.9.2005, 01:41
Может поможет http://www.relib.com/forums/thread754956.aspx

Автор: SergKO 6.9.2005, 04:54
В самом деле, посмотрите в сторону RAISERROR. Таблицу sysmessage можно пополнять, пользовательские сообщения с номером не ниже 50 000.

Автор: SergeBS 6.9.2005, 14:12
Vit
Цитата

1. Заменять ничего нельзя! Ты что! За переправленной цифрой могут стоять семизначные суммы денег!

smile. Это мы уже проходили. Давай так:
1. Ты знаешь, какое должно быть верное значение (хотя бы диапазон). Делаешь проверку и если значение неверное - исправляешь на верное. Все корректно. При желании вместо строчки в инструкции (или вместе с) добавь Сообщение (красного цвета, в полэкрана и :smile smile ) что была ошибка, она исправлена, за 3-ю ошибку расстрел через повешенье! smile
2. Ты НЕ знаешь, какое должно быть верное значение. Тогда ты не можешь и проверить.

Может быть либо 1, либо 2. Крики про деньги - самоообман. Если Мэри листая Плейбой долбила по 0 и вместо 1$ - ввела 1,000,000,000,000,000$, то ты эту ошибку никак не отловишь и виновата все-таки Мэри. У нее отберут любимый журнал и разницу вычтут из жалованья (в рассрочку на 100 лет). smile

Цитата

2. Триггер не хочу - он отрабатывает не до запроса а после запроса

smile. И это мы уже проходили. Давай так:
вариантов опять 2:
1. Отрабатывает сервер. Чтобы ты ни придумывал, нагрузка на него, есс-но возрастет. Должен быть запрос. Или ХП. Или триггер на append/update/delete. Или ограничение. Что грузит больше, угадай. Ограничение - ну оно если и меньше грузит, то ненамного.
По идеологии РБД - должен быть триггер. Сложное правило. Сложность в том, чтобы видно было отработку всем, но не видно - почему.

2. Отрабатывает клиент. У тебя их разных 100 типов. Все переделать.

Может быть либо 1, либо 2.

Есть 3 вариант, еще страшнее: 3-х звенка. В просторечии MIDAS.

Автор: Vit 6.9.2005, 18:38
Цитата(SergeBS @ 6.9.2005, 05:12)
. Ты НЕ знаешь, какое должно быть верное значение. Тогда ты не можешь и проверить.

Может быть либо 1, либо 2. Крики про деньги - самоообман. Если Мэри листая Плейбой долбила по 0 и вместо 1$ - ввела 1,000,000,000,000,000$, то ты эту ошибку никак не отловишь и виновата все-таки Мэри. У нее отберут любимый журнал и разницу вычтут из жалованья (в рассрочку на 100 лет).


Это корпоративный бизнес, там свои правила. Я не могу вставлять значение, никакое. Должна генерироваться ошибка и транзакция проходить не должна, пока пользователь не введёт значение которое разрешено по условиям контрактов.


Цитата(SergeBS @ 6.9.2005, 05:12)
1. Отрабатывает сервер. Чтобы ты ни придумывал, нагрузка на него, есс-но возрастет. Должен быть запрос. Или ХП. Или триггер на append/update/delete. Или ограничение. Что грузит больше, угадай. Ограничение - ну оно если и меньше грузит, то ненамного.
По идеологии РБД - должен быть триггер. Сложное правило. Сложность в том, чтобы видно было отработку всем, но не видно - почему.


Триггер ГОРАЗДО более напряжный с точки зрения рассходов ресурсов так как отрабатывается после транзакции. Если я ставлю constraint то сервер сначала проверяет запрос на constraint а только потом его выполняет, если поставить триггер, то реально произойдёт - изменение таблицы, изменение всех зависимых таблиц, перестройка индексов и кластерного индекса, увеличение аутоинкрементов в таблице и всех связанных, затем отработка запроса триггера и откат транзакции. В течение всего этого времени все вовлечённые таблицы будут полностью или частично заблокированны на запись, а иногда и на чтение (в зависимости как hints установлены), кроме того для отработки такой транзакции сам сервер будет ждать пока все вовлечённое дело таблицы будут доступны на редактирование. Итого расходы на триггер просто несопоставимы с constraint - речь идёт о накладных расходах отличающихся на порядки! База данных и так очень загружена, лишний триггер вполне может очень сильно тормознуть систему, особенно при учёте что вовлечены таблицы размером с пол-террабайта при количестве одновременных подключений далеко за тысячу и нагрузкой от 10 до 100 запросов в секунду...

Автор: SergeBS 7.9.2005, 09:27
Vit
Цитата

особенно при учёте что вовлечены таблицы размером с пол-терабайта при количестве одновременных подключений далеко за тысячу и нагрузкой от 10 до 100 запросов в секунду...

"С этого и надо было начинать" Штирлиц.
С такими аппетитами без 3-хзвенки не выживешь. Все остальное - паллиатив.
И то наверняка кластеризовать придется.

А как с сетевым трафиком дела? Сервак несколько портов в несколько подсеток имеет?
Просто интересно. Я опасаюсь, что мне где-то через полгода-год тоже понадобится решать задачу подключения толпы, причем территориально разделенной. Все, блин, помешались на термине "единое социальное окно".

Цитата

Это корпоративный бизнес, там свои правила. Я не могу вставлять значение, никакое. Должна генерироваться ошибка и транзакция проходить не должна, пока пользователь не введёт значение которое разрешено по условиям контрактов.

Какой бизнес - неважно. Вот вся цепочка:
- в любом случае либо есть проверка, либо нет.
- для любой проверки либо есть возможность получить правдоподобное значение, либо нет.
- соответственно если есть возможность, то либо есть необходимость вставлять это правдоподобное, либо нет.
Консенсус?
У меня просто часто были задачки, когда одно поле - не больше другого по значению и как правило - равно, но только как правило. Я и привык это поле заполнять из другого, либо как только другое введено, либо после ошибки в нем самом.

Автор: leniviy 7.9.2005, 10:08
Vit
Цитата
Если я ставлю constraint то сервер сначала проверяет запрос на constraint а только потом его выполняет

Код

use pubs 
go
if object_id( 't2' ) is not null drop table t2 
if object_id( 't1' ) is not null drop table t1 
create table t1 ( id int primary key ) 
create table t2 ( id int identity , f int , 
constraint FK_t2__t1 foreign key ( f ) references t1 ( id ) 
) 

insert t1 ( id ) values ( 355 ) 

insert t2 ( f ) 
select a
from (
select A = 355 from sysobjects 
union all select 366 
) t1
order by a 

--Сейчас он вернет явно не единицу 
--Значит он успел что-то навставлять , а потом откатил 
select ident_current( 't2' )
print ident_current( 't2' )

Что мешает в after триггер вставить Rollback?

Автор: Vit 7.9.2005, 15:35
Цитата(leniviy @ 7.9.2005, 01:08)
Что мешает в after триггер вставить Rollback?


Ответ уже дан:

Цитата(Vit @ 6.9.2005, 09:38)
Триггер ГОРАЗДО более напряжный с точки зрения рассходов ресурсов так как отрабатывается после транзакции. Если я ставлю constraint то сервер сначала проверяет запрос на constraint а только потом его выполняет, если поставить триггер, то реально произойдёт - изменение таблицы, изменение всех зависимых таблиц, перестройка индексов и кластерного индекса, увеличение аутоинкрементов в таблице и всех связанных, затем отработка запроса триггера и откат транзакции. В течение всего этого времени все вовлечённые таблицы будут полностью или частично заблокированны на запись, а иногда и на чтение (в зависимости как hints установлены), кроме того для отработки такой транзакции сам сервер будет ждать пока все вовлечённое дело таблицы будут доступны на редактирование. Итого расходы на триггер просто несопоставимы с constraint - речь идёт о накладных расходах отличающихся на порядки! База данных и так очень загружена, лишний триггер вполне может очень сильно тормознуть систему, особенно при учёте что вовлечены таблицы размером с пол-террабайта при количестве одновременных подключений далеко за тысячу и нагрузкой от 10 до 100 запросов в секунду...



Цитата(SergeBS @ 7.9.2005, 00:27)
С этого и надо было начинать" Штирлиц.
С такими аппетитами без 3-хзвенки не выживешь. Все остальное - паллиатив.
И то наверняка кластеризовать придется.

А как с сетевым трафиком дела? Сервак несколько портов в несколько подсеток имеет?


Трёхзвенка местами есть, там где это возможно... Всё намного сложнее... В системе таких серваков...много, довольно сложные взаимосвязи. Задача кластеризации уже решается - пока стоят четырёхпроцессорные компы с оптоволоконным железным рейдом (сундук такой за пол миллиона с [censored 12]ой тучей винтов и собственной операционкой), но переходим на кластеры очень скоро. Сетевой трафик фигня - сетки гигабайтные, да и программы по умному работают, лишний трафик не гоняют. Подсеток насколько я знаю 4.

Добавлено @ 15:38
Цитата(SergeBS @ 7.9.2005, 00:27)
Какой бизнес - неважно. Вот вся цепочка:
- в любом случае либо есть проверка, либо нет.
- для любой проверки либо есть возможность получить правдоподобное значение, либо нет.
- соответственно если есть возможность, то либо есть необходимость вставлять это правдоподобное, либо нет.



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

Автор: leniviy 7.9.2005, 16:00
Vit
Цитата
Ответ уже дан

Да, триггер тяжелее, но констраинт тоже не такой уж безобидный.
Связанные таблицы лочатся, автоинкремент тоже растет.
разница в том, что с констраинтом апдэйт доходит не до конца и откатывается

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)