PLSQL:ORA-14551:无法在查询内执行DML操作

时间:2019-03-12 05:53:23

标签: oracle plsql

我经历了下面已经提到的一些已经回答的问题,但是找不到适合我的解决方案。

ORA-14551: cannot perform a DML operation inside a query

ORA-14551: cannot perform a DML operation inside a query error while using Execute immediate

我已经在我从过程中调用的函数中编写了此代码。

OPEN c_rules_details;
            LOOP
                FETCH c_rules_details INTO rule_conditions_record;
                EXIT WHEN c_rules_details %notfound;                
                dbms_output.put_line('Range and rule is  '|| rule_conditions_record.rdr_tmplt_id || rule_conditions_record.rdr_rng_from ||rule_conditions_record.rdr_rng_to); 
                SELECT COUNT(*) INTO v_balance_records FROM t_scb_temp_objects WHERE RULE_CONDITION=rule_conditions_record.rdr_tmplt_id AND CHARGE is NULL;
                dbms_output.put_line('Number of records in rule are  '|| v_balance_records); 
                IF v_balance_records>rule_conditions_record.rdr_rng_from AND v_balance_records<rule_conditions_record.rdr_rng_to THEN
                    v_ssql_stmnt:='UPDATE t_scb_temp_objects
                    SET CHARGE='||rule_conditions_record.rfr_chrg_amt||' WHERE RULE_CONDITION='||rule_conditions_record.rdr_tmplt_id;

                    EXECUTE IMMEDIATE v_ssql_stmnt;
                END IF;
            END LOOP;
        CLOSE   c_rules_details;

1 个答案:

答案 0 :(得分:1)

这就是您所知道的-您无法在所使用的函数中执行DML(就您的情况而言,UPDATE t_scb_temp_objects ...)(以某种方式-您没有显示方法 )从过程中调用。那可能是-例如:

create or replace function f_test (par_deptno in number)
  return number 
is
  ...
begin
  open c_rules_details;
  loop
    -- your current code goes here
    execute immediate v_sql_stmnt;
  end loop;
  return 1;
end;

create or replace procedure p_test is
  l_ename emp.ename%type;
begin
  select e.ename 
    into l_ename
    from emp e
    where e.deptno = f_test(e.deptno);        --> this will cause the error
end;

那该怎么办?从过程而不是函数中执行UPDATE

如果必须是一个函数,则使其成为一个自主事务(使用PRAGMA),但是我不建议这样做。您希望找出一些不同的东西。不过,方法如下:

SQL> create table test (col number);

Table created.

SQL> insert into test (col) values (100);

1 row created.

SQL> commit;

Commit complete.

首先,一个会失败的函数(就像您的函数一样):

SQL> create or replace function f_test return number is
  2  begin
  3    update test set col = 10;
  4    commit;
  5    return 1;
  6  end;
  7  /

Function created.

SQL> select f_test from dual;
select f_test from dual
       *
ERROR at line 1:
ORA-14551: cannot perform a DML operation inside a query
ORA-06512: at "SCOTT.F_TEST", line 3

现在,将会成功的人:

SQL> create or replace function f_test return number is
  2    pragma autonomous_transaction;                        --> this
  3  begin
  4    update test set col = 10;
  5    commit;
  6    return 1;
  7  end;
  8  /

Function created.

SQL> select f_test from dual;

    F_TEST
----------
         1

SQL> select * from test;

       COL
----------
        10

SQL>

再次:您可能不想这样做。