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

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

Как с этим бороться? Селекты триггеров отличаются только одной таблицей. Эти таблицы (отличиющиеся) не ссылаются ни на кого, и никто на них не ссылается так же.
...
Рейтинг: 0 / 0
23.01.2003, 16:06
    #32095339
Denis Popov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Mutating table
Припоминаю я, что в 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
23.01.2003, 16:16
    #32095344
ksukhonosenko
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Mutating table
Код: 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
23.01.2003, 16:25
    #32095352
Denis Popov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Mutating table
У тебя 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
23.01.2003, 16:41
    #32095358
ksukhonosenko
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Mutating table
По этой логике, что должен выдавать триггер BEFORE DELETE? Можешь проверить - ошибку.
...
Рейтинг: 0 / 0
23.01.2003, 16:53
    #32095369
Denis Popov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Mutating table
Хм, вот это уже интересно. И update тоже не идет. Получается следующее: прочитать данные из таблицы можно только в триггере BEFORE INSERT при вставке (insert) записей. Все остальное приводит к мутации, это если говорить про row-level триггера. Значит, я не до конца еще понял документацию, но по-крайней мере конкретизировалась ситуация.
...
Рейтинг: 0 / 0
23.01.2003, 16:58
    #32095375
ksukhonosenko
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Mutating table
Блин! У меня документация другая.
...
Рейтинг: 0 / 0
23.01.2003, 16:58
    #32095376
Denis Popov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Mutating table
А вот и ответ: 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
23.01.2003, 17:09
    #32095388
Denis Popov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Mutating table
Последнюю ссылку я взял отсюда: http://asktom.oracle.com/~tkyte/Mutate/index.html
...
Рейтинг: 0 / 0
23.01.2003, 19:23
    #32095525
SAA_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Mutating table
А потом пойдут вопросы... а почему ошибка мутации вылетает снова при конструкции (триггер на таблицу а):

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

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

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

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

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

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

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

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

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


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