Recientemente hemos actualizado de Oracle 10 a Oracle 11.2. Después de la actualización, comencé a ver un error de tabla de mutación causado por una función en lugar de un disparador (que nunca he encontrado antes). Es código antiguo que funcionaba en versiones anteriores de Oracle.Tabla de Mutación en Oracle 11 causada por una función
He aquí un escenario que hará que el error:
create table mutate (
x NUMBER,
y NUMBER
);
insert into mutate (x, y)
values (1,2);
insert into mutate (x, y)
values (3,4);
He creado dos filas. Ahora, voy a duplicar mis filas llamando a esta declaración:
insert into mutate (x, y)
select x + 1, y + 1
from mutate;
Esto no es estrictamente necesario duplicar el error, pero ayuda con mi demostración más tarde. Entonces el contenido de la tabla ahora se ve así:
X,Y
1,2
3,4
2,3
4,5
Todo está bien. Ahora, para la parte divertida:
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;
/
He creado una función para consultar mi tabla y devolver un conteo. Ahora, combinaré eso con una instrucción INSERT:
insert into mutate (x, y)
select x + 2, y + 2
from mutate
where mutate_count() = 4;
¿El resultado? Este error:
ORA-04091: table MUTATE is mutating, trigger/function may not see it
ORA-06512: at "MUTATE_COUNT", line 6
así que sé lo que causa el error, pero estoy curioso en cuanto a por qué el . ¿Oracle no está ejecutando SELECT, recuperando el conjunto de resultados, y luego realizando una inserción masiva de esos resultados? Solo esperaría un error de tabla mutante si los registros ya se estaban insertando antes de que la consulta finalizara. Pero si Oracle hizo eso, no lo haría la declaración anterior:
insert into mutate (x, y)
select x + 1, y + 1
from mutate;
empezar un bucle infinito?
ACTUALIZACIÓN:
a través del enlace de Jeffrey encontré esto en the Oracle docs:
By default, Oracle guarantees statement-level read consistency. The set of data returned by a single query is consistent with respect to a single point in time.
Hay también un comentario del autor en his post:
One could argue why Oracle doesn't ensure this 'statement-level read consistency' for repeated function calls that appear inside a SQL statement. It could be considered a bug as far as I'm concerned. But this is the way it currently works.
Estoy en lo cierto al suponer que este el comportamiento ha cambiado entre las versiones de Oracle 10 y 11?
¡Buen enlace, gracias! Voy a actualizar mi pregunta y dejarla abierta un momento para ver si genera alguna discusión adicional. –
+1 usted entendió por qué sucede – zep
Esto ayudó, pero tiene una pregunta de aclaración ... ¿Puede la función existir en un paquete que se llama desde un activador de actualización anterior? Estoy teniendo una pesadilla de problemas como muchos otros debido a los desencadenantes de mierda de Oracles. –