Reputation: 67
This question is related to my previous question.
I have a procedure(PROC_YEARLYACTIVELIST2
) that will show all records that is active on a specified year.
It will delete the previous contents of TBLACTIVELISTYEARLY2
and insert the result from PROC_YEARLYACTIVELIST2
.
I created a function that will execute TBLACTIVELISTYEARLY2
, Select all records from TBLACTIVELISTYEARLY
and put it into CURSOR C_IH
, and return the table for Crystal Report.
Below is just a part of the code:
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 (....)
I've tried to call the function as
SELECT GETDEPLOYMENT_COMPUTER('2012') from dual;
And has an ORA-14551
error
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
Searched for it and found that it is because of the conflict with INSERT
, UPDATE
or DELETE
and DUAL
.
Is there any other way to execute my procedure in a function that will return a table?
THANKS!
Upvotes: 2
Views: 5768
Reputation: 67
This was so complicated.
For the reason that I want to get records from a table to crystal report, I put what I select to a table.
Now, I realized that I can place the logic from my procedure into the function, put it into a SYS_REFCURSOR
, return it and call the function using this query:
SELECT * FROM TABLE(GETDEPLOYMENT_COMPUTER('2012'));
Thanks, anyways, for those who response and helped me. :)
Upvotes: 0
Reputation: 52863
No; for very good reasons you cannot perform DML in a SELECT statement.
You're changing the data in the database and Oracle needs a read-consistent view of the data, i.e. it needs to know that what you're selecting is not being changed by what you're selecting.
What you're doing sounds highly unnecessary; you've got a 3 step process:
Why not simply select the data you need; it'll be a lot quicker? If you have to pre-process the data then you can have a procedure that does this asynchronously to the selecting of the data.
I don't know anything about Crystal Reports but you can also do this in a PL/SQL block.
declare
l_getdeployment my_variable_type;
begin
l_getdeployment := GETDEPLOYMENT_COMPUTER('2012');
end;
/
Upvotes: 2
Reputation: 3499
I think you need to separate DML changes and reporting part. Procedure that does data changes should be called outside of your report function call...
Upvotes: 1