How to get rowtype of a ref cursor?
Hello again,
I need your help once more.
I have a function in a package which returns a SYS_REFCURSOR. Now I am trying to open that cursor from the application (currently sql_developer) to show the data. For starting I have a simple query in the statement: select * from emp;
Later it will be a complex query which returns results of multiple joined tables.
I have the following package:
>
CREATE OR REPLACE
PACKAGE P_TEST_ASP AS
FUNCTION test_asp_1 (dti_id in NUMBER)
RETURN SYS_REFCURSOR;
END P_TEST_ASP;
>
And here comes the package body:
>
CREATE OR REPLACE
PACKAGE BODY P_TEST_ASP AS
FUNCTION test_asp_1 (dti_id in NUMBER)
RETURN SYS_REFCURSOR AS
resultCursor SYS_REFCURSOR;
BEGIN
OPEN resultCursor FOR select * from emp;
RETURN resultCursor;
END test_asp_1;
END P_TEST_ASP;
>
Now my Problem is that I do not know how to get the cursor's rowtype to assign it to the collection:
I Managed to access the cursor when I set the rowtype of my collection res to emp%rowtype.
>
set serveroutput on
DECLARE
type testtype is TABLE OF emp%rowtype;
myCursor SYS_REFCURSOR;
res testtype;
BEGIN
-- Get ref cursor from function
myCursor := p_test_asp.test_asp_1(9);
FETCH myCursor BULK COLLECT into res;
dbms_output.put_line('Value from cursor:' );
CLOSE myCursor;
END;
>
But that will not work with the final statement.
I would like to set the rowtype to myCursor%rowtype -> But I don't know how to do it:
>
set serveroutput on
DECLARE
type testtype is TABLE OF myCursor%rowtype;
myCursor SYS_REFCURSOR;
res testtype;
BEGIN
-- Get ref cursor from function
myCursor := p_test_asp.test_asp_1(9);
FETCH myCursor BULK COLLECT into res;
dbms_output.put_line('Value from cursor:' );
CLOSE myCursor;
END;
>
this statement throws the following errors:
Fehlerbericht:
ORA-06550: line 2, column 36:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 2, column 3:
PL/SQL: Item ignored
ORA-06550: line 11, column 36:
PLS-00597: expression 'RES' in the INTO list is of wrong type
ORA-06550: line 11, column 3:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
Edited by: Andreas S. on 13.12.2011 04:56
Why do you want to use a collection? I dont see any need for that.
Lets say your client is SQL Plus. SQL Plus provides a API called PRINT that prints the cursor. You can use that.
SQL> var rc refcursor
SQL>
SQL> exec open :rc for select level from dual connect by level <= 10;
PL/SQL procedure successfully completed.
SQL> print rc
LEVEL
1
2
3
4
5
6
7
8
9
10
10 rows selected.
SQL>Like wise whatever is your client use the correct API that offers to handle cursors.
Similar Messages
-
How to get values from a ref cursor in a procedure
I have a procedure that returns a cursor type of values, but I cannot get the values.
I got error when on how to define the output cursor. Could someone please look at the code and tell me how to correct it?
Thanks in advance.
******************************8
--This is the package
CREATE OR REPLACE PACKAGE Test_SECURITY2 as
type T_RoleTest is ref cursor;
Procedure P_GetUserRole(userID in number, p_cur out T_RoleTest);
end;
CREATE OR REPLACE PACKAGE BODY Test_SECURITY2 as
Procedure P_GetUserRole(userID in number, p_cur out T_RoleTest) as
begin
open p_cur for
select PREO_Role.ROLE_ID,PREO_Role.ROLE_NAME
from preorder.PREO_Role, preorder.PREO_User_Role
where PREO_Role.Role_id = PREO_User_Role.Role_id
and PREO_User_Role.user_id = userid;
end;
end;
--This is the testing code. I got error here
SQL> set serveroutput on;
SQL> execute dbms_output.enable;
PL/SQL procedure successfully completed.
SQL> declare
2 type T_RoleTest is ref cursor;
3 V_UserRole is ref cursor; --how to define the output cursor
4 v_userId number := 42;
5 V_Role_Id number;
6 v_Role_name varchar2(20);
7 begin
8 Test_SECURITY2.P_GetUserRole(v_userId, V_UserRole);
9
10 open V_UserRole;
11 loop
12 fetch V_UserRole into V_Role_Id, v_Role_name;
13
14 EXIT WHEN V_UserRole%NOTFOUND;
15 dbms_output.put_line('RoleID'||v_Role_ID);
16 dbms_output.put_line('Rolename'||v_Role_name);
17
18 end loop;
19
20 end;
21 /
V_UserRole is ref cursor;
ERROR at line 3:
ORA-06550: line 3, column 13:
PLS-00103: Encountered the symbol "IS" when expecting one of the following:
constant exception <an identifier>declare
type T_RoleTest is ref cursor;
v_UserRole T_RoleTest;or just:
declare
v_UserRole Test_Security2.T_RoleTest;And, if you are on 9i or later, you can just use the built-in sys_refcursor type. -
Getting data stored in ref cursor ( got from store proc in oracle) to excel sheet)
Hey, I am trying to Get data stored in ref cursor ( got from store proc in oracle) to excel sheet in a virtual folder using ssis.
I am getting errors and cant do it. If anyone can help meHi Nabin000,
The Oracle stored procedure doesn't work with SSIS source adapters such as OLE DB Source because the data provider doesn't provide metadata for the source adapter. To achieve your goal, you can use a Script Component as source to call
the Oracle stored procedure by using System.Data.OracleClient OracleDataReader, and get the rows and add them to the pipeline buffer. For more information, please see:
http://social.msdn.microsoft.com/Forums/sqlserver/en-US/1d0b3a1b-8792-469c-b0d1-f2fbb9e9ff20/dump-oracle-ref-cursor-into-ms-sql-staging-table-using-ssis
http://social.msdn.microsoft.com/Forums/sqlserver/en-US/fcdaa97e-8415-4c3e-8ffd-1ad45b590d57/executing-an-oracle-stored-procedure-from-ssis?forum=sqlintegrationservices
http://msdn.microsoft.com/en-us/library/system.data.oracleclient.oracledatareader(VS.90).aspx
Regards,
Mike Yin
TechNet Community Support -
How to retrieve data from a REF CURSOR using OCI 8.0?
I found an example in Oracle docs (shown below) that discusses how to bind a REF CURSOR for later data retrieval, but it does not explain actually how to do the later data retrieval.
I hope someone can explain it to me. Thanks
The OCI provides the ability to bind and define PL/SQL REF CURSORs and nested tables. An application can use a statement handle to bind and define these types of variables. As an example, consider this PL/SQL block:
static const text plsql_block = (text )
"begin \
OPEN :cursor1 FOR SELECT empno, ename, job, mgr, sal, deptno \
FROM emp_rc WHERE job=:job ORDER BY empno; \
OPEN :cursor2 FOR SELECT * FROM dept_rc ORDER BY deptno; \
end;";
An application would allocate a statement handle for binding, by calling OCIHandleAlloc(), and then bind the :cursor1 placeholder to the statement handle, as in the following code, where :cursor1 is bound to stm2p. Note that the handle allocation code is not included here.
err = OCIStmtPrepare (stm1p, errhp, (text *) nst_tab, strlen(nst_tab),
OCI_NTV_SYNTAX, OCI_DEFAULT);
err = OCIBindByName (stm1p, (OCIBind **) bndp, errhp,
(text *)":cursor1", (sb4)strlen((char *)":cursor1"),
(dvoid *)&stm2p, (sb4) 0, SQLT_RSET, (dvoid *)0,
(ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, (ub4)OCI_DEFAULT);
In this code, stm1p is the statement handle for the PL/SQL block, while stm2p is the statement handle which is bound as a REF CURSOR for later data retrieval. A value of SQLT_RSET is passed for the dty parameter.( sorry, i forgot the Link where i get this html fiLes, so i just copy-paste here )
( maybe it can heLp you a bit. -- it's heLp me, for sure )
And the following is thanks to Brett Rosen :
I noticed that you didn't have an OCI entry
on http://osi.oracle.com/~tkyte/ResultSets/index.html .
Here is OCI code to do this (Oracle 81) if you want to include it on
that page.
Some error checking and cleanup has been removed, but the below should
work. (once dbname has been replaced appropriately)
Brett
int main(int argc, char* argv[])
OCIError* pOciError;
char* pConnectChar = "dbname";
char* pUsernameChar = "scott";
char* pPasswordChar = "tiger";
int answer;
OCIStmt* pOciStatement;
char* sqlCharArray = "BEGIN :success := sp_ListEmp; END;";
int id;
char ename[40];
OCIEnv* g_pOciEnvironment = NULL;
OCIServer* g_pOciServer = NULL;
OCISession* g_pOciSession = NULL;
OCISvcCtx* g_pOciServiceContext = NULL;
sb2* pIndicator=0;
sb2* pIndicator2=0;
sb2* pIndicator3=0;
OCIDefine* pOciDefine;
OCIDefine* pOciDefine2;
OCIBind* pBind;
OCIStmt* cursor;
answer = OCIInitialize(OCI_THREADED, NULL, NULL, NULL, NULL);
answer = OCIEnvInit(&g_pOciEnvironment, OCI_DEFAULT, 0, NULL);
answer = OCIHandleAlloc(g_pOciEnvironment, (void **)&pOciError, OCI_HTYPE_ERROR, 0, NULL);
answer = OCIHandleAlloc(g_pOciEnvironment, (void **)&g_pOciSession, OCI_HTYPE_SESSION, 0, NULL);
answer = OCIHandleAlloc(g_pOciEnvironment, (void **)&g_pOciServer, OCI_HTYPE_SERVER, 0, NULL);
answer = OCIHandleAlloc(g_pOciEnvironment, (void **)&g_pOciServiceContext, OCI_HTYPE_SVCCTX, 0, NULL);
answer = OCIServerAttach(g_pOciServer, pOciError, (unsigned char *)pConnectChar, strlen(pConnectChar),
OCI_DEFAULT);
answer = OCIAttrSet(g_pOciSession, OCI_HTYPE_SESSION, (unsigned char *)pUsernameChar, strlen(pUsernameChar),
OCI_ATTR_USERNAME, pOciError);
answer = OCIAttrSet(g_pOciSession, OCI_HTYPE_SESSION, (unsigned char *)pPasswordChar, strlen(pPasswordChar),
OCI_ATTR_PASSWORD, pOciError);
answer = OCIAttrSet(g_pOciServiceContext, OCI_HTYPE_SVCCTX, g_pOciServer, 0, OCI_ATTR_SERVER, pOciError);
answer = OCIAttrSet(g_pOciServiceContext, OCI_HTYPE_SVCCTX, g_pOciSession, 0, OCI_ATTR_SESSION, pOciError);
answer = OCISessionBegin(g_pOciServiceContext, pOciError, g_pOciSession, OCI_CRED_RDBMS, OCI_DEFAULT);
answer = OCIHandleAlloc(g_pOciEnvironment, (void **)(&pOciStatement), OCI_HTYPE_STMT, 0, NULL);
answer = OCIStmtPrepare(pOciStatement, pOciError, (unsigned char *)sqlCharArray, strlen(sqlCharArray),
OCI_NTV_SYNTAX, OCI_DEFAULT);
answer = OCIHandleAlloc(g_pOciEnvironment, (void **)(&cursor), OCI_HTYPE_STMT, 0, NULL);
answer = OCIBindByPos(pOciStatement,&pBind, pOciError, 1, &cursor, 0,SQLT_RSET,
pIndicator2, 0,NULL, 0,0,OCI_DEFAULT);
answer = OCIStmtExecute(g_pOciServiceContext, pOciStatement, pOciError, 1, 0, NULL, NULL,
OCI_COMMIT_ON_SUCCESS);
answer = OCIDefineByPos(cursor,&pOciDefine, pOciError,2,&id,sizeof(int),
SQLT_INT,pIndicator, 0, 0,OCI_DEFAULT);
answer = OCIDefineByPos(cursor,&pOciDefine2, pOciError,1,ename,40,
SQLT_STR,pIndicator3, 0, 0,OCI_DEFAULT);
if (answer == 0)
while ((answer = OCIStmtFetch(cursor,pOciError, 1,OCI_FETCH_NEXT,OCI_DEFAULT)) == 0)
printf("fetched id %d and name %s\n",id,ename);
answer = OCIHandleFree(pOciError, OCI_HTYPE_ERROR);
return 0;
} -
How to return a table to ref cursor?
My client has created a package stored procedure that takes in 2 parameters of VarChar2 and an out parameter which is a table
Following is the package header
CREATE OR REPLACE PACKAGE "PKG_TRAVEL_NEW_SUND" IS
---RECORD TYPE DELARATION
TYPE DIRECT_ALT_REC IS RECORD (SERVICE_NO CBG_DISTANCE_FARE.SERVICE_NO%TYPE,
DISTANCE CBG_DISTANCE_FARE.DISTANCE%TYPE,
CASH_FARE_AC CBG_DISTANCE_FARE.CASH_FARE_AC%TYPE,
CASH_FARE_NON_AC CBG_DISTANCE_FARE.CASH_FARE_NON_AC%TYPE,
CARD_FARE_AC CBG_DISTANCE_FARE.CARD_FARE_AC%TYPE,
CARD_FARE_NON_AC CBG_DISTANCE_FARE.CARD_FARE_NON_AC%TYPE,
EZLINK_FARE_AC CBG_DISTANCE_FARE.EZLINK_FARE_AC%TYPE,
EZLINK_FARE_NON_AC CBG_DISTANCE_FARE.EZLINK_FARE_NON_AC%TYPE,
AVG_RUNTIME CBG_DISTANCE_FARE.AVG_RUNTIME%TYPE,
ALTERNATIVE_NO CBG_DIRECT_ALT.ALTERNATIVE_NO%TYPE,
MAX_FREQ_AM CBG_SVC.MAX_FREQ_AM%TYPE,
MIN_FREQ_AM CBG_SVC.MIN_FREQ_AM%TYPE,
ADVANTAGE_CODE CBG_DIRECT_ALT.ADVANTAGE_CODE%TYPE,
DIST_FARE_CODE_1 CBG_DISTANCE_FARE.DIST_FARE_CODE%TYPE,
DIST_FARE_CODE_2 CBG_DISTANCE_FARE.DIST_FARE_CODE%TYPE,
DIST_FARE_CODE_3 CBG_DISTANCE_FARE.DIST_FARE_CODE%TYPE,
FROM_STOP_CODE CBG_DISTANCE_FARE.FROM_STOP_CODE%TYPE,
TO_STOP_CODE CBG_DISTANCE_FARE.TO_STOP_CODE%TYPE,
MIN_TIME CBG_DIRECT_ALT.MIN_TIME%TYPE,
MIN_FARE CBG_DIRECT_ALT.MIN_FARE%TYPE,
ACT_FARE CBG_DIRECT_ALT.MIN_FARE%TYPE,
TRAVEL_TYPE VARCHAR2(4),
TRANSFER_INFO VARCHAR2(1),
END_TRANSFER_INFO VARCHAR2(1));
--TABLE TYPE DECLARATION
TYPE BUS_INFO_TAB IS TABLE OF DIRECT_ALT_REC INDEX BY BINARY_INTEGER;
-- CURSOR TYPE DECLARATION
TYPE TEMP_REC_STRUCT1 IS RECORD (
RECORD_POSITION BINARY_INTEGER,
DIST_FARE_CODE1 CBG_DISTANCE_FARE.DIST_FARE_CODE%TYPE,
DIST_FARE_CODE2 CBG_DISTANCE_FARE.DIST_FARE_CODE%TYPE,
DIST_FARE_CODE3 CBG_DISTANCE_FARE.DIST_FARE_CODE%TYPE,
ADVANTAGE_CODE CBG_DIRECT_ALT.ADVANTAGE_CODE%TYPE,
MINIMUM_FARE CBG_DIRECT_ALT.MIN_FARE%TYPE,
MINIMUM_TIME CBG_DIRECT_ALT.MIN_TIME%TYPE,
TRAVEL_TYPE VARCHAR2(4) );
TYPE TEMP_TAB_STRUCT1 IS TABLE OF TEMP_REC_STRUCT1 INDEX BY BINARY_INTEGER;
TEMP_TABLE1 BUS_INFO_TAB;
G_RESULTSET_INDEX BINARY_INTEGER := 0 ;
G_TOT_RECS_IN_TAB1 BINARY_INTEGER := 0 ;
TYPE BUS_INFO_CUR IS REF CURSOR RETURN DIRECT_ALT_REC;
---PROCEDURE INSIDE THE PACKAGE
--- PROCEDURE TO SELECT THE RECORDS
PROCEDURE SEL_DIRECT_ALT(P_FROM_STOP_CODE IN VARCHAR2,
P_TO_STOP_CODE IN VARCHAR2,
RESULTSET IN OUT BUS_INFO_TAB);
I'm using ODP.net and here is my code
string storedprocedure = "PKG_TRAVEL_NEW_SUND.SEL_DIRECT_ALT";
//PKG_TRAVEL_NEW_SUND
//CBG003_XP_SP_TEST1
ArrayList retlist = new ArrayList();
OracleConnection curr_conn = this.GetOpenConnection();
OracleCommand cmd = curr_conn.CreateCommand();
cmd = new OracleCommand(storedprocedure, curr_conn);
cmd.CommandType = CommandType.StoredProcedure;
// input parameter
OracleParameter param1 = new OracleParameter();
OracleParameter param2 = new OracleParameter();
param1.ParameterName = "start_code";
param2.ParameterName = "end_code";
param1.OracleDbType = OracleDbType.Varchar2;
param2.OracleDbType = OracleDbType.Varchar2;
param1.Direction = ParameterDirection.Input;
param2.Direction = ParameterDirection.Input;
param1.Size = 5;
param2.Size = 5;
param1.Value = start_codes;
param2.Value = end_codes;
cmd.Parameters.Add(param1);
cmd.Parameters.Add(param2);
OracleParameter outputparam3 = new OracleParameter();
outputparam3.Direction = ParameterDirection.InputOutput;
outputparam3.ParameterName = "output";
outputparam3.OracleDbType = OracleDbType.RefCursor;
// output type
cmd.Parameters.Add(outputparam3);
cmd.ExecuteNonQuery();
At this point, when i execute Query, i get the message telling me that i could have the wrong number or type arguments for the procedure.
I've looked thru countless examples saying i should use a RefCursor, but what else could i miss out?Hi,
This is from Metalink NOTE.219191.1 How to return the values in a PL/SQL table to a ref cursor
Hope it helps,
Greg
This document gives details with an example on how to pass the values
in a PL/SQL table to a ref cursor.
SCOPE & APPLICATION
This document is useful for developers who are familiar with SQL & PL/SQL
How to return the values in a PL/SQL table to a ref cursor
This can be done by using a SQL Object type instead of a PL/SQL table.
Here is an example.
SQL> create or replace type ObjectType as object
2 ( x int,
3 y date,
4 z varchar2(25)
5 );
6 /
Type created.
SQL> create or replace type TabType as table of ObjectType;
2 /
Type created.
SQL> create or replace
2 function demo_function( p_start_row in number,
3 p_end_row in number )
4 return TabType
5 as
6 l_data TabType := TabType();
7 l_cnt number default 0;
8 begin
9 for x in ( select * from emp order by sal desc )
10 loop
11 l_cnt := l_cnt + 1;
12 if ( l_cnt >= p_start_row )
13 then
14 l_data.extend;
15 l_data(l_data.count) :=
16 objectType( x.empno,
17 x.hiredate,
18 x.ename );
19 end if;
20 exit when l_cnt = p_end_row;
21 end loop;
22
23 return l_data;
24 end;
25 /
Function created.
SQL> select *
2 from the ( select cast( demo_function(3,7) as TabType )
3 from dual ) a;
X Y Z
7902 03-DEC-81 FORD
7566 02-APR-81 JONES
7698 01-MAY-81 BLAKE
7782 09-JUN-81 CLARK
7844 08-SEP-81 TURNER
By using a SQL object type, the table can be selected easily.
SQL> create or replace package demo_pkg
2 as
3 type rc is ref cursor;
4
5 procedure p( p_cursor in out rc );
6 end;
7 /
Package created.
SQL> create or replace package body demo_pkg
2 as
3
4 procedure p( P_cursor in out rc )
5 is
6 l_data TabType := TabType();
7 begin
8 for i in 1 .. 3 loop
9 l_data.extend;
10 l_data(i) :=
11 ObjectType( i, sysdate+i, i || ' data');
12 end loop;
13
14 open p_cursor for
15 select *
16 from TABLE ( cast ( l_data as TabType) );
17 end;
18
19 end;
20 /
Package body created.
SQL> set autoprint on
SQL> variable x refcursor
SQL> exec demo_pkg.p(:x)
PL/SQL procedure successfully completed.
X Y Z
1 15-NOV-02 1 data
2 16-NOV-02 2 data
3 17-NOV-02 3 data -
How to get highest number of open cursors within the current calendar day
Hi all ,
i need to know how to get the highest number of open cursors within the current calendar day.
Thanks ,823030 wrote:
the issue is my customer is getting the error ORA-01000: maximum open cursors exceeded and we need an sql statment that gets the following values :
-highest number of open cursors experienced in the current calendar day.
-current open cursors
-and maximum open cursorsThis error is rare. It happens when
a) the value of the open cursor parameter is set extremly low (default is something like 1000). Low would be something like 10.
b) <strike>you have many concurrent users(=sessions) and </strike>the application does not use bind values
In this case each select will open a new cursor, instead of reusing it.
c) you have a select that opens a cursor for each line. This can happen with a statement where you have the CURSOR keyword somewhere in the select or where clause. Those cursors will be closed when the select is finished. But during the run time of the select, all cursors stay open.
To track the number of "open cursors" during the day you would need to implement some monitoring. Maybe based on the view that was already mentioned.
Edited by: Sven W. on May 16, 2011 2:30 PM - since the parameter is on session level, other open cursors should not influence it much. -
How to get query text from reference cursor
Oracle 9.2.0.5
create or replace procedure test3
is
lcur sys_refcursor;
lquery varchar2(2000);
begin
OPEN lcur FOR
SELECT CONTRACT_ID FROM CONTRACT;
lquery := lcur.Query; -- <= Pseudocode
end;Basically, if someone passes a reference cursor, how can I get the "text" of the cursor. I want to pass it to DBMS_DESCRIBE.PARSE...so that I eventually call DBMS_SQL.DESCRIBE_COLUMNS.
Thanks,
JasonDo you have a code example?
Ideally, I'd like to use Pl/SQL only, but if I have to do it in Java, I will.
Thanks,
Jason -
How to convert the varray to ref cursor
Hi,
Is there any way to convert varray to ref cursor....
i dont want to use any table or record as an ref cursor..
i just want to create a procedure which returns a ref cursor..
below is the sample procedure for it..
create or replace procedure FETCH_DATA1
tab_name in varchar2,
p_recordset1 OUT fetch_data_pak.ref_cursor
AS
type v_array1 is varray(1000) of t_transaction%rowtype;
v_array2 v_array1;
cursor s1 is select * from t_transaction where lastupdate_date > '08-Aug-09';
begin
open s1;
fetch s1 bulk collect into v_array2 limit 100;
close s1;
select * from table(cast (v_array2 as p_recordset1));
end FETCH_DATA1;
I need to convert the varray to ref cursor.....Why put it into a varray at all?
You can just open the ref cursor for that select you are desiring.
And if you need to limit it to returning just the first 100 (as your code seems to imply), wrap it and filter on rownum.
Something similar to this:
create or replace procedure FETCH_DATA1
tab_name in varchar2,
p_recordset1 OUT fetch_data_pak.ref_cursor
AS
begin
open p_recordset1 for
select /*+ first_rows(100) */ * from (
select * from t_transaction
where lastupdate_date > to_date('08-08-2009','DD-MM-YYYY')
--order by something
where rownum <= 100;
end FETCH_DATA1;And note, that you really should have an order by when you wish to limit yourself to "first 100 rows" - otherwise it will be "random 100 rows".
That goes for your cursor solution as well...
Edited by: Kim Berg Hansen on Nov 28, 2011 10:25 AM
Added explicit date conversion - it is bad practice not to explicitly convert dates ;-) -
How to update data returned using REF CURSOR
Hi all,
I am trying to update updated data in a gridview but the update button seem to do nothing as i retrieve data using REF CURSOR.
Let me describe the architecture of my application first. I'm trying to implement best practice whenever possible. I am following the data access tutorial published in www.asp.net , the only difference is that i have an Oracle (10g) database. So I split my application into three layers, data access, business logic, and presentation layer. I'm also writing all queries in an Oracle package.
So I have my Oracle packages that perform CRUD operations. Then I have an xsd file that define dataTable based on the package procedure. My business logic layer then calls functions defined in the xsd file. And finally a detailsView control that uses an ObjectDataSource to call business logic functions.
In a nutshell, I am just trying to update records retrieved using REF CURSOR. Your help is very much appreciated. Please let me know if further details are required. Cheers,In the DataSet (xsd) where your DataTable is defined, you just need to add additional methods to the TableAdapter to handle insert, update and delete, either with SQL or by mapping to stored procedures.
Alternatively in code, create an OracleDataAdapter and supply its InsertCommand, UpdateCommand and DeleteCommand.
David -
How to use BULK COLLECT in ref cursor?
hi,
can we use bulk collect in ref cursor ? if yes then please give small example ..
thanksTry this:
create or replace type person_ot as object (name varchar2(10)) not final;
create or replace type student_ot under person_ot (s_num number) not final;
create type person_tt as table of person_ot;
create table persons of person_ot;
declare
lv_person_list person_tt;
lv_sql varchar2(1000);
ref_cur sys_refcursor;
begin
lv_sql:= 'select new student_ot(''fred'', 100) from dual
union all
select new student_ot(''sally'', 200) from dual';
open ref_cur for lv_sql;
fetch ref_cur bulk collect into lv_person_list;
close ref_cur;
for i in lv_person_list.first..lv_person_list.last loop
dbms_output.put_line(lv_person_list(i).name );
end loop;
forall i in lv_person_list.first..lv_person_list.last
insert into persons values lv_person_list(i);
end;
/ -
How to get SQL text from dbms_sql cursor ID
Hello,
I have a progam using dbms_sql. A cursor is built by dbms_sql.parse (cur_id, v_query, dbms_sql.native);From now on I have only the internal ID cur_id of the cursor. Is there a way to get back the original query the cursor is built from when the cursor is passed to another package?
Regards
MarcusOracle provides several views that show part or all of the SQL statement. See your Oracle version# Reference manual for v$sql...
v$sqltext is one view that displays the full text but the text is contained in multiple rows.
HTH -- Mark D Powell -- -
AS3: TextField - How do get rid of text select cursor
SC3 - AS3
How do we turn off the text select cursor?
I have a button object that has dynamic text, and the hand
cursor works fine outside of the text object but over the text
object the cursor is changing to a text select cursor!
I am setting selectable to false for the text field.Is your dynamic text field part of a button? I just created a
test file with a dynamic text field set to not selectable and it is
not showing the text cursor.
Also, are you dynamically generating the text field or are
you drawing it on the stage? -
How to call a Stored Procedure with a REF CURSOR output parameter
I am looking forward an example that call a stored function/procedure with a REF CURSOR output parameter and get the result.
In other words, I have a stored function/procedure that execute a SELECT statement using the OCI library and then it could get the values of each column and each row.
I put a code snippet, it have only the main thing to call a simple stored procedure and print the name of each column of the cursor, but I couldn´t to print out the values in the table that call the stored procedure.
I understand that the next step, it is to call a OCIStmtFetch.
How to associate the cursor with the OCIStmtFetch?
If you need more information, only tell me.
I am using ANSI C with HP-UX Operative System (C for HP-UX) and Oracle 10g.
Regards.
Antonio Garcia
/* callOracleSP */
#include <stdio.h>
#include <string.h>
#include <oci.h>
#include <stdlib.h>
char* pConnectChar ="server";
char* pUsernameChar = "user";
char* pPasswordChar = "passwd";
char* sqlCharArray1 = "BEGIN SP_GETCITIES(:s, :c); END;";
int retval;
ub4 parmcnt=0;
ub4 pos2=0;
text *pcoln[20];
ub4 namelen[20];
char state_key[5];
OCIStmt* pOciStatement;
OCIStmt* pOciStatCursor;
OCIError* pOciError;
OCIEnv* pOciEnviron;
OCIServer* pOciServer;
OCISession* pOciSession;
OCISvcCtx* pOciServiceContext;
OCIBind* pOciBind[500];
OCIParam* pOciParam;
int main()
retval = OCIEnvCreate(&pOciEnviron, OCI_DEFAULT, NULL, NULL, NULL, NULL,0,NULL);
retval = OCIEnvInit(&pOciEnviron, OCI_DEFAULT, 0, NULL);
retval = OCIHandleAlloc(pOciEnviron, (void **)&pOciError, OCI_HTYPE_ERROR, 0, NULL);
retval = OCIHandleAlloc(pOciEnviron, (void **)&pOciServiceContext, OCI_HTYPE_SVCCTX, 0, NULL);
retval = OCIHandleAlloc(pOciEnviron, (void **)&pOciStatement, OCI_HTYPE_STMT, 0, NULL);
retval = OCILogon(pOciEnviron,pOciError,&pOciServiceContext,(unsigned char *)pUsernameChar,
strlen(pUsernameChar), (unsigned char *)pPasswordChar, strlen(pPasswordChar),
(unsigned char *)pConnectChar,strlen(pConnectChar));
printf("OCILogon retval=%d\n",retval);
retval = OCIStmtPrepare(pOciStatement, pOciError, (unsigned char *)sqlCharArray1,strlen(sqlCharArray1),
OCI_NTV_SYNTAX, OCI_DEFAULT);
printf("StmtPrepare retval=%d\n",retval);
retval = OCIHandleAlloc(pOciEnviron, (void **)&pOciStatCursor, OCI_HTYPE_STMT, 0, NULL);
retval = OCIBindByPos(pOciStatement,&pOciBind[0], pOciError, (ub4) 1, (void *)&state_key,
(sb4) sizeof(state_key), SQLT_STR, (void *) 0, (ub2 *) 0, (ub2 *)0,(ub4)0, (ub4 *)0, (ub4) OCI_DEFAULT);
printf("BindByPos OCI_HTYPE_STMT retval=%d\n",retval);
retval = OCIBindByPos(pOciStatement,&pOciBind[1], pOciError, (ub4) 2, (void *)&pOciStatCursor,
(sb4) 0, SQLT_RSET, (void *) 0, (ub2 *) 0, (ub2 *)0,(ub4)0, (ub4 *)0, (ub4) OCI_DEFAULT);
printf("BindByPos OCI_HTYPE_STMT retval=%d\n",retval);
strcpy(state_key,"CA");
retval = OCIStmtExecute(pOciServiceContext, pOciStatement, pOciError, (ub4)1, (ub4) 0,
(OCISnapshot *)NULL, (OCISnapshot *)NULL, (ub4) OCI_DEFAULT);
printf("StmtExecute retval=%d\n",retval);
/* How to get the values of the cursor? */
/* Get number of parameters of the Cursor */
OCIAttrGet((void *) pOciStatCursor, (ub4)OCI_HTYPE_STMT, (void*) &parmcnt,(ub4 *) 0,
(ub4)OCI_ATTR_PARAM_COUNT, pOciError);
printf("\nNumber of parameters of the cursor = %d\n",parmcnt);
for (int pos = 1; pos <= (int)parmcnt; pos++)
OCIAttrGet((void *) pOciStatCursor, (ub4)OCI_HTYPE_STMT, (void*) &pos2,(ub4 *) 0,
(ub4)OCI_ATTR_CURRENT_POSITION, pOciError);
retval = OCIParamGet((void *)pOciStatCursor, (ub4)OCI_HTYPE_STMT, pOciError, (void **)&pOciParam,
(ub4) pos );
OCIAttrGet((void*) pOciParam, (ub4) OCI_DTYPE_PARAM,(void*) &pcoln[pos-1],(ub4 *) &namelen[pos-1],
(ub4) OCI_ATTR_NAME,(OCIError *)pOciError );
for (int i = 1; i <=(int)parmcnt; i++)
printf("Column %i\tNAME = %.*s\n",i,namelen[i-1],pcoln[i-1]);
return 0;
This is the script that create the table, insert records and create the stored procedure
CREATE TABLE CITIES (
STATE_CODE VARCHAR2(2) NULL,
CITY_CODE NUMBER(15,5) NULL,
CITY_NAME VARCHAR2(30) NULL
INSERT INTO CITIES(STATE_CODE, CITY_CODE, CITY_NAME)
VALUES('CA', 30, 'SAN DIEGO')
INSERT INTO CITIES(STATE_CODE, CITY_CODE, CITY_NAME)
VALUES('CA', 40, 'SACRAMENTO')
INSERT INTO CITIES(STATE_CODE, CITY_CODE, CITY_NAME)
VALUES('FL', 10, 'MIAMI')
INSERT INTO CITIES(STATE_CODE, CITY_CODE, CITY_NAME)
VALUES('FL', 20, 'ORLANDO')
INSERT INTO CITIES(STATE_CODE, CITY_CODE, CITY_NAME)
VALUES('NY', 10, 'NEW YORK')
INSERT INTO CITIES(STATE_CODE, CITY_CODE, CITY_NAME)
VALUES('NY', 20, 'ALBANY')
INSERT INTO CITIES(STATE_CODE, CITY_CODE, CITY_NAME)
VALUES('CA', 10, 'LOS ANGELES')
INSERT INTO CITIES(STATE_CODE, CITY_CODE, CITY_NAME)
VALUES('CA', 20, 'SAN FRANCISCO')
CREATE OR REPLACE PACKAGE globalPkg AUTHID CURRENT_USER AS
/* The following are T/SQL specific global variables. */
TYPE RCT1 IS REF CURSOR;/*new weak cursor definition*/
END globalPkg;
CREATE OR REPLACE PROCEDURE SP_ADDCITY(
P_STATE_CODE IN VARCHAR,
P_CITY_CODE IN NUMBER,
P_CITY_NAME IN VARCHAR2,
P_RETURN IN OUT NUMBER)
AS
StoO_error INTEGER;
StoO_selcnt INTEGER;
StoO_rowcnt INTEGER;
StoO_errmsg VARCHAR2(255);
BEGIN
StoO_rowcnt := 0;
StoO_error := 0;
StoO_selcnt := 0;
P_RETURN := 0;
INSERT INTO CITIES (STATE_CODE, CITY_CODE, CITY_NAME)
VALUES (P_STATE_CODE, P_CITY_CODE, P_CITY_NAME);
StoO_rowcnt := SQL%ROWCOUNT;
EXCEPTION
WHEN TOO_MANY_ROWS THEN
StoO_rowcnt := 2;
WHEN OTHERS THEN
StoO_rowcnt := 0;
StoO_selcnt := 0;
StoO_error := SQLCODE;
StoO_errmsg := SQLERRM;
IF StoO_error != 0 THEN
BEGIN
P_RETURN := 1;
RETURN;
END;
END IF;
END;
CREATE OR REPLACE PROCEDURE SP_GETCITIES(
STATE_KEY IN VARCHAR,
RC1 IN OUT globalPkg.RCT1)
AS
StoO_error INTEGER;
StoO_selcnt INTEGER;
StoO_rowcnt INTEGER;
StoO_errmsg VARCHAR2(255);
BEGIN
StoO_rowcnt := 0;
StoO_error := 0;
StoO_selcnt := 0;
OPEN RC1 FOR
SELECT STATE_CODE, CITY_CODE, CITY_NAME
FROM CITIES
WHERE STATE_CODE = STATE_KEY
ORDER BY CITY_CODE;
StoO_rowcnt := SQL%ROWCOUNT;
EXCEPTION
WHEN OTHERS THEN
StoO_rowcnt := 0;
StoO_error := SQLCODE;
StoO_errmsg := SQLERRM;
END;
/Hi Mark,
Thanks for your recommendations.
I change the code with OCIDefineByPos, one for each parameter from cursor and then use the OCIStmtFetch.
I don´t receive a error when call OCIDefineByPos, but when I call OCIStmtFetch receive a -1 error number.
What is wrong with the code?
The script is the same.
I need your help!
Best Regards!
Antonio Garcia (Mexico)
This the new code:
#include <stdio.h>
#include <string.h>
#include <oci.h>
#include <stdlib.h>
char* pConnectChar ="ORAC617";
char* pUsernameChar = "C617_005_DBO_01";
char* pPasswordChar = "Tempora1";
char* sqlCharArray1 = "BEGIN SP_GETCITIES(:s, :c); END;";
int retval;
ub4 parmcnt=0;
ub4 pos2=0;
sb2 *c_indp;
text *pcoln[20], *name,*name2;
ub4 namelen[20],len;
ub2 type,size;
char state_key[5];
OCIDefine *pdef;
OCIBind *p_bnd;
ub1 **c_buf;
OCIStmt* pOciStatement; /* Statement handle */
OCIStmt* pOciStatCursor; /* Statement handle */
OCIError* pOciError; /* Error handle */
OCIEnv* pOciEnviron; /* Environment handle */
OCIServer* pOciServer; /* Server handle */
OCISession* pOciSession; /* Session handle */
OCISvcCtx* pOciServiceContext; /* Service Context handle */
OCIBind* pOciBind[500]; /* Bind handle */
OCIParam* pOciParam; /* Param handle */
int OCI_Fetch(OCIStmt *p_select,OCIError *p_err, int *piOcc)
int iOcc, rc;
rc=OCIStmtFetch(p_select,p_err,1,OCI_FETCH_NEXT,OCI_DEFAULT);
printf("rc fetch %i",rc);
if(rc==0&&piOcc!=NULL){
printf("entro al if");
iOcc=*piOcc;
*piOcc=iOcc+1;
return rc;
int main()
int pos,i=0,rc;
retval = OCIEnvCreate(&pOciEnviron, OCI_DEFAULT, NULL, NULL, NULL, NULL,0,NULL);
printf("EnvCreate retval=%d\n", retval);
retval = OCIEnvInit(&pOciEnviron, OCI_DEFAULT, 0, NULL);
printf("EnvInit retval=%d\n",retval);
retval = OCIHandleAlloc(pOciEnviron, (void **)&pOciError, OCI_HTYPE_ERROR, 0, NULL);
printf("HandleAlloc OCI_HTYPE_ERROR retval=%d\n",retval);
retval = OCIHandleAlloc(pOciEnviron, (void **)&pOciServiceContext, OCI_HTYPE_SVCCTX, 0, NULL);
printf("HandleAlloc OCI_HTYPE_SVCCTX retval=%d\n",retval);
retval = OCIHandleAlloc(pOciEnviron, (void **)&pOciStatement, OCI_HTYPE_STMT, 0, NULL);
printf("HandleAlloc OCI_HTYPE_STMT retval=%d\n",retval);
retval = OCILogon(pOciEnviron,pOciError,&pOciServiceContext,(unsigned char *)pUsernameChar,
strlen(pUsernameChar), (unsigned char *)pPasswordChar, strlen(pPasswordChar),
(unsigned char *)pConnectChar,strlen(pConnectChar));
printf("OCILogon retval=%d\n",retval);
retval = OCIStmtPrepare(pOciStatement, pOciError, (unsigned char *)sqlCharArray1,strlen(sqlCharArray1),
OCI_NTV_SYNTAX, OCI_DEFAULT);
printf("StmtPrepare retval=%d\n",retval);
retval = OCIHandleAlloc(pOciEnviron, (void **)&pOciStatCursor, OCI_HTYPE_STMT, 0, NULL);
printf("HandleAlloc OCI_HTYPE_STMT retval=%d\n",retval);
retval = OCIBindByPos(pOciStatement,&pOciBind[0], pOciError, (ub4) 1, (void *)&state_key,
(sb4) sizeof(state_key), SQLT_STR, (void *) 0, (ub2 *) 0, (ub2 *)0,(ub4)0, (ub4 *)0, (ub4) OCI_DEFAULT);
printf("BindByPos OCI_HTYPE_STMT retval=%d\n",retval);
retval = OCIBindByPos(pOciStatement,&pOciBind[1], pOciError, (ub4) 2, (void *)&pOciStatCursor,
(sb4) 0, SQLT_RSET, (void *) 0, (ub2 *) 0, (ub2 *)0,(ub4)0, (ub4 *)0, (ub4) OCI_DEFAULT);
printf("BindByPos OCI_HTYPE_STMT retval=%d\n",retval);
strcpy(state_key,"CA");
retval = OCIStmtExecute(pOciServiceContext, pOciStatement, pOciError, (ub4)1, (ub4) 0,
(OCISnapshot *)NULL, (OCISnapshot *)NULL, (ub4) OCI_DEFAULT);
printf("StmtExecute retval=%d\n",retval);
c_buf=(ub1 **)calloc(sizeof(ub1 *),3);
c_indp=(sb2 *)calloc(sizeof(sb2 *),3);
// Get number of parameters of the Cursor
OCIAttrGet((void *) pOciStatCursor, (ub4)OCI_HTYPE_STMT, (void*) &parmcnt,(ub4 *) 0,
(ub4)OCI_ATTR_PARAM_COUNT, pOciError);
printf("\nNumber of parameters of the cursor = %d\n",parmcnt);
for (pos = 1; pos <= (int)parmcnt; pos++)
OCIAttrGet((void *) pOciStatCursor, (ub4)OCI_HTYPE_STMT, (void*) &pos2,(ub4 *) 0,
(ub4)OCI_ATTR_CURRENT_POSITION, pOciError);
retval = OCIParamGet((void *)pOciStatCursor, (ub4)OCI_HTYPE_STMT, pOciError, (void **)&pOciParam,(ub4) pos );
// Get the column name
OCIAttrGet((void*) pOciParam, (ub4) OCI_DTYPE_PARAM,(void*) &name,(ub4 *) &len, (ub4) OCI_ATTR_NAME,(OCIError *)pOciError );
// Get the column datatype
OCIAttrGet((void*) pOciParam, (ub4) OCI_DTYPE_PARAM,(void*) &type,(ub4 *)0,(ub4)OCI_ATTR_DATA_TYPE,(OCIError *)pOciError);
// Get the column size
OCIAttrGet((void*) pOciParam, (ub4) OCI_DTYPE_PARAM,(void*) &size,(ub4 *)0,(ub4)OCI_ATTR_DATA_SIZE,(OCIError *)pOciError);
printf("Column %i\tNAME = %.*s \ttype %d \tsize %d\n",pos,len,name,type,size);
// OCIDefine ByPos, one for each parameter
// c_buf store the STATE_CODE, CITY_CODE and CITY_NAME columns from the cursor
rc=OCIDefineByPos(pOciStatCursor,&pdef,(OCIError *)pOciError,pos,c_buf[pos-1],size+1,(ub2)type,(dvoid *)c_indp[pos-1],(ub2 *)0,(ub2 *)0,OCI_DEFAULT);
printf("OCIDefineByPos retval=%d\n,rc);
// call OCIStmtFetch. In the next line, I receive the error
rc=OCIStmtFetch(pOciStatCursor,pOciError,1,OCI_FETCH_NEXT,OCI_DEFAULT);
printf("rc fetch %i",rc);
return 0;
{code} -
Is there a different way to open a cursor for a ref cursor procedure?
hello everybody
i have two cursors, cur_a and cur_b, declared somewhere else in my application.
These two cursors have the same fields, in the same order, and i have to treat both in the same way. So i wrote a routine that gets as input a ref cursor based on the cur_a rowtype, and i am trying to use this routine for both.
The problem is that i am not able to open outside the routine the cursor in a different way than usual...
the common method is :
declare curs ref cursor ...
begin
open curs for (select *...)
end;
instead i would like to obtain something different
declare curs ref cursor ...
begin
open curs for cur_a
end;hi
thanks for answering
i wanted just to give a better idea, anyway you were near to get it.
the only difference is that the two cursors are not written in dynamic sql, just like strings, but are real cursors.
anyway, this is the version of the package i need, but i am not able to compile
(your original code is commented and immediately below there is my code)
CREATE OR REPLACE PACKAGE BODY mytest
IS
--cur_a VARCHAR2(200) := 'SELECT dummy FROM DUAL';
CURSOR cur_a
IS
SELECT dummy
FROM DUAL;
--cur_b VARCHAR2(200) := 'SELECT ''fred'' FROM DUAL';
CURSOR cur_b
IS
SELECT 'fred' fred
FROM DUAL;
TYPE t_cur_a IS REF CURSOR
RETURN cur_a%ROWTYPE
--PROCEDURE routine_a_b (p_cur SYS_REFCURSOR) IS
PROCEDURE routine_a_b (p_cur t_cur_a)
IS
v_x VARCHAR2 (10);
BEGIN
LOOP
FETCH p_cur
INTO v_x;
EXIT WHEN p_cur%NOTFOUND;
DBMS_OUTPUT.put_line (v_x);
END LOOP;
END;
PROCEDURE doit
IS
--v_curs SYS_REFCURSOR;
v_curs t_cur_a;
BEGIN
NULL;
-- open v_curs FOR cur_a;
OPEN v_curs FOR cur_a;
routine_a_b (v_curs);
CLOSE v_curs;
-- open v_curs FOR cur_b;
-- routine_a_b(v_curs);
-- close v_curs;
END;
END;
the error is:
cursor 'V_CURS' cannot be used in dynamic SQL OPEN statement
i did read that if use weak ref cursor, it could work, so i declare the ref cursor type in this way:
TYPE t_cur_a IS REF CURSOR;
instead than
TYPE t_cur_a IS REF CURSOR
RETURN cur_a%ROWTYPE
what i get is another error (in the open cursor command)
PLS-00382: expression is of wrong type....
but if i replace
OPEN v_curs FOR cur_a;
with
OPEN v_curs for select dummy from dual;
it works... but i already knew it.. :-)
anyway, i used a work around to resolve it, so it's just philosophy -
Hello All,
I have a small procedure like the following.
CREATE OR REPLACE procedure PROC_DEPT_SALE(SALEC_CUR out sys_refcursor)
as
begin
open sale for select * from dept_sale where dept_no='Z2341324';
end;
I just want to execute it from toad like
exec PROC_DEPT_SALE( C1);
In order to do that i need to have a sys_refcursor c1 created in my DB. I know that i can execute it as a plsql block like this
DECLARE
SALE SYS_REFCURSOR;
BEGIN
PROC_DEPT_SALE( SALE );
END;
Could anyone please let me know how can i create a TYPE REF cursor which is permanantly stored in the DB and then execute the proc the way i wanted to using the first statement.
ThanksActually, you had it correct with
CREATE OR REPLACE package cur_type as
TYPE ref_cur IS REF CURSOR;
end;but you still need to declare a variable of the type to pass the the procedure since the procedure needs to have a cursor variable to open. Given your package, the call would be more like:
DECLARE
l_cur cur_type.ref_cur;
BEGIN
proc_dept_sale(l_cur);
<do something with l_cur>
END;Forget about the cursor for a minute and think through this example. If I have a procedure that looks like:
CREATE PROCEDURE get_name (p_id IN NUMBER,
p_name OUT VARCHAR2) AS
BEGIN
SELECT last_name||', '||first_name
INTO p_name
FROM employee
WHERE emp_id = p_id;
END;I can pass a literal value to the procedure for the p_id parameter (e.g. 42) or I could pass a variable holding a value.
What do I need to pass to the procedure in p_name to get the name back out? A procedure returning a cursor is no different than this in concept.
John
Maybe you are looking for
-
IPod touch 5g is ocassionally unresponsive to touch when flat on a surface.
This happens a good portion of the time, though not always, that it is laying flat on a surface. Sometimes it continues afer I pick it up. Most of the time it starts working normally when I turn the screen off and then on again, but sometimes takes a
-
Error while printing smartforms
Hi Friends, I am getting error "<b>Invalid value for parameter ARCHDEST</b>" while printing smartforms. This is happening only in IDES server. In Development the same smartform is working normally. I have checked in transaction SU53, to see whether
-
Button not working on ear pods
I bought a new pair of Apple Ear Pods four months ago, and they have been great. Then, for no apparent reason, the button stopped working. The audio is perfect, but I can't use the button to play/pause, change volume, and the microphone is also not w
-
X100e problems with the BIOS update
Hello, this is my first message and my english is not so good. I have a problem on my X100e to make a BIOS update. I download the newest update from Lenovo and burn a CD. At next i boot from this CD with the X100e and the update starts. But after a f
-
How to use a link bar or navigation bar for display only?
My app has a link bar in an Application Control bar that is bound to the view stack of the steps in my application. I would like to use this as a mechanism to show the user which step he is on and how many are left, but NOT to click on it to navigate