Mutating Table in Oracle 11 caused by a function

后端 未结 2 452
我在风中等你
我在风中等你 2021-01-17 11:10

We\'ve recently upgraded from Oracle 10 to Oracle 11.2. After upgrading, I started seeing a mutating table error caused by a function rather than a trigger (which I\'ve nev

相关标签:
2条回答
  • 2021-01-17 11:20

    Statement-Level Read Consistency and Transaction-Level Read Consistency".

    From the manual:

    "If a SELECT list contains a function, then the database applies statement-level read consistency at the statement level for SQL run within the PL/SQL function code, rather than at the parent SQL level. For example, a function could access a table whose data is changed and committed by another user. For each execution of the SELECT in the function, a new read consistent snapshot is established".

    Both concepts are explained in the "Oracle® Database Concepts" :

    http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/consist.htm#sthref1955


    ->>> UPDATE

    ->>>*Section added after the OP was closed

    The rule

    The technical rule , well linked by Mr Kemp(@jeffrey-kemp) and well explained by Toon Koppelaars here, is reported in "Pl/Sql language reference - Controlling Side Effects of PL/SQL Subprograms"(your function violates RNDS reads no database state):

    When invoked from an INSERT, UPDATE, or DELETE statement, the function cannot query or modify any database tables modified by that statement.

    If a function either queries or modifies a table, and a DML statement on that table invokes the function, then ORA-04091 (mutating-table error) occurs.

    PL/SQL Functions that SQL Statements Can Invoke

    0 讨论(0)
  • 2021-01-17 11:28

    Firstly,

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

    Does not start an infinite loop, because the query will not see the data that was inserted - only data that existed as of the start of the statement. The new rows will only be visible to subsequent statements.

    This explains it quite well:

    When Oracle steps out of the SQL-engine that's currently executing the update statement, and invokes the function, then this function -- just like an after row update trigger would -- sees the intermediate states of EMP as they exist during execution of the update statement. This implies that the return value of our function invocations heavily depend on the order in which the rows happen to be updated.

    0 讨论(0)
提交回复
热议问题