Abbiamo recentemente aggiornato da Oracle 10 a Oracle 11.2. Dopo l'aggiornamento, ho iniziato a vedere un errore di tabella mutante causato da una funzione piuttosto che da un trigger (che non ho mai visto prima). È il vecchio codice che funzionava nelle versioni precedenti di Oracle.Tabella muting in Oracle 11 causata da una funzione
Ecco uno scenario che causerà l'errore:
create table mutate (
x NUMBER,
y NUMBER
);
insert into mutate (x, y)
values (1,2);
insert into mutate (x, y)
values (3,4);
ho creato due file. Ora, io raddoppiare i miei file chiamando questa affermazione:
insert into mutate (x, y)
select x + 1, y + 1
from mutate;
Questo non è strettamente necessario duplicare l'errore, ma si aiuta con la mia dimostrazione più tardi. Quindi il contenuto della tabella ora appare così:
X,Y
1,2
3,4
2,3
4,5
Tutto va bene. Ora per la parte divertente:
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;
/
Ho creato una funzione per interrogare la mia tabella e restituire un conteggio. Ora, lo combinerò con una dichiarazione INSERT:
insert into mutate (x, y)
select x + 2, y + 2
from mutate
where mutate_count() = 4;
Il risultato? Questo errore:
ORA-04091: table MUTATE is mutating, trigger/function may not see it
ORA-06512: at "MUTATE_COUNT", line 6
Quindi so che cosa causa l'errore, ma sono curioso di sapere il motivo per cui . Oracle non sta eseguendo SELECT, recuperando il set di risultati e quindi eseguendo un inserimento di questi risultati? Mi aspetterei solo un errore di tabella mutante se i record fossero già stati inseriti prima della fine della query. Ma se Oracle ha fatto questo, non sarebbe la dichiarazione precedente:
insert into mutate (x, y)
select x + 1, y + 1
from mutate;
avviare un ciclo infinito?
UPDATE:
tramite link di Jeffrey Ho trovato questo in 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.
C'è anche un commento da parte dell'autore in 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.
Ho ragione nel ritenere che questo comportamento è cambiato tra Oracle versioni 10 e 11?
buon collegamento, grazie! Ho intenzione di aggiornare la mia domanda e lasciarla aperta per un po 'per vedere se genera discussioni aggiuntive. –
+1 hai capito il motivo per cui succede – zep
Questo ha aiutato, ma hai una domanda di chiarimento ... La funzione può esistere in un Pacchetto che viene chiamato da un trigger di aggiornamento precedente? Sto avendo un incubo di problemi come molti altri a causa di oracoli trigger di oracoli. –