ora-04091 table is Mutating-

谁都会走 提交于 2019-12-02 23:37:23

问题


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;

回答1:


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;



回答2:


You might consider using a temporary table, I.E.:

create global temporary table table12_gt(empname varchar2(30), is_changed char(1));

CREATE OR REPLACE PROCEDURE updatetabble1_2 AS
  BEGIN
   insert into table12_gt
    select empname,
           CASE
             WHEN count(v) > 1 THEN
              'Y'
             ELSE
              'N'
           END is_changed
      from (SELECT empname, trim(column1 || column2 || column3) v
              FROM table1
            UNION
            SELECT empname, trim(column1 || column2 || column3) v FROM table2)
     GROUP BY empname;

  MERGE INTO Table1 DBC
  USING (SELECT empname, is_changed as DATA_CHANGED FROM table12_gt) TBL_MAIN
  ON (DBC.empname = TBL_MAIN.empname)
  WHEN MATCHED THEN
    UPDATE SET DBC.DATA_CHANGED = TBL_MAIN.DATA_CHANGED;

  COMMIT;
END updatetabble1_2;

This quite "quick and dirty" but can be a start



来源:https://stackoverflow.com/questions/19150671/ora-04091-table-is-mutating

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!