【问题标题】:PLSQL : ORA-14551: cannot perform a DML operation inside a queryPLSQL:ORA-14551:无法在查询中执行 DML 操作
【发布时间】:2019-03-12 05:53:22
【问题描述】:

我检查了一些已经回答的问题,如下所述,但找不到适合我的解决方案。

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;

【问题讨论】:

  • 为什么不直接把你的函数变成一个过程呢?

标签: oracle plsql


【解决方案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>

再说一遍:你可能不想这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-08
    • 2011-05-04
    • 1970-01-01
    • 2019-11-05
    • 2012-02-02
    • 2011-11-10
    • 1970-01-01
    相关资源
    最近更新 更多