Мутирующая таблица в Oracle 11, вызванная функцией

Недавно мы обновили Oracle 10 до Oracle 11.2. После обновления я начал видеть ошибку изменяющейся таблицы, вызванную функцией, а не триггером (, с которой я никогда раньше не сталкивался). Это старый код, который работал в предыдущих версиях Oracle.

Вот сценарий, который вызовет ошибку:

create table mutate (
    x NUMBER,
    y NUMBER
);

insert into mutate (x, y)
values (1,2);

insert into mutate (x, y)
values (3,4);

Я создал две строки. Теперь я удвою свои строки, вызвав этот оператор:

insert into mutate (x, y)
select x + 1, y + 1 
from mutate;

Это не обязательно для дублирования ошибки, но это поможет в моей демонстрации позже. Итак, содержимое таблицы теперь выглядит так:

X,Y
1,2
3,4
2,3
4,5

Все хорошо. Теперь самое интересное :

create or replace function mutate_count
return PLS_INTEGER
is
    v_dummy PLS_INTEGER;
begin
    select count(*) 
    into v_dummy
    from mutate;

    return v_dummy;
end mutate_count;
/

. Я создал функцию для запроса моей таблицы и возврата количества. Теперь я объединю это с оператором INSERT :

insert into mutate (x, y)
select x + 2, y + 2
from mutate
where mutate_count() = 4;

. Результат? Эта ошибка:

ORA-04091: table MUTATE is mutating, trigger/function may not see it
ORA-06512: at "MUTATE_COUNT", line 6

Итак, я знаю, что вызывает ошибку, но мне любопытно, почему . Разве Oracle не выполняет SELECT, извлекает набор результатов, а затем , а затем выполняет массовую вставку этих результатов? Я бы ожидал ошибки изменяющейся таблицы только в том случае, если записи уже были вставлены до завершения запроса. Но если бы Oracle сделал это, не запустил бы ли более ранний оператор:

insert into mutate (x, y)
select x + 1, y + 1 
from mutate;

бесконечный цикл?

ОБНОВЛЕНИЕ:

По ссылке Джеффри я нашел это в документации Oracle:

По умолчанию Oracle гарантирует согласованность чтения на уровне оператора-. То набор данных, возвращаемый одним запросом, непротиворечив по отношению к единый момент времени.

Также есть комментарий автора в его посте:

Можно возразить, почему Oracle не гарантирует, что этот «оператор-уровень прочитан». согласованность» для повторяющихся вызовов функций, которые появляются внутри SQL утверждение. Насколько я понимаю, это можно считать ошибкой. Но это то, как это работает в настоящее время.

Правильно ли я предполагаю, что это поведение изменилось между версиями Oracle 10 и 11?

13
задан Dan A. 30 March 2012 в 02:43
поделиться