Search code examples
oracle-databaseora-04091

ora-04091 table is Mutating-


I'm using a function which compares all the columns in Table 1 and Table 2 and returns 'Y' or 'N'. Based on that, I will update my Table 1.

But when I run the merge statement it displays an error:

ora-04091 - Table1 is mutating, trigger/function may not see it

How can I fix this?

CREATE OR REPLACE function  DataChange  (in_epmname varchar2) return char  is
    v_epmname   table2.empname%type;
    v_DATA_COUNT  varchar2(2);
    v_DATA_CHANGED  char;
begin
    SELECT COUNT (*) into v_DATA_COUNT
    FROM
    (
        SELECT trim(column1||column2||column3)
        FROM table1
        WHERE empname  =  in_epmname
        UNION
        SELECT trim(column1||column2||column3)
        FROM table2
        WHERE empname = in_epmname
    );
    If (v_DATA_COUNT = '1' ) Then
        v_DATA_CHANGED :='N';
    else
        v_DATA_CHANGED :='Y';
    end if;
    return v_DATA_CHANGED;
end DataChange  ;

The merge statement that I'm using is:

CREATE OR REPLACE PROCEDURE updatetabble1 AS
BEGIN
    MERGE
        INTO Table1 DBC
        USING  ( SELECT
            empname,
            DataChange(empname) as DATA_CHANGED
            FROM employee
        ) TBL_MAIN
        ON ( DBC.empname = TBL_MAIN.empname    )
        WHEN MATCHED THEN
          UPDATE SET
          DBC.DATA_CHANGED = TBL_MAIN.DATA_CHANGED;
    COMMIT;     
END updatetabble1;

Solution

  • Chade i tried this Option it didnt throw me any error.

    CREATE OR REPLACE PROCEDURE updatetabble1 AS
        BEGIN
            MERGE
            INTO Table1 DBC
            USING  (            Select ename from
                (
                Select ename
                from
                    (
                    Select ename, column1||Column2||Column3 from table1
                    union
                    Select ename, column1||Column2||Column3 from table2 
                    ) 
                ) 
            GROUP BY ename HAVING count(*) > 1
            ) TBL_MAIN
                     ON ( DBC.empname = TBL_MAIN.empname)
                    WHEN MATCHED THEN
     UPDATE SET DBC.DATA_CHANGED = 'Y';
    COMMIT;     
    END updatetabble1;