Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Кто понимает смысл ошибки "Таблица мутирует" ? [Оракл]


Страницы:   1 2 3 4

ANB ©   (2006-09-04 16:06:00) 

В общем то смысл самой ошибки понятен. И как ее избегать я знаю. А вот смыл ее генерации ? Неужели нельзя ораклу было без нее обойтись ? Почему я не могу селекать в триггере изменяющуюся таблицу ?


kaif   (2006-09-05 16:04:00) [41]

Petr V. Abramov ©   (05.09.06 14:47) [21]
ну так FB ошибку не выдает, а выдает муть.


Приведи пример кода, который выдаст такую муть.
Я готов попробовать.
Зачем зря спорить?

Может я неправ, а прав - ты.

Только учти, что в FB существует большое разнообразие типов транзакций: и wait и nowait и Snapshot и ReadCommitted и RepeatebleRead. И всевозможные лок-конфликты, которые FB успешно отлавливает.

Не знаю, как в ORACLE.

По крайней мере, работая из JAVA, я не смог от ORACLE получить ничего
кроме READ COMMITTED в том смысле, который, как известно периодически "мутирует". Возможно плохо старался.
:)


evvcom   (2006-09-05 16:01:00) [42]

> [33] ANB ©   (05.09.06 15:56)
> В триггере уровня строки этого сделать нельзя.
> Обойти вообще никак, только если вставлять всегда по одной
> строке.

Том Кайт думает по-другому. См. [27] последнее предложение и [30].

> 3) И на закузку. Ошибка мутации может вылезти и без триггеров.

Поподробнее можно?


evvcom   (2006-09-05 15:57:00) [43]

> [29] ANB ©   (05.09.06 15:39)
> Неправильно организовали разделение ID между филиалами,
> а потом уже "исторически сложилось".

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


ANB   (2006-09-05 15:56:00) [44]


> Petr V. Abramov ©   (05.09.06 15:49) [32]

ОК.
1)
Имеем парентовое дерево. ID, ID_Parent.
При добавлении/изменении данных пользователь может умудриться дерево зациклить. Чтобы не дать ему этого сделать, нужно выполнить проверку по своей же таблице. В триггере уровня строки этого сделать нельзя. Этот случай можно разрулить либо триггером уровня оператора (сохранив массив строк) либо вообще изменять данные только через хранимку (там такой проблемы не вылезет).
2) Имеем триггер, который присваивает ID первичному ключу. Т.к. сиквенс зациклен, то в триггере производится обращение к своей таблице для проверки дублирования. При вставке более одной строки за раз триггер падает. Обойти вообще никак, только если вставлять всегда по одной строке.
3) И на закузку. Ошибка мутации может вылезти и без триггеров.


Petr V. Abramov   (2006-09-05 15:49:00) [45]

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


Sergey13   (2006-09-05 15:48:00) [46]

> Ну откуда ж оракл знает, что ты дерево в таблице нарисовал.
> Он только при connect by об этом и узнает.

Наверное ты прав, а мне пригрезилось. Попробовал - получил как ты говоришь.


evvcom   (2006-09-05 15:45:00) [47]

> [29] ANB ©   (05.09.06 15:39)
> А если проблема в уже добавленных/измененных записях ?

И что? Я так понимаю, тебе надо узнать используется такой id или нет? ХП проверит, видит ли она такой id и вернет результат триггеру. Триггер дальше решает, что с этим делать. Хочешь raise сделай, хочешь сиквенс еще дерни и опять в ХП.


ANB   (2006-09-05 15:39:00) [48]


> в отдельной ХП с прагмой автономной транзакции

А если проблема в уже добавленных/измененных записях ?


> Разве? Помнится (хоть и давно это было) я вроде получал
> ошибку и при апдейте.

Ну откуда ж оракл знает, что ты дерево в таблице нарисовал. Он только при connect by об этом и узнает.


> И что? Не хватило размерности?

За историю фирмы грили, раза три триггера на 0 скидывались.
Неправильно организовали разделение ID между филиалами, а потом уже "исторически сложилось".


Sergey13   (2006-09-05 15:31:00) [49]

> [26] ANB ©   (05.09.06 15:23)
> Только при селекте.
Разве? Помнится (хоть и давно это было) я вроде получал ошибку и при апдейте.

> А т.к. исторически сиквенсы были зацикленными

И что? Не хватило размерности?


evvcom   (2006-09-05 15:29:00) [50]

> [23] ANB ©   (05.09.06 15:02)
> Ни фига они были бы не случайные. Они были бы непредсказуемыми

Согласен.

> Например, если вставляется одна строка и производится проверка
> на дубль ID, то триггер отрабатывает

Заметь, триггер before on each row

> Если же в эту таблицу делаешь вставку хотя бы 2-х строк
> одним инсертом, то триггер падает.

Естественно, на второй записи.
Если тебе пофиг, что вернет селект, то напиши этот селект в отдельной ХП с прагмой автономной транзакции и вызывай ее из своего триггера. Тогда будет все ок.


ANB   (2006-09-05 15:23:00) [51]


> Что-то мне помнится Оракл сам отлавливает зацикливания дерева.

Только при селекте. А мне надо не допустить этой ситуации при изменении данных. Этим же селектом с генерацией ошибки очень удобно ловить.


> Плюс непонятно зачем искать дубль ID

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


Sergey13   (2006-09-05 15:13:00) [52]

> [23] ANB ©   (05.09.06 15:02)

Что-то мне помнится Оракл сам отлавливает зацикливания дерева. Плюс непонятно зачем искать дубль ID? Руками что-ли вводишь?


ANB   (2006-09-05 15:03:00) [53]


> Если же в эту таблицу делаешь вставку хотя бы 2-х строк
> одним инсертом, то триггер падает.

И при этом триггер уровня оператора мне уже не поможет, если мне нужно было в триггере присвоить значение ID.


ANB   (2006-09-05 15:02:00) [54]


> выдал бы СЛУЧАЙНЫЕ данные

Ни фига они были бы не случайные. Они были бы непредсказуемыми, что не есть одно и тоже. Однако, для проверки, например, зацикливания дерева мне бы любые подошли. Кстати, ошибка при некоторых условиях валится даже если меняется всего одна строка (но не всегда). Например, если вставляется одна строка и производится проверка на дубль ID, то триггер отрабатывает. Если же в эту таблицу делаешь вставку хотя бы 2-х строк одним инсертом, то триггер падает.


evvcom   (2006-09-05 14:52:00) [55]

> [13] ANB ©   (05.09.06 09:57)
> оракл - не версионник. Он иммитация версионника.

Ну вот, опять двадцать пять! Что ты понимаешь под термином "версионник"?

> [12] kaif ©   (05.09.06 01:17)
> В версионнике как может таблица мутировать?

А какая разница в версионнике это или нет? Вот так и мутирует. При апдейте нескольких записей, после апдейта первой таблица УЖЕ изменяется и в триггере уровня строки на селекте и получим вышеуказанную ошибку. Зато в триггере после апдейта уровня оператора таблица уже НЕ изменяется и подобной ошибки не будет.

> [18] ANB ©   (05.09.06 14:03)

Так тебе ж селект выдал бы СЛУЧАЙНЫЕ данные, разве ж это не винегрет? Если тебе все равно, что выдаст селект, сделай его из dual хотя бы тогда :)


Petr V. Abramov   (2006-09-05 14:47:00) [56]

> Я не сталкивался с подобным явлением.
 ну так FB ошибку не выдает, а выдает муть.

> каких ? Ну давайте представим, что оракл ошибку убрал и вместо этого
> начал возвращать винегрет. В какой ситуации может что то сломаться ?
 да сломаться-то ничего не сломается. но бред будет.
например в триггере на table1 пишем
select count(*) from t1 where field1=1

потом говорим update t1 set fied1 = 1

что должен возвращать select count(*) на каждой стороке?

зайдем по-другому: а покажите пример задачи, которая решается красиво, если ошибка "убрана", инекрасиво, если ошибка "не убрана".


ANB   (2006-09-05 14:20:00) [57]


> kaif ©   (05.09.06 14:19) [19]

Кстати, а что FB возращает в такой ситуации ?


kaif   (2006-09-05 14:19:00) [58]

2 Petr V. Abramov ©   (05.09.06 13:07) [17]
точно так же мутирует, только ошибку не выдает.
Я не сталкивался с подобным явлением.


ANB   (2006-09-05 14:03:00) [59]


> винигрет будет источником трудноуловимых ошибок.

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


Petr V. Abramov   (2006-09-05 13:07:00) [60]

>  Неужто при старте оракл лезет первым делом в RBS и начинает откат слетевших транзакций ?
 лезет в redo, накатывает его на rbs, и "естественным образом" откатывает. Если под "случаем сбоя" понимать падение пусть по уважительным причинам. А что в этом такого "неужто"?

> Вот в IB она никогда не мутирует в режиме ReadCommitted.
 точно так же мутирует, только ошибку не выдает.

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


Страницы:   1 2 3 4

Наверх

Титульная страница Поиск, карта сайта Написать письмо