Ref cursor to table convertor
Hello.
I ask you a favor and I hope you could help me out.
I have a lot of legacy functions that return REF CURSOR.
I'd like to have a generic method that convert a cursor variable to something what I could query with SELECT statement.
select * from TABLE(mypkg.CONVERT(LEGACYFUNCTION()));
Here I give you an example how I can deal with the problem.
But It's easy to see that "mypkg" depends on "ordr" table.
I would like the "mypkg" to be unaware of "ordr" table - it must be generic.
A legacy function looks like this one:
CREATE OR REPLACE FUNCTION LEGACYFUNCTION RETURN SYS_REFCURSOR AS
c SYS_REFCURSOR;
begin
OPEN c FOR SELECT * from ordr;
return c;
end;
Here my package that converts REF CURSOR to something good:
CREATE OR REPLACE PACKAGE mypkg AS
TYPE TabTyp IS TABLE OF ordr%ROWTYPE;
FUNCTION CONVERT(c IN SYS_REFCURSOR) RETURN TabTyp PIPELINED;
end;
CREATE OR REPLACE PACKAGE BODY mypkg AS
FUNCTION CONVERT(c IN SYS_REFCURSOR) RETURN TabTyp PIPELINED AS
data ordr%ROWTYPE;
begin
LOOP
FETCH c INTO data;
PIPE ROW(data);
EXIT WHEN c%NOTFOUND;
END LOOP;
CLOSE c;
end;
end;
I'm looking for something like SELET * FROM CONVERT(LEGACYFUNCTION());
Thanks
> On Oracle 10.1 I can't even get compile:
CREATE OR REPLACE PACKAGE mypkg AS
FUNCTION CONVERT(c IN SYS_REFCURSOR) RETURN
SYS.ANYDATASET PIPELINED;
end;
It's work, but not for PIPELINED functions. I can't
generalize my first example.
Pipeline table functions can be generalised. In PL/SQL. Using the any data set type. It is possible.
BUT.. In this case it will be a major hack to make it work for you. I honestly think it is NOT the correct thing to do to solve your problem. Nor is it feasible with you proclaiming no Oracle experience as doing this, generically via a pipeline table, is not trivial coding.
> I'm java developer, thus I can't refactor Oracle
database.
Then you get an Oracle back-end developer that can. I harp almost everyday (in some forum on the net or in the office with our developers) that one fixes CAUSES and not symptoms.
The root cause you have is that the ref cursors returns data sets that you need to manipulate further - given your requirement that you want to run additional SQLs on the ref cursors.
Slapping any kind of interface layer over these ref cursors to as a "fix" does not address the cause. It is a fix that will not scale. A fix that is not robust. A fix that introduces more moving parts between the application and Oracle which means a bigger chance of failure.
So the choices you have seem simple. Either learn how to use Oracle and refactor the Oracle side - or get someone with the expertise do it.
I understand that is easy said. But these fact should not be ignored.
> I want to ask you a favor. Not write PL/SQL function
that return a REF CURSOR.
Er.. you missed me completely with that statement. Are you saying that a ref cursor pipeline is too complex or not doing the job? If so, then yes - I agree in principle that this is the wrong method for you to use to address your problem.
Similar Messages
-
ORA-12714 error using NVARCHAR2, REF CURSOR and TABLE FUNCTION
Hello,
we have tested this simple script on all the following versions of Oracle: 9.2.0.3, 10.2.0.1.0 , 11.1.0.6.0 - but we got the same error in everyone of these.
CREATE OR REPLACE TYPE Rec_Prova IS OBJECT(
Id INTEGER,
NodeValue NVARCHAR2(50)
CREATE OR REPLACE TYPE Tab_Prova IS TABLE OF Rec_Prova;
DECLARE
CurProva SYS_REFCURSOR;
varTable Tab_Prova := Tab_Prova();
BEGIN
OPEN CurProva FOR
SELECT Id, NodeValue FROM TABLE(CAST(varTable AS Tab_Prova));
END;The error is: "ORA-12714: invalid national character set specified"
We know that changing the type of NodeValue from NVARCHAR2 to NCLOB it works, but the performances are very poor.
Therefore this solution is not acceptable for us.
We also know that if the character set of the database is set to unicode (NLS_NCHAR_CHARACTERSET = AL16UTF16) we can use the VARCHAR2 for store also the unicode characters and the problem is solved. But some of our customers can't change the settings of theirs databases... moreover, in this forum someone says:
"To all dba's who try to change the NLS_CHARACTERSET or NLS_NCHAR_CHARACTERSET by updating props$ . This is NOT supported and WILL corrupt your database. This is one of the best way's to destroy a complete dataset. Oracle Support will TRY to help you out of this but Oracle will NOT warrant that the data can be recoverd or recovered data is correct. Most likely you WILL be asked to do a FULL export and a COMPLETE rebuild of the database."
Is there any workaround except the two that I have mentioned?
Thank you in advance.
Edited by: user11929330 on 22-set-2009 7.50ORA-12714: invalid national character set specified
Cause: Only UTF8 and AL16UTF16 are allowed to be used as the national character set
Action: Ensure that the specified national character set is valid
So it looks like that you should change the character set or go for NCLOB (and if you're on version 11, maybe securefiles gives you the performance you want).
-Andy -
I was looking at this example given for ref cursor
CREATE TABLE employees (
empid NUMBER(5),
empname VARCHAR2(30));
INSERT INTO employees (empid, empname) VALUES (1, 'Dan Morgan');
INSERT INTO employees (empid, empname) VALUES (2, 'Hans Forbrich');
INSERT INTO employees (empid, empname) VALUES (3, 'Caleb Small');
COMMIT;
CREATE OR REPLACE PROCEDURE pass_ref_cur(p_cursor SYS_REFCURSOR) IS
TYPE array_t IS TABLE OF VARCHAR2(4000)
INDEX BY BINARY_INTEGER;
rec_array array_t;
BEGIN
FETCH p_cursor BULK COLLECT INTO rec_array;
FOR i IN rec_array.FIRST .. rec_array.LAST
LOOP
dbms_output.put_line(rec_array(i));
END LOOP;
END pass_ref_cur;
set serveroutput on
DECLARE
rec_array SYS_REFCURSOR;
BEGIN
OPEN rec_array FOR
'SELECT empname FROM employees';
pass_ref_cur(rec_array);
CLOSE rec_array;
END;
In this P_cursor is weaklytyped ref cursor. My question is
1. How does the fetch identifies which columns are there in the cursor ?
2. If I add another column (say empid) to cursor query it is throwing error message !
3. In my case; I need to use the cursor columns for futher processing in my proc. In such cases how do we define the cursor ?
TIA1. How does the fetch identifies which columns are there in the cursor ?It doesn't. It just puts the first value into the first variable, the second into the next and so on. If it doesn't fit you get an exception (as you found).
In fact a strongly typed ref cursor is the same underneath, it just makes your code declare things slightly more specifically.
2. If I add another column (say empid) to cursor query it is throwing error message !You would have to modify the target variable and the fetch to match the cursor.
3. In my case; I need to use the cursor columns for futher processing in my proc. In such cases how do we define the cursor ?You have to know what columns you are fetching so that you can do something with them. Even if you parsed it out (as SQL*Plus does when it prints a refcursor variable for example) the rest of your code would need to know what it was referring to, how many columns, their datatypes etc. -
STORED PROCEDURE/REF CURSOR: How to output entire buffer
I wrote a Stored Procedure wherein I use a Cursor to extract multiple
rows and columns. I then write them into the buffer
(dmbs_output.put_line). But when I try to capture the entire result
into an OUT variable, I only get the last buffered line.
So how do I output the entire buffer- all rows and columns? In other words (maybe), how do I use dbms_output.get_lines() to assign value to an OUT variable?
Alternatively, using REF CURSOR as OUT variable, I added the following to "CREATE OR REPLACE PROCEDURE ... ()":
cursor_out_test OUT cursor_test
But when I tried:
DEFINE CURSOR TYPE cursor_test IS REF CURSOR RETURN table%ROWTYPE;
...or...
DECLARE TYPE cursor_test IS REF CURSOR RETURN table%ROWTYPE;
I still got syntax errors.
In one line, what I am trying to do is break the result array at the database level rather than at the application level.
Cheers, Bill
http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14261/sqloperations.htm#LNPLS00605I did the following:
OPEN CURSOR x
LOOP
FETCH CURSOR x INTO col1, col2
(EXIT WHEN...)
variable_line := col1 || col2
END LOOP
CLOSE CURSOR
But after closing this cursor, variable_line contains only the last buffered line. I want all the looped lines (without using associative arrays, nested tables etc). So I guess I am just looking for some way to append data lines- adding chr(10) doesn't work either.
Cheers, Bill -
How to populate table name dynamically to a ref cursor
Hi,
I came accross with a requirement that in ref cursor how can i pass the table name
for ex
open ref_cur for select * from emp;Like that i've some 100 tables , instead of typing each and every time the table name
that should be dynamically changed
Like below
open ref_cur for select * from &tbl_nm;How can i do that??
Thank youI assume you are using SQL*Plus:
SQL> variable ref_cur refcursor;
SQL> begin
2 open :ref_cur for select * from &tbl_nm;
3 end;
4 /
Enter value for tbl_nm: emp
old 2: open :ref_cur for select * from &tbl_nm;
new 2: open :ref_cur for select * from emp;
PL/SQL procedure successfully completed.
SQL> print ref_cur
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7369 SMITH CLERK 7902 12/17/1980 00:00:00 800 20
7499 ALLEN SALESMAN 7698 02/20/1981 00:00:00 1600 300 30
7521 WARD SALESMAN 7698 02/22/1981 00:00:00 1250 500 30
7566 JONES MANAGER 7839 04/02/1981 00:00:00 2975 20
7654 MARTIN SALESMAN 7698 09/28/1981 00:00:00 1250 1400 30
7698 BLAKE MANAGER 7839 05/01/1981 00:00:00 2850 30
7782 CLARK MANAGER 7839 06/09/1981 00:00:00 2450 10
7788 SCOTT ANALYST 7566 04/19/1987 00:00:00 3000 20
7839 KING PRESIDENT 11/17/1981 00:00:00 5000 10
7844 TURNER SALESMAN 7698 09/08/1981 00:00:00 1500 0 30
7876 ADAMS CLERK 7788 05/23/1987 00:00:00 1100 20
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7900 JAMES CLERK 7698 12/03/1981 00:00:00 950 30
7902 FORD ANALYST 7566 12/03/1981 00:00:00 3000 20
7934 MILLER CLERK 7782 01/23/1982 00:00:00 1300 10
14 rows selected.
SQL> begin
2 open :ref_cur for select * from &tbl_nm;
3 end;
4 /
Enter value for tbl_nm: dept
old 2: open :ref_cur for select * from &tbl_nm;
new 2: open :ref_cur for select * from dept;
PL/SQL procedure successfully completed.
SQL> print ref_cur
DEPTNO DNAME LOC
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL> SY. -
Help on CAST function, defining TYPE TABLE and using a REF cursor
Hi,
I have written a procedure (lookup) inside a package (lookup_pkg) as shown below.
Procedure has an output variable of type PL/SQL TABLE which is defined in the package.
I want to write a wrapper procedure lookupref to the procedure lookup to return a ref cursor.
CREATE OR REPLACE PACKAGE lookup_pkg AS
TYPE t_lookup_refcur IS REF CURSOR;
CURSOR c_lookup IS
Select columns1,2,3,....100
FROM A, B, C, D, E
WHERE ROWNUM < 1;
TYPE t_lookup IS TABLE OF c_lookup%ROWTYPE;
Procedure lookup(id Number, o_lookup OUT t_lookup);
End lookup_pkg;
CREATE OR REPLACE PACKAGE BODY lookup_pkg As
Procedure lookup(id Number, o_lookup OUT t_lookup) IS
BEGIN
END lookup;
Procedure lookupref(id Number, o_lookupref OUT t_lookup_refcur) IS
o_lookup t_lookup;
BEGIN
lookup(id, o_lookup t_lookup);
OPEN t_lookup_refcur FOR
SELECT *
FROM TABLE(CAST(o_lookup AS t_lookup));
Exception
End lookupref;
END lookup_pkg;
When I compile this procedure, I am getting invalid datatype Oracle error and
cursor points the datatype t_lookup in the CAST function.
1. Can anyone tell me what is wrong in this. Can I convert a PL/SQL collection (pl/sql table in this case) to PL/SQL datatype table or does it need to be a SQL datatype only (which is created as a type in database).
Also, to resolve this error, I have created a SQL type and table type instead of PL/SQL table in the package as shown below.
create or replace type t_lookuprec as object
(Select columns1,2,3,....100
FROM A, B, C, D, E
WHERE ROWNUM < 1);
create or replace type t_lookup_tab AS table of t_lookuprec;
CREATE OR REPLACE PACKAGE BODY lookup_pkg As
Procedure lookup(id Number, o_lookup OUT t_lookup) IS
BEGIN
END lookup;
Procedure lookupref(id Number, o_lookupref OUT t_lookup_refcur) IS
o_lookup t_lookup;
BEGIN
lookup(id, o_lookup t_lookup);
OPEN t_lookup_refcur FOR
SELECT *
FROM TABLE(CAST(o_lookup AS t_lookup_tab));
Exception
End lookupref;
END lookup_pkg;
When I compile this package, I am getting "PL/SQL: ORA-22800: invalid user-defined type" Oracle error and
points the datatype t_lookup_tab in the CAST function.
2. Can anyone tell me what is wrong. Can I create a type with a select statement and create a table type using type created earlier?
I have checked the all_types view and found that
value for Incomplete column for these two types are YES.
3. What does that mean?
Any suggestions and help is appreciated.
Thanks
Srinivascreate or replace type t_lookuprec as object
(Select columns1,2,3,....100
FROM A, B, C, D, E
WHERE ROWNUM < 1);You are correct that you need to use CREATE TYPE to use the type in SQL.
However unless I am mistaken you appear to have invented your own syntax for CREATE TYPE, suggest you refer to Oracle documentation. -
DB proc - do you need to create a table to pass a ref cursor record type?
I want to pass a limited selection of columns from a large table through a DB procedure using a REF CURSOR, returning a table rowtype:
CREATE OR REPLACE package XXVDF_XPOS_DS021_ITEMS AS
TYPE XXVDF_XPOS_DS021_ITEM_ARRAY
IS REF CURSOR
return XXVDF_XPOS_DS021_ITEM_TABLE%ROWTYPE;
Do I need to create this dummy table?
I can't get a TYPE to work, where the type is an OBJECT with the desired columns in it.
So a dummy empty table will sit in the database...
Is there another way?
thanks!You can use RECORD type declaration:
SQL> declare
2 type rec_type is record (
3 ename emp.ename%type,
4 sal emp.sal%type
5 );
6 type rc is ref cursor return rec_type;
7 rc1 rc;
8 rec1 rec_type;
9 begin
10 open rc1 for select ename, sal from emp;
11 loop
12 fetch rc1 into rec1;
13 exit when rc1%notfound;
14 dbms_output.put_line(rec1.ename || ' ' || rec1.sal);
15 end loop;
16 close rc1;
17 end;
18 /
SMITH 800
ALLEN 1600
WARD 1250
JONES 2975
MARTIN 1250
BLAKE 2850
CLARK 2450
SCOTT 3000
KING 5000
TURNER 1500
ADAMS 1100
JAMES 950
FORD 3000
MILLER 1300or use, for example, VIEW to declare rowtype:
SQL> create view dummy_view as select ename, sal from emp;
View created.
SQL> declare
2 type rc is ref cursor return dummy_view%rowtype;
3 rc1 rc;
4 rec1 dummy_view%rowtype;
5 begin
6 open rc1 for select ename, sal from emp;
7 loop
8 fetch rc1 into rec1;
9 exit when rc1%notfound;
10 dbms_output.put_line(rec1.ename || ' ' || rec1.sal);
11 end loop;
12 close rc1;
13 end;
14 /
SMITH 800
ALLEN 1600
WARD 1250
JONES 2975
MARTIN 1250
BLAKE 2850
CLARK 2450
SCOTT 3000
KING 5000
TURNER 1500
ADAMS 1100
JAMES 950
FORD 3000
MILLER 1300 Rgds. -
Selecting the contents of a table(collection) into a strong REF Cursor
I'm trying to roll some data into a table collection and return it as a strong named cursor.
I have not been able to do this successfully yet.
I have tried casting the table and I couldn't get that to work either.
I have included the whole procedure but here is the line I am getting errors on:
SELECT * bulk collect into o_response_data_cur from table (response_data_tbl);
Any help on this would be great.
P.S. - As this is being picked up by BizTalk I can't return a table.
Thanks,
Todd M
PROCEDURE create_customer (
i_interface_hdr IN BizTalk_TestCustomer.interface_hdr_rec,
i_customer_rec IN BizTalk_TestCustomer.customer_rec,
i_address_cur IN BizTalk_TestCustomer.CUR_Addresses,
i_contact_cur IN BizTalk_TestCustomer.CUR_Contact,
o_interface_status OUT varchar2,
o_response_data_cur OUT BizTalk_TestCustomer.CUR_CreateCustResponse)
IS
l_response_rec create_cust_response_rec;
response_data_tbl create_cust_response_tbl;
BEGIN
FOR i IN 1 .. 10
LOOP
l_response_rec.ERROR_TYPE := 'Pre-Validation Error';
l_response_rec.ERROR_CODE := 'DUMMY-' || i;
l_response_rec.error_message := 'Test Error Message-' || i;
response_data_tbl (i) := l_response_rec;
END LOOP;
SELECT * bulk collect into o_response_data_cur from table (response_data_tbl);
o_interface_status := 'FAILURE';
END create_customer;
END BizTalk_TestCustomer;
Here is the important Spec info:
TYPE create_cust_response_rec
IS
RECORD (
orig_system_party_ref varchar2 (240),
orig_system_cust_acct_ref varchar2 (240),
orig_system_site_ref varchar2 (240),
oracle_party_id number,
oracle_customer_id number,
oracle_site_id number,
ERROR_TYPE strar_cust_intf_err.ERROR_TYPE%TYPE,
ERROR_CODE strar_cust_intf_err.ERROR_CODE%TYPE,
error_message strar_cust_intf_err.error_message%TYPE
TYPE CUR_Addresses IS REF CURSOR RETURN BizTalk_TestCustomer.address_rec;
TYPE CUR_Contact IS REF CURSOR RETURN BizTalk_TestCustomer.contact_rec;
TYPE CUR_CreateCustResponse IS REF CURSOR RETURN BizTalk_TestCustomer.create_cust_response_rec;
TYPE create_cust_response_tbl
IS
TABLE OF create_cust_response_rec
INDEX BY binary_integer;I think this is one of the most complicated one to develop and execute perfectly. ;)
Here is one such case ->
satyaki>
satyaki>select * from v$version;
BANNER
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Prod
PL/SQL Release 10.2.0.3.0 - Production
CORE 10.2.0.3.0 Production
TNS for 32-bit Windows: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 - Production
Elapsed: 00:00:00.55
satyaki>
satyaki>
satyaki>create or replace type d_obj as object
2 (
3 buff varchar2(310)
4 );
5 /
Type created.
Elapsed: 00:00:00.05
satyaki>
satyaki>
satyaki>create or replace type d_rec as table of d_obj;
2 /
Type created.
Elapsed: 00:00:01.14
satyaki>
satyaki>
satyaki>
satyaki>
satyaki>create or replace function pipe_buff(e_sal in number)
2 return d_rec
3 pipelined
4 is
5 cursor c1
6 is
7 select d_obj(
8 ename||' Joined On '||to_char(hiredate,'DD-MON-YYYY hh24:mi:ss')
9 ) str
10 from emp
11 where sal > e_sal;
12
13 r1 c1%rowtype;
14 begin
15 for r1 in c1
16 loop
17 pipe row(r1.str);
18 end loop;
19 return;
20 end;
21 /
Function created.
Elapsed: 00:00:01.69
satyaki>
satyaki>
satyaki>
satyaki>create or replace procedure gen_cur_pipe(
2 s_sal in number,
3 rc in out sys_refcursor
4 )
5 is
6 str1 varchar2(500);
7 begin
8 str1 := 'select *
9 from table(cast(pipe_buff('||s_sal||') as d_rec))';
10
11 open rc for str1;
12 exception
13 when others then
14 dbms_output.put_line(sqlerrm);
15 end;
16 /
Procedure created.
Elapsed: 00:00:00.05
satyaki>
satyaki>
satyaki>
satyaki>create table test_dual
2 (
3 dummy varchar2(310)
4 );
Table created.
Elapsed: 00:00:00.10
satyaki>
satyaki>
satyaki>
satyaki>declare
2 rec_x test_dual%rowtype;
3 w sys_refcursor;
4 begin
5 dbms_output.enable(1000000);
6 gen_cur_pipe(&num,w);
7 loop
8 fetch w into rec_x;
9 exit when w%notfound;
10 dbms_output.put_line('Employee Special Deatils: '||rec_x.dummy);
11 end loop;
12 close w;
13 exception
14 when others then
15 dbms_output.put_line(sqlerrm);
16 end;
17 /
Enter value for num: 1000
old 6: gen_cur_pipe(&num,w);
new 6: gen_cur_pipe(1000,w);
Employee Special Deatils: SATYAKI Joined On 02-NOV-2008 12:07:30
Employee Special Deatils: SOURAV Joined On 14-SEP-2008 00:07:21
Employee Special Deatils: WARD Joined On 22-FEB-1981 00:00:00
Employee Special Deatils: JONES Joined On 02-APR-1981 00:00:00
Employee Special Deatils: MARTIN Joined On 28-SEP-1981 00:00:00
Employee Special Deatils: BLAKE Joined On 01-MAY-1981 00:00:00
Employee Special Deatils: CLARK Joined On 09-JUN-1981 00:00:00
Employee Special Deatils: SCOTT Joined On 19-APR-1987 00:00:00
Employee Special Deatils: KING Joined On 17-NOV-1981 00:00:00
Employee Special Deatils: TURNER Joined On 08-SEP-1981 00:00:00
Employee Special Deatils: ADAMS Joined On 23-MAY-1987 00:00:00
Employee Special Deatils: FORD Joined On 03-DEC-1981 00:00:00
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.30
satyaki>
satyaki>
satyaki>/
Enter value for num: 4000
old 6: gen_cur_pipe(&num,w);
new 6: gen_cur_pipe(4000,w);
Employee Special Deatils: SATYAKI Joined On 02-NOV-2008 12:07:30
Employee Special Deatils: SOURAV Joined On 14-SEP-2008 00:07:21
Employee Special Deatils: CLARK Joined On 09-JUN-1981 00:00:00
Employee Special Deatils: KING Joined On 17-NOV-1981 00:00:00
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.13
satyaki>I'm not so sure about the performance.
Regards.
Satyaki De. -
Using plsql table and ref cursor in oracle forms 10g
Hi all,
Can anyone give me an example of a scenario where we need to create a form manually based on a database stored procedures.
And in that procedure i have created a pl/sql table and a ref cursor in data base level.
CREATE OR REPLACE PACKAGE SCOTT.BONUS_PKG IS TYPE bonus_rec
IS RECORD(
empno bonus_EMP.empno%TYPE,
ename bonus_EMP.ename%TYPE,
job bonus_EMP.job%TYPE,
sal bonus_EMP.sal%TYPE,
comm bonus_EMP.comm%TYPE);
TYPE b_cursor IS REF CURSOR RETURN bonus_rec;
TYPE bontab IS TABLE OF bonus_rec INDEX BY BINARY_INTEGER;
PROCEDURE bonus_refcur(bonus_data IN OUT b_cursor);
PROCEDURE bonus_query(bonus_data IN OUT bontab);
END bonus_pkg;
CREATE OR REPLACE PACKAGE BODY SCOTT.BONUS_PKG IS
PROCEDURE bonus_query(bonus_data IN OUT bontab) IS
ii NUMBER;
CURSOR bonselect IS
SELECT empno, ename, job, sal, comm FROM bonus_EMP ORDER BY empno;
BEGIN
OPEN bonselect;
ii := 1;
LOOP
FETCH bonselect INTO
bonus_data( ii ).empno,
bonus_data( ii ).ename,
bonus_data( ii ).job,
bonus_data( ii ).sal,
bonus_data( ii ).comm;
EXIT WHEN bonselect%NOTFOUND;
ii := ii + 1;
END LOOP;
END bonus_query;
PROCEDURE bonus_refcur(bonus_data IN OUT b_cursor) IS
BEGIN
OPEN bonus_data FOR SELECT empno, ename, job, sal, comm FROM bonus_EMP ORDER BY empno;
END bonus_refcur;
END bonus_pkg;
i want to populate the data in forms manually not using forms data block wizard and programmatically.
please reply...Can anyone give me an example of a scenario where we need to create a form manually based on a database stored procedures.Typically, you would use a procedure based block when you have a collection of data from multiple tables presented in a Form and your user needs to be able to update the information displayed.
From your code example, it looks like you are using Oracle Support document "Basing a Block on a Stored Procedure - Sample Code [ID 66887.1]". If this is the case, keep following the document - it walks you through all of the steps. There is no need to Manually configure things that the Data Block Wizard will perform for you!
i want to populate the data in forms manually not using forms data block wizard and programmatically. Why? Let the Data Block Wizard take care of configuring your block based on a procedure for you. There is no need to manually loop through the data! I've actually done what you are attempting and it was more work than was needed. Let Forms do the work for you. :)
If you absolutely must do things manually, I recommend you use the PROCEDURE bonus_query(bonus_data IN OUT bontab) instead of the bonus_refcur(bonus_data IN OUT b_cursor) . Then, in your code create a variable of type BONTAB and then call the bonus_query procedure. Then it is a simple case of looping through the table of records returned by the bonus_query procedure. For example:
DECLARE
t_bonus bonus_pkb.bontab;
BEGIN
bonus_pkg.bonus_query(t_bonus);
FOR i in 1 .. t_bonus.count LOOP
:YOUR_BLOCK.EMPLOYEE_NUMBER := t_bonus(i).empno;
:YOUR_BLOCK.EMPLOYEE_NAME := t_bonus(i).ename;
:YOUR_BLOCK.EMPLOYEE_JOB := t_bonus(i).job;
:YOUR_BLOCK.EMPLOYEE_SALARY := t_bonus(i).sal;
:YOUR_BLOCK.EMPLOYEE_COMMISSION := t_bonus(i).comm;
END LOOP;
END;This code sample demonstrates the basics, but as it is sample code - you will have to adapt it to your situation.
Also, I strongly recommend you look at the article InoL listed. This is a very comprehensive discussion on REF CURSORs. If you are set on using a procedure based data source - it is more efficient to pass the table of records back to your form than it is to pass a ref cursor. Using a ref cursor, you might as well just using a standard named cursor and loop through your named cursor. The effect is the same (one row returned at a time creating lots of network traffic). Using the table of records is more efficient because the entire data set is returned so network traffic is reduced.
Hope this helps,
Craig B-)
If someone's response is helpful or correct, please mark it accordingly. -
Wanted to fetch data from ref cursor to nested pl/sql table getting an erro
create or replace type "DEPT12" as object(dno number(2),dname varchar2(30),loc varchar2(50));
create or replace type dept_tab as table of "DEPT12"
create or replace type "LOC12" as object(locno number,loc_name varchar2(100))
create or replace type loc_tab as table of "LOC12"
create or replace type dept_loc_rec1 as object (dept_dt dept_tab,eno number,loc_dt loc_tab);
create type dept_loc_tb as table of dept_loc_rec1
create table dept_loc_tb_bk1(dept_dt dept_tab,eno number,loc_dt loc_tab)
NESTED TABLE dept_dt
STORE AS dept_tab12,
NESTED TABLE loc_dt
STORE AS loc_tab12
insert into dept_loc_tb_bk1 values(dept_tab(dept12(3,'ABD','LOC')
,dept12(4,'ABD','LOC')
,dept12(5,'ABD','LOC')),3,loc_tab(loc12(21,'AAB'),
loc12(22,'AAB'),
loc12(23,'AAB')));
when I am trying to fetch data from ref cursor to pl/sql table which i am getting an error ora-06504: pl/sql : Return types of result set variables or query do not match.
I have created a nested table of same as the nested pl/sql object table dept_loc_tb and i have declared the lv_dept_loc_tb of same dept_loc_tb but getting an above error when trying to fetch into that variable.
Please any one who can solve my problem.
declare
type cr is ref cursor;
cr_obj cr;
lv_dept_loc_tb dept_loc_tb;
begin
open cr_obj for select dept_dt,eno,loc_dt from dept_loc_tb_bk1;
fetch cr_obj bulk collect into lv_dept_loc_tb;
close cr_obj;
end;Your query selects 3 separate columns therefore requires 3 collections of corresponding types. You want to treat those 3 columns as an object of DEPT_LOC_REC1 type:
SQL> declare
2 type cr is ref cursor;
3 cr_obj cr;
4
5 lv_dept_loc_tb dept_loc_tb;
6
7 begin
8 open cr_obj for select dept_dt,eno,loc_dt from dept_loc_tb_bk1;
9 fetch cr_obj bulk collect into lv_dept_loc_tb;
10 close cr_obj;
11 end;
12 /
declare
ERROR at line 1:
ORA-06504: PL/SQL: Return types of Result Set variables or query do not match
ORA-06512: at line 9
SQL> declare
2 type cr is ref cursor;
3 cr_obj cr;
4
5 lv_dept_loc_tb dept_loc_tb;
6
7 begin
8 open cr_obj for select DEPT_LOC_REC1(dept_dt,eno,loc_dt) from dept_loc_tb_bk1;
9 fetch cr_obj bulk collect into lv_dept_loc_tb;
10 close cr_obj;
11 end;
12 /
PL/SQL procedure successfully completed.
SQL> SY.
P.S. Discover sys_refcursor. -
Ref Cursor from PL/SQL Table
I'm building a complex report in which the information cames from a lot of tables and needs complex formatting. I'd like to base my report in a table returned by a stored procedure (like you can do in Forms). Is there any way to convert an PL/SQL table in a Ref Cursor?
Why don't you process the data in procedure and dump into temporary table. And base your report on that temporary table.
it may simplify your report.
Atul -
Joining a ref cursor to a table
Dear all;
Can you please show me a simple example on how to join a ref cursor to a table because I have a function that returns a ref cursor and I would like to call that function in another function(function B) and then join it to a table in that function(function B)user13328581 wrote:
well, I personnally know it is a bad idea but my fellow senior keeps advicing me to do it. Their reason is based on the code reusability aspect of things. I had a function 1 already created which returned a ref cursor and basically within that function is a complex select statement. Now I have function 2 which is making use of a similar select statement, the only different between the two select statment is based on the fact, the function 2 select statement is joining to another table at the very end, so based on their argument they want me to call that select statement from function 1 and join it to that table instead...Then your "+seniors+" need to extract their heads from whatever dark orifice they have it stuck in, as this is not how '"+code reusability+" works in the Oracle environment.
In the SQL language, views are used to create re-usable SQL source code.
In Oracle, the Shared Pool is used to create and store cursors for reuse (assuming the SQL source allows reusability and uses bind variables).
Joining a ref cursor (code) with a table (data) is just plain stupid - and no amount of "code reusability" arguing will change this fact. -
Returning a ref cursor on a Global Temporary table
I realize this is probably not feasible but I am manipulating data and storing it in a GTT and I wish to return that transformed data out as a ref cursor is this possible to do? I also dont want a static table because this is a heavily hit procedure and I do not want to have to keep track of which session is which data not to mention contention between them.
I am using Oracle 10g on Windows server 2008You will be able to see the records in the refcursor in the same session
Example
SQL> create global temporary table X_GTT as select * from emp where 1=2;
Table created.
SQL> insert into x_GTT select * from emp ;
14 rows created.
SQL> var rf refcursor ;
SQL> begin
2 open :rf for select * from X_GTT ;
3 end ;
PL/SQL procedure successfully completed.
SQL> print rf
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7369 SMITH CLERK 7902 17-DEC-80 800 99
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7566 JONES MANAGER 7839 02-APR-81 2975 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
7782 CLARK MANAGER 7839 09-JUN-81 2450 10
7788 SCOTT ANALYST 7566 19-APR-87 3000 20
7839 KING PRESIDENT 17-NOV-81 5000 10
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
7876 ADAMS CLERK 7788 23-MAY-87 1100 20
7900 JAMES CLERK 7698 03-DEC-81 950 30
7902 FORD ANALYST 7566 03-DEC-81 3000 20
7934 MILLER CLERK 7782 23-JAN-82 1300 10
14 rows selected.SS -
Using temporary tables with a ref. cursor
I want to use a temporary table to populate certain data and then return a ref cursor fetching data from the temporary table.
1. Will this approach work ?
2. Do I need to drop the temporary table ? Can I drop the table as a last statement in the stored proc (remember a ref cursor based on this table is to be returned as a out parameter).
Please help.1. Will this approach work ?Sort of, just like it is possible to dig a trench with a spoon. It can be done, but why can't you just write a select that returns the data without storing intermediate versions of your processing somewhere.
2. Do I need to drop the temporary table ?No. and you shouldn't.
Can I drop the table as a last statement in the stored proc
(remember a ref cursor based on this table is to be returned as a out parameter).No.
If you really need to use a temporary table, it should be created one time when the application is installed, and should never be created in code. -
Retrieving nested table columns through a REF CURSOR in php
Hello.
I have been able to execute REF CURSORS returned by pl/sql functions succesfully with php. I have also been able to bind collections to the input/output of pl/sql functions/procedures.
However, what I am unable to do, is to execute a cursor returned by a pl/sql function that has one of the columns a named datatype (a simple one-dimensional nested table):
create type stab is table of varchar2(255);
create table lp_landing (
token varchar2(255),
text varchar2(512),
country varchar2(255),
creator varchar2(255),
is_active char(1),
css_file char(1),
autofollowing stab default stab(),
constraint lp_landing_pk primary key (token)) organization index
nested table autofollowing store as lp_landings_af_nt
(constraint autofollowing_pk primary key (nested_table_id,column_value)) organization index compress
function landings_usercountry (in_uname in lp_users.uname%type, in_country in lp_country.cname%type) return Landing_curType
is
ret Landing_curType;
begin
open ret for
select * --token,text,country,creator,is_active,css_file,tab2str(autofollowing) as autofollowing
from lp_landing
where country = (select country
from lp_permissions
where country = in_country and uname = in_uname);
return ret;
end landings_usercountry;
here is the php:
$sql = 'BEGIN :res := LP_PKG.landings_usercountry(:user, :country); END;';
$stmt = oci_parse($c, $sql);
$cursor = oci_new_cursor($c);
oci_bind_by_name($stmt,':user',$name, 32);
oci_bind_by_name($stmt,':country',$country, 32);
oci_bind_by_name($stmt,':res', $cursor, -1, OCI_B_CURSOR);
$name = "root";
$country = "Spain";
try {
@oci_execute($stmt);
$m = oci_error($stmt);
if($m){
throw new Exception($m['message'], $m['code']);
}else{
@oci_execute($cursor);
$m = oci_error($cursor);
if($m){
throw new Exception($m['message'], $m['code']);
}else{
while ( $entry = oci_fetch_object($cursor) ) {
var_dump($entry);
} catch (Exception $e) {
print_r($e);
With "select *" in the function, the autofollowing column (of datatype stab) fails to bind, giving an ORA-932 error. The workaround for the moment is to convert the nested table to a comma delimited string (via the tab2str function).
However, I would like to be able to tell php to accept a collection within the cursor, but I cannot figure out how to do this.
Any ideas?
thx in advanceyes, it is an ORA-932:
Warning: oci_fetch_object() [function.oci-fetch-object]: ORA-00932: inconsistent datatypes: expected CHAR got ADT in /home/apolion/apache2/htdocs/old/test1.php on line 104
Maybe you are looking for
-
Print to go and Windows 8.1 not working
Recently moved to Windows 8.1. System on-line and full access to internet. Select Print to go and when it tries to connect it says that the ptg web page can not be opened. This heppens when the window to select the playbook device should open Old XP
-
Getting all of my iTunes library onto my external hard-drive
Hey, I've recently noticed that my MacBook (now called a McBook pro?) is running slightly slower than usual. I have the majority of my music stored on an external hard-drive, but anything that I've downloaded looks to be stored on my MacBook's intern
-
Hi all, Pls tell me what is the Cost column in Billing document and what is use? As i know, it relates to internal price, so why it's displayed in billing doc? Thanks,
-
Help required in Material master new view extension
Hi, I have created one additional view for matrial master , i have added few custom fields in that i am able to save the records. but i am facing problem if i use already used fields in other views in my view and it is saying "Maintenance status of
-
HT4623 Help with the new IOS 6 update
I was trying to update the IOS 6 of Iphone 3Gs, and the phone went black showing only the apple logo switching on and off repeatedly. This is been going on for 4 days, and I can't turn the phone back to normal. Please help!!