Solution to “cannot perform a DML operation inside a query”?

后端 未结 3 461
自闭症患者
自闭症患者 2020-12-01 05:19

I am using a Data Analysis tool and the requirement I have was to accept a value from the user, pass that as a parameter and store it in a table. Pretty straighforward so I

相关标签:
3条回答
  • 2020-12-01 05:54

    Just declare a variable to accept the return value, for example:

    declare
        retvar varchar2(4);
    begin
        retvar := supercomplex('somevalue');
    end;
    

    The select doesn't work because the function is performing an insert, if all it did was return a value then it would work.

    0 讨论(0)
  • 2020-12-01 05:58

    Just execute the function in a dummy if ... end if; statement to ignore the return value:

    exec if supercomplex('somevalue') then null; end if;
    

    Or execute it as a parameter for put_line procedure to output the return value:

    exec dbms_ouput ('result of supercomplex='||supercomplex('somevalue'));
    
    result of supercomplex=done
    
    0 讨论(0)
  • 2020-12-01 06:14

    You could use the directive pragma autonomous_transaction. This will run the function into an independant transaction that will be able to perform DML without raising the ORA-14551.

    Be aware that since the autonomous transaction is independent, the results of the DML will be commited outside of the scope of the parent transaction. In most cases that would not be an acceptable workaround.

    SQL> CREATE OR REPLACE FUNCTION supercomplex(datainput IN VARCHAR2)
      2     RETURN VARCHAR2 IS
      3     PRAGMA AUTONOMOUS_TRANSACTION;
      4  BEGIN
      5     INSERT INTO dumtab VALUES (datainput);
      6     COMMIT;
      7     RETURN 'done';
      8  END supercomplex;
      9  /
    
    Function created
    
    SQL> SELECT supercomplex('somevalue') FROM dual;
    
    SUPERCOMPLEX('SOMEVALUE')
    --------------------------------------------------------------------------------
    done
    
    SQL> select * from dumtab;
    
    A
    --------------------------------------------------------------------------------
    somevalue
    

    Tom Kyte has a nice explanation about why the error is raised in the first place. It is not safe because it may depend upon the order in which the rows are processed. Furthermore, Oracle doesn't guarantee that the function will be executed at least once and at most once per row.

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