此问题与我的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
搜索并发现它是因为与INSERT
,UPDATE
或DELETE
和DUAL
发生冲突。
有没有其他方法可以在返回表的函数中执行我的过程?
谢谢!
答案 0 :(得分:2)
没有;由于很好的理由,无法在SELECT语句中执行DML。
您正在更改数据库中的数据,而Oracle需要一个读取一致的数据视图,即它需要知道您所选择的内容并未因您选择的内容而改变。
你所做的事听起来非常不必要;你有一个3步骤的过程:
为什么不简单地选择您需要的数据;它会快得多吗?如果您必须预先处理数据,那么您可以拥有一个与选择数据异步执行此操作的过程。
我对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'));
谢谢,无论如何,对于那些回应和帮助我的人。 :)