执行函数内的过程(ORA-14551错误)

时间:2013-02-12 06:11:49

标签: oracle function procedure dml

此问题与我的previous question有关。

我有一个程序(PROC_YEARLYACTIVELIST2),它将显示在指定年份有效的所有记录 它将删除TBLACTIVELISTYEARLY2的先前内容并插入PROC_YEARLYACTIVELIST2的结果
我创建了一个将执行TBLACTIVELISTYEARLY2的函数,从TBLACTIVELISTYEARLY中选择所有记录并将其放入CURSOR C_IH,然后返回Crystal Report的表格。

以下只是代码的一部分:


DECLARE
  CURSOR C_IH IS SELECT * FROM tblActiveListYearly2;

  ctr INT;
  i NUMBER;  
  currDeploymentComputer COL_TYPE_DEPLOYMENT_COMPUTER := COL_TYPE_DEPLOYMENT_COMPUTER NULL);
  R_IH C_IH%ROWTYPE;

 BEGIN
 PROC_YEARLYACTIVELIST2(in_year);

  OPEN C_IH;
   i := 0;
    LOOP (....)

我试图将该功能称为

SELECT GETDEPLOYMENT_COMPUTER('2012') from dual;

发生ORA-14551错误

ORA-14551: cannot perform a DML operation inside a query 
ORA-06512: at "NPLS.PROC_YEARLYACTIVELIST2", line 12
ORA-06512: at "NPLS.GETDEPLOYMENT_COMPUTER", line 3

搜索并发现它是因为与INSERTUPDATEDELETEDUAL发生冲突。

有没有其他方法可以在返回表的函数中执行我的过程?

谢谢!

3 个答案:

答案 0 :(得分:2)

没有;由于很好的理由,无法在SELECT语句中执行DML。

您正在更改数据库中的数据,而Oracle需要一个读取一致的数据视图,即它需要知道您所选择的内容并未因您选择的内容而改变。

你所做的事听起来非常不必要;你有一个3步骤的过程:

  1. 从表中删除一些数据
  2. 将新数据插入该表
  3. 从表中选择数据。
  4. 为什么不简单地选择您需要的数据;它会快得多吗?如果您必须预先处理数据,那么您可以拥有一个与选择数据异步执行此操作的过程。

    我对Crystal Reports一无所知,但您也可以在PL / SQL块中执行此操作。

    declare
       l_getdeployment my_variable_type;
    begin
       l_getdeployment := GETDEPLOYMENT_COMPUTER('2012');
    end;
    /
    

答案 1 :(得分:1)

我认为您需要将DML更改和报告部分分开。应在报告函数调用之外调用执行数据更改的过程...

答案 2 :(得分:0)

这太复杂了 由于我想从表格到水晶报告中获取记录,我将我选择的内容放到表格中
现在,我意识到我可以将我的过程中的逻辑放入函数中,将其放入SYS_REFCURSOR,返回并使用此查询调用函数:

SELECT * FROM TABLE(GETDEPLOYMENT_COMPUTER('2012'));

谢谢,无论如何,对于那些回应和帮助我的人。 :)