![]() |
|
Модераторы: skyboy |
![]()
|
|
| UsamaBrainLaden |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 39 Регистрация: 10.11.2008 Репутация: нет Всего: нет |
Никак не могу организовать бизнес-правила!
CHEK не работает, а в мануалах по триггерам указаны в основном опреация SET. Можно ли с помощью триггера отменять удаление в событии BEFORE DELETE (или другом) при неудовлетворении какого-то логического условия? Скажем если пользователь пытается добавить запись, которая не удовлетворяет какому-то условию, которое проверяет триггер, то происходит отмена операции (типа Break в циклах паскаля). ЗЫ: Дело в том что в книге по SQL четко описаны реализации ограничений всех типов, даже которые накладываются на запись таблицы. Одним из способов это просто вставка в конце таблицы CHECK и какого-то условия которое проверяется при каждой ее модификации и соответственно отменяет опреацию в случае неудачи. В пятой версии MySQL всю эту прелесть отменили походу и ничего не остается как подумать что это можно реализовать через триггеры, но я не исключаю того, что это можно сделать и другими средствами, вопрос только какими? |
|||
|
||||
| sir_nuf_nuf |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 920 Регистрация: 6.1.2008 Репутация: 8 Всего: 31 |
Да.. CHECK что то действительно не реализован в MySQL
А с каким движком вы хотите это использовать ? Если с InnoDB - то есть предложение повесить триггер BEFORE INSERT / UPDATE и откатывать транзакцию, если проверка не прошла..(Как это красиво реализовать другая тема.) А если не транзакционный движок (MyISAM например), то нужно предложить какую-то замену вставляемому значению, например оставлять старым.. вот пример тригеров:
при нарушении условия при INSERT - вставляет NULL при нарушении условия при UPDATE - оставляет старым ну так.. для справки:
Это сообщение отредактировал(а) sir_nuf_nuf - 13.11.2008, 12:45 |
||||
|
|||||
| UsamaBrainLaden |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 39 Регистрация: 10.11.2008 Репутация: нет Всего: нет |
Я так понимаю innoDB транзакционный движок?
То есть фактически мне нужно при создании таблицы в конце указать innoDB, а потом создать триггер, скажем после удаления (AFTER DELETE) и если меня уловие не устроит то откатывать (ROLLBACK) так я понял? Дело в том что удаление происходит не через транзакцию, а просто так. В Delphi через компонент DBNavigator. Ясно что все равно происходит посылка запроса (DELETE FROM), но опять же никакой транзакции нет, или сам движок innoDB выполняет запросы к таблицам вкладывая их в транзакцию? Дело втом что меня не устраивает немного забивание NULL'ом и вообще больше озобочен процессом отмены удаления записи если пользователь (вернее его код) не совпадает с кодом владельца записи. |
|||
|
||||
| UsamaBrainLaden |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 39 Регистрация: 10.11.2008 Репутация: нет Всего: нет |
Если я делаю так:
То он ругается на то что откат транзакции не может производиться внутри триггера! |
|||
|
||||
| sir_nuf_nuf |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 920 Регистрация: 6.1.2008 Репутация: 8 Всего: 31 |
UsamaBrainLaden, InnoDB - транзакционный.
А) Любая DML операция происходит в рамках транзакции. Возможен режим autocommit, когда для каждого оператора - открывается своя транзакция, скорее всего ваш дельфи-компонент работает именно в autocommit. Но это не суть. Б) у MySQL куча ограничений на триггеры. по хорошему явно вызывать ROLLBACK не нужно. вызов этого оператора предполагает, что вы продолжите дальш работу, а вам нужно прервать выполнение. Так что бы MySQL сам откатил транзакцию. Сейчас погуглю поэтому поводу. А пока есть костыль для прерывания транзакции: заместо ROLLBACK вызовите несуществующую функциию.
|
|||
|
||||
| UsamaBrainLaden |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 39 Регистрация: 10.11.2008 Репутация: нет Всего: нет |
Действительно работает))
я правда немного неправильно написал триггер:
просто выдается ошибка о несуществующей функции и запись остается во своясе, а для пользователя - владельца записи процесс удаления проходит нормально, тока сами понимаете это же не выход, как-то не по русски получается! |
|||
|
||||
| sir_nuf_nuf |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 920 Регистрация: 6.1.2008 Репутация: 8 Всего: 31 |
UsamaBrainLaden, да пожалуй не по-русски. но судя по форумам и докам
А) CHECK в MySQL пока что не реализован Б) exceptions тоже не реализованы. Хотя это обычный способ сообщать о нарушениях бизнес правил на уровне БД. Есть костыли для реализации Exceptions. один из них я вам показал. Еще как вариант - писать UDF на C. Ищете по форумам.. Но мне кажется что несуществующая функция - приемлемый вариант. Главное имя ей подходящие дайте.., наприрме EMPTY_BALANCE_EXCEPTION. тогда вызов такой функции будет похож на exception
такой вот syntactic sugar |
|||
|
||||
| UsamaBrainLaden |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 39 Регистрация: 10.11.2008 Репутация: нет Всего: нет |
А в какая СУБД поддерживает CHECK?
Главное чтобы она была бесплатная,а ещё лучше чтобы это была другая версия MySQL (даже если она коммерческая). |
|||
|
||||
| sir_nuf_nuf |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 920 Регистрация: 6.1.2008 Репутация: 8 Всего: 31 |
UsamaBrainLaden, странно.. Postgress поддерживает.
Но выбирать БД стоит по другим критериям =) |
|||
|
||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | MySQL | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |