powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Mutating table
14 сообщений из 14, страница 1 из 1
Mutating table
    #32095312
ksukhonosenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть два триггера. В них работает одинаковая логика (только SELECT). Один проходит нормально - другой отвергается ораклом из-за mutating table.

Прочтя руководство и, убедившись в его неправильности, попробовал написать тестовый триггер, который считает количество строк в таблице. Когда в эту таблицу я добавляю INSERT'ом - все ок. DELETE - тоже mutating table error. Вывод, иметь доступ к изменяющейся таблице можно, это же подтверждает и один из оригинальных триггеров.

Как с этим бороться? Селекты триггеров отличаются только одной таблицей. Эти таблицы (отличиющиеся) не ссылаются ни на кого, и никто на них не ссылается так же.
...
Рейтинг: 0 / 0
Mutating table
    #32095339
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Припоминаю я, что в 7-ке мы как-то делали select из этой же таблице в триггере after insert for each row. Может это ложное воспоминание, но для 9i я не верю в "неправильность руководства": "A mutating table is a table that is currently being modified by an UPDATE, DELETE, or INSERT statement":
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
SQL> create table test (
   2         test_id number( 9 )
   3       , constraint pk_test primary key (test_id)
   4   )
   5   /

Table created

SQL> insert into test (test_id) values ( 1 );

 1  row inserted

SQL> create or replace trigger taiudr_test
   2   after insert or update or delete on test
   3   for each row
   4   declare v_count integer;
   5   begin
   6     select count(*) into v_count from test;
   7     dbms_output.put_line('taiudr_test: count='||v_count||';');
   8   end;
   9   /

Trigger created

SQL> insert into test (test_id) values ( 2 );

insert into test (test_id) values ( 2 )

ORA- 04091 : table DAN.TEST is mutating, trigger/function may not see it
ORA- 06512 : at "DAN.TAIUDR_TEST", line  3 
ORA- 04088 : error during execution of trigger 'DAN.TAIUDR_TEST'

SQL> update test set test_id = - 1  where test_id  =  1 ;

update test set test_id = - 1  where test_id  =  1 

ORA- 04091 : table DAN.TEST is mutating, trigger/function may not see it
ORA- 06512 : at "DAN.TAIUDR_TEST", line  3 
ORA- 04088 : error during execution of trigger 'DAN.TAIUDR_TEST'

SQL> delete test where test_id =  1 ;

delete test where test_id =  1 

ORA- 04091 : table DAN.TEST is mutating, trigger/function may not see it
ORA- 06512 : at "DAN.TAIUDR_TEST", line  3 
ORA- 04088 : error during execution of trigger 'DAN.TAIUDR_TEST'
Либо мы говорим о разных вещах.
...
Рейтинг: 0 / 0
Mutating table
    #32095344
ksukhonosenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
1.
2.
3.
CREATE TABLE DMSLOG ( 
  MESSAGE    VARCHAR2 ( 255 ) CONSTRAINT NAME   NOT NULL, 
  TIMESTAMP  NUMBER)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
CREATE OR REPLACE TRIGGER trig_OnLog
BEFORE INSERT OR UPDATE ON DMSLOG
FOR EACH ROW
DECLARE 
	 cnt NUMBER;
BEGIN
	 select count(*) into cnt from DMSLOG;
	 DBMS_OUTPUT.PUT_LINE('Hello from trigger. Count = ' || cnt);
END;
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
delete from dmslog where timestamp =  123 ;
insert into dmslog values('sdf', 123 );
insert into dmslog values('sdf', 123 );

---

Hello from trigger. Count =  1 
Hello from trigger. Count =  2 
...
Рейтинг: 0 / 0
Mutating table
    #32095352
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У тебя BEFORE UPDATE, у меня AFTER UPDATE. Имхо получается, что фразу "A mutating table is a table that is currently being modified" следует понимать так: таблица, которая _изменена_ (или изменяется) к настоящему времени. Во время выполнения триггера BEFORE UPDATE данные таблицы еще не меняются. Такой триггер дает ответ на вопрос: сколько записей было перед изменением, не после. Выполнив твой скрипт, я получил:

Hello from trigger. Count = 0
Hello from trigger. Count = 1
...
Рейтинг: 0 / 0
Mutating table
    #32095358
ksukhonosenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
По этой логике, что должен выдавать триггер BEFORE DELETE? Можешь проверить - ошибку.
...
Рейтинг: 0 / 0
Mutating table
    #32095369
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хм, вот это уже интересно. И update тоже не идет. Получается следующее: прочитать данные из таблицы можно только в триггере BEFORE INSERT при вставке (insert) записей. Все остальное приводит к мутации, это если говорить про row-level триггера. Значит, я не до конца еще понял документацию, но по-крайней мере конкретизировалась ситуация.
...
Рейтинг: 0 / 0
Mutating table
    #32095375
ksukhonosenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Блин! У меня документация другая.
...
Рейтинг: 0 / 0
Mutating table
    #32095376
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вот и ответ: http://technet.oracle.com/doc/server.815/a68003/01_13dbt.htm#786
Обрати внимание на фразу:
There is an exception to this restriction: For a single row INSERT, constraining tables are mutating for AFTER row triggers, but not for BEFORE row triggers. INSERT statements that involve more than one row, such as INSERT INTO Emp_tab SELECT..., are not considered single row inserts, even if they only result in one row being inserted.
...
Рейтинг: 0 / 0
Mutating table
    #32095388
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Последнюю ссылку я взял отсюда: http://asktom.oracle.com/~tkyte/Mutate/index.html
...
Рейтинг: 0 / 0
Mutating table
    #32095525
SAA_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А потом пойдут вопросы... а почему ошибка мутации вылетает снова при конструкции (триггер на таблицу а):

insert into a (a, b, c) select a, b, c from d;
...
Рейтинг: 0 / 0
Mutating table
    #32095691
ksukhonosenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ты это к чему?

На самом деле, для меня странно, почему бы пользователю не дать возможность читать значения :old. Да и :new тоже. К каким проблемам, например, это может привести? А если и есть такие проблемы, то надо о них сказать и развязать пользователю руки (или как-то синтаксис инструкции подправить или опцию сделать).

Что скажет умудренная опытом публика?

Почему нельзя, скажем, с помощью триггера проверить некоторе условие по данным в таблице и разрешить/запретить текущую операцию?
...
Рейтинг: 0 / 0
Mutating table
    #32095707
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ответ имхо будет сродни прозвучавшему в фидо по поводу одноименных таблиц и public synonym'а, о том, как достучаться к последнему. Если стоит задача анализа и разрешения/запрета изменений таблицы, то из того, что она не решается при помощи одного триггера, совсем не следует, что она не решается вообще. Просто не надо зацикливатся именно на таком решении, других вариантов масса.

Если из доки на 9i выкинули описание ситуации, когда мутация не происходит, значит, есть на то причины. Может когда-нибудь мутация проявится и в этой исключительной ситуации, а пока, начиная с 8.1.7 это - недокументированная фича, как select for update skip locked.

А про :old и :new мне непонятно- почему их нельзя читать?
...
Рейтинг: 0 / 0
Mutating table
    #32095723
ksukhonosenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да "вообще"-то я ее решил, конечно. Просто мне показалось странным, что с помощью триггера этого нельзя сделать.

Про :old \:new - это меня склинило. Сорри. Я имел в виду доступ ко всей таблице.

А дока у меня 8.1.6.

А какими проблемами чреват доступ на чтение к mutating таблице?
...
Рейтинг: 0 / 0
Mutating table
    #32095740
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ты имеешь в виду, откуда вообще взялась эта самая мутация? Скорее это вопрос следует адресовать к самим разработчикам Оракла, к горячим индийским парням:)
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Mutating table
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]