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) 

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


Sergey13   (2006-09-07 08:19:00) [1]

> [75] Petr V. Abramov ©   (06.09.06 22:05)

Хм. А у меня 8.1.7 съел и не подавился.


Petr V. Abramov   (2006-09-06 22:05:00) [2]

> Не знаю как этот случай описан в базовых принципах, а Оракл без
> специального аттрибута в ключе тоже по рукам даст за такое.
 и по умолчанию бьет. dererrable initially defrerred появилось только в 8-ке (и, что странно, в той же версии оно уже работало :)


Desdechado   (2006-09-06 15:39:00) [3]

>  поле с уникальным индексом. делаем update sometable set unq_field = unq_field + 1
Смысл этого запроса?


evvcom   (2006-09-06 15:01:00) [4]

> [72] Андрей Пазик   (06.09.06 14:43)

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


Андрей Пазик   (2006-09-06 14:43:00) [5]

IB/FB вообще нарушает базовые принципы SQL. Например. Есть у вас поле с уникальным индексом. делаем update sometable set unq_field = unq_field + 1
И получаем детскими граблями! Потому что ограничения целостности проверяются тут на onrowChange, а не на onStatementFinish.


Petr V. Abramov   (2006-09-06 14:05:00) [6]

> ANB ©  
 если интересует, что там происходит "во время выполнения оператора", то
1. сделай триггер, который после изменения двух-трех записей повесит сессию (dbms_lock.sleep)
2. поизучай заголовки блоков (v$bh). вечерком могу поискать, как скинуть дамп блока в trace, сейчас просто убегаю.
Счастливых анатомических исследований :)))


Petr V. Abramov   (2006-09-06 13:37:00) [7]

> ПОСЛЕ оператора до коммита в таблице лежат новые данные, в RBS -
> старые. А вот где что лежит во время выполнения оператора - х.з. (знаний маловато).
 в RBS лежат change vectors, изменения данных. А "во время измения" - в тех блоках, которые уже поменялись - новые данные, в которых еще не поменялись - старые :) Второй свежести данных не бывает :) То есть триггер в процеесе выполнения запроса относительно легко может получить старые данные (обычным consistent read, небесплатной процедурой), а новые - никак, потому что не все блоки еще обновились. Может, еще именно из-за consistent read не стали они связываться и сделали выдачу ошибки, тем более, что про винигрет уже много тут говорилось


ANB   (2006-09-06 10:43:00) [8]


> evvcom ©   (06.09.06 10:35) [68]
> > [67] ANB ©   (06.09.06 10:31)
>
> Ну сделай табличку в пакете, в нее пиши изменения, а в автономной
> внешне джойни ее с оригинальной. И будет тебе все, как хочешь.
>

Способов изгала то много. Для проверки на целостность дерева можно и стандартным обходом обойтись. Можно и вообще триггера не использовать.
И запретить использовать функции в DML.


evvcom   (2006-09-06 10:35:00) [9]

> [67] ANB ©   (06.09.06 10:31)

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


ANB   (2006-09-06 10:31:00) [10]


> А зря, менеджеров, не устраивает, в 99% случаев.

Менеджерам важны данные в отчетах и гриде. Триггер их никак волновать не должен. А если по логике триггера мне все равно, в каком порядке изменяются данные, главное - чтобы давали читать уже измененные ?


evvcom   (2006-09-06 10:27:00) [11]

> [51] ANB ©   (05.09.06 17:44)
> А вот где что лежит во время выполнения оператора - х.з.
> (знаний маловато).

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

> [53] Desdechado ©   (05.09.06 19:15)

Поддерживаю.

> [56] ANB ©   (05.09.06 19:40)
> Но эта прагма автоматически включает чтение старых данных.

Она не включает. Просто автономной транзакции не доступны изменения, сделанные в первичной транзакции, а потому для нее
таблица неизменяется.


ANB   (2006-09-06 09:21:00) [12]


> tesseract ©   (06.09.06 00:08) [62]

Во. Наконец то опытный спец пришел. Как чувствовал, что просто забили на баг, оформили исключением и сделали его фичей.

> (сабж - не глюк :),
- конечно, не глюк - глюк, это непойманный баг. А пойманный, заткнутый и документированный - это уже фича.

Продолжил эксперименты :

При наличии указанных выше таблиц и триггера (без прагмы) вот это работатет :

insert into table2 (ID, Parent_ID, Status)
values (10001, 1, 2)

insert into table2 (ID, Parent_ID, Status)
select 10002, 1, 3 from dual

insert into table2 (ID, Parent_ID, Status)
select rownum + 10010, rownum + 10010 - 1, decode(mod(rownum,2),0,4,5) from dual
connect by level <= 1000

А вот это - уже нет :
update table2 T2
set Status = t2_prev_status(t2.PARENT_ID)
where ID = 1

Кстати, в похожей ситуации на 8-ке инсерт нескольких записей не работал. Так что есть надежда, что таки потихоньку доведут до ума.

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


Petr V. Abramov   (2006-09-06 01:44:00) [13]

да ладно. много много в Oracle несовершенства, но у него есть такое же гадкое св-во, как у Windows - люди матерятся на глюки (сабж - не глюк :), но на другие продукты не переходят :)


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

> Как-раз таки технические проблемы ИМХО здесь и есть, с ними вроде
> только DB2 в состояниии справиться.
 тот же FB пожеланиям  некотрых трудящихся удовлетворяет. А в чем, на Ваш взгляд, технические проблемы-то? Давайте погадаем :)

> пока не подтвердишь данные можно считать старые.
 только это небесплатно в плане ресурсов-то


tesseract   (2006-09-06 00:08:00) [15]

> Выгоднее делать новые фичи, чем Ларри успешно занимается.


да нет в моде упрощёнка, а на кой он MySQL к рукам прибрал?


> я не могу селекать в триггере изменяющуюся таблицу ?


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


> Есно, при триггере уровня строки у меня селект завалится.
> Однако, если бы он не завалился, а возвращал мне смесь новых
> и старых строк - это бы меня вполне устроило.


А зря, менеджеров, не устраивает, в 99% случаев.


> Вот в IB она никогда не мутирует в режиме ReadCommitted.


ReadCommited для того и создан, максимум производительности при минимуме проблем. Фактически неявная неблокирующая транзакция, пока не подтвердишь данные можно считать старые.


> > что оракл просто по техническим причинам (из-за существующего
>
> > механизма транзакций) не готов работать с измененными/удаленными
>
> > записями в рамках одного оператора.
> на мое ИМХО технических проблем нет. Такой же Plssql-ный
> объект, как и ХП и пакет. А от plssql до мехпнизма управления
> транзакциями - 2 лаптя по карте. Работает-то он все равно
> в терминах блоков. Может, конечно просто поленились к релизу
> глючок какой исправить, и оказалось, что оно на надо, пусть
> так живет, приложения надежней будут


Как-раз таки технические проблемы ИМХО здесь и есть, с ними вроде только DB2 в состояниии справиться.


Petr V. Abramov   (2006-09-05 23:40:00) [16]

> С триггерами можно и руками подправить, если они корректно написаны. А
> вот с ХП можно нарваться и на поломку целостности, если кто-то из
> любителей поправить руками (ну я, например) вдруг не знает, что делать
> это с данной таблицей категорически запрещается.
 это уже оргметодами решается. т.е любители подправить руками, которые не знают, не должны иметь возможность это сделать. А необходимость сия на моей памяти возникала только в случае, когда облажались с кодом и надо быстро привести базу в состояние, когда она в целости и непротиворечивости.
 Проблема чуть глубже. вотя как кодер, когда говорю update, знаю, что поменяются записи в соответствии с set и where, и больше ничего. А так прежде чем писать update, теоретически должен предугадать фантазию триггерописателей на срок службы системы. Проблема ессно вылезает, когда таблица стоИт на грани полномочий двух разработчиков.

> что оракл просто по техническим причинам (из-за существующего
> механизма транзакций) не готов работать с измененными/удаленными
> записями в рамках одного оператора.
 на мое ИМХО технических проблем нет. Такой же Plssql-ный объект, как и ХП и пакет. А от plssql до мехпнизма управления транзакциями - 2 лаптя по карте. Работает-то он все равно в терминах блоков. Может, конечно просто поленились к релизу глючок какой исправить, и оказалось, что оно на надо, пусть так живет, приложения надежней будут


ANB   (2006-09-05 19:54:00) [17]

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


ANB   (2006-09-05 19:51:00) [18]

CREATE OR REPLACE TRIGGER tr_table2
  BEFORE UPDATE
  ON table2
  FOR EACH ROW
DECLARE
  PRAGMA AUTONOMOUS_TRANSACTION;
  v_cnt   INTEGER;
BEGIN
  SELECT COUNT (*)
    INTO v_cnt
    FROM table2 t2
   WHERE t2.parent_id = :NEW.parent_id;
END;

Вот этот триггер работает. Убираем прагму - валится.


> если надо будет откатить всю транзакцию, а не отдельные
> ее автономности?

Что откатывать после селекта ?
Кстати, таки доп. неудобство. Мало того, что я не могу производить проверки с учетом уже измененных записей (хотя всего одна то меняется, здесь то зачем мутация ?), так еще изменять данный в общем контексте транзакции не смогу.


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


Desdechado   (2006-09-05 19:46:00) [19]

> Функция перестала падать.
А теперь подумай, что будет, если надо будет откатить всю транзакцию, а не отдельные ее автономности?
И ты поймешь, что заблуждался относительно "решения пролемы". Ты ее только замаскировал и углубил.


Val   (2006-09-05 19:44:00) [20]

>включает чтение старых данных
может, отключает чтение новых?


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

Наверх

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