REF Cursor Rowcount
I need to get the rowcount for the refcursor before fetching the data itself.
Please let me know how to get the same.
Example:
Open X FOR Query
var:= x%rowcount
Once this executed i am getting the value var is 0 but it's retriving some rows to java environment.
PL/SQL 101 : Understanding Ref Cursors
Similar Messages
-
Dynamic sql and ref cursors URGENT!!
Hi,
I'm using a long to build a dynamic sql statement. This is limited by about 32k. This is too short for my statement.
The query results in a ref cursor.
Does anyone have an idea to create larger statement or to couple ref cursors, so I can execute the statement a couple of times and as an result I still have one ref cursor.
Example:
/* Determine if project is main project, then select all subprojects */
for i in isMainProject loop
if i.belongstoprojectno is null then
for i in ProjectSubNumbers loop
if ProjectSubNumbers%rowcount=1 then
SqlStatement := InitialStatement || i.projectno;
else
SqlStatement := SqlStatement || PartialStatement || i.projectno;
end if;
end loop;
else
for i in ProjectNumber loop
if ProjectNumber%rowcount=1 then
SqlStatement := InitialStatement || i.projectno;
else
SqlStatement := SqlStatement || PartialStatement || i.projectno;
end if;
end loop;
end if;
end loop;
/* Open ref cursor */
open sql_output for SqlStatement;
Thanks in advance,
Jeroen Muis
KCI Datasystems BV
mailto:[email protected]Example for 'dynamic' ref cursor - dynamic WHERE
(note that Reports need 'static' ref cursor type
for building Report Layout):
1. Stored package
CREATE OR REPLACE PACKAGE report_dynamic IS
TYPE type_ref_cur_sta IS REF CURSOR RETURN dept%ROWTYPE; -- for Report Layout only
TYPE type_ref_cur_dyn IS REF CURSOR;
FUNCTION func_dyn (p_where VARCHAR2) RETURN type_ref_cur_dyn;
END;
CREATE OR REPLACE PACKAGE BODY report_dynamic IS
FUNCTION func_dyn (p_where VARCHAR2) RETURN type_ref_cur_dyn IS
ref_cur_dyn type_ref_cur_dyn;
BEGIN
OPEN ref_cur_dyn FOR
'SELECT * FROM dept WHERE ' | | NVL (p_where, '1 = 1');
RETURN ref_cur_dyn;
END;
END;
2. Query PL/SQL in Reports
function QR_1RefCurQuery return report_dynamic.type_ref_cur_sta is
begin
return report_dynamic.func_dyn (:p_where);
end;
Regards
Zlatko Sirotic
null -
How can I see the contents in a Ref Cursor
I have this code:
CREATE OR REPLACE PACKAGE APOD_LOG.APOD_C3_LOG_API_PKG
AUTHID CURRENT_USER
AS
type rc is ref cursor;
PROCEDURE Fetch_Log_Spec
in_LOCAL_IP_VALUE IN BINARY_INTEGER,
out_RESULT_SET OUT rc
END APOD_C3_LOG_API_PKG;
CREATE OR REPLACE PACKAGE BODY APOD_LOG.APOD_C3_LOG_API_PKG
AS
PROCEDURE Fetch_Log_Spec
in_LOCAL_IP_VALUE IN BINARY_INTEGER,
out_RESULT_SET OUT rc
IS
BEGIN
DBMS_APPLICATION_INFO.set_module(module_name => 'APOD_LOG.API_PKG',action_name => 'Fetch_Log_Spec');
DBMS_APPLICATION_INFO.set_client_info(client_info => 'Calling with in_LOCAL_IP_VALUE = ' ||to_char(in_LOCAL_IP_VALUE));
open out_RESULT_SET for
select
in_LOCAL_IP_VALUE as IN_LOCAL_IP_VALUE,
10002 as PORT,
APOD_CORE.UTIL_IP_PKG.IPAddressToIPValue2('''224.168.100.1''') as MULTICAST_IP_VALUE
from
dual
union
select
in_LOCAL_IP_VALUE as IN_LOCAL_IP_VALUE,
10002 as PORT,
APOD_CORE.UTIL_IP_PKG.IPAddressToIPValue2('''224.168.200.1''') as MULTICAST_IP_VALUE
from
dual
union
select
in_LOCAL_IP_VALUE as IN_LOCAL_IP_VALUE,
10002 as PORT,
APOD_CORE.UTIL_IP_PKG.IPAddressToIPValue2('''224.168.100.123''') as MULTICAST_IP_VALUE
from
dual
union
select
in_LOCAL_IP_VALUE as IN_LOCAL_IP_VALUE,
10002 as PORT,
APOD_CORE.UTIL_IP_PKG.IPAddressToIPValue2('''224.168.200.123''') as MULTICAST_IP_VALUE
from
dual;
DBMS_APPLICATION_INFO.set_client_info(client_info => 'Called Fetch_Log_Spec '||to_char(SQL%ROWCOUNT)||' row(s) returned with in_LOCAL_IP_VALUE = '||to_char(in_LOCAL_IP_VALUE) );
END Fetch_Log_Spec;
END APOD_C3_LOG_API_PKG;
And I am trying to test it like this:
DECLARE
IN_LOCAL_IP_VALUE BINARY_INTEGER;
OUT_RESULT_SET APOD_LOG.APOD_C3_LOG_API_PKG.rc;
BEGIN
IN_LOCAL_IP_VALUE := 23374048;
-- OUT_RESULT_SET := NULL; How do I see this
APOD_LOG.APOD_C3_LOG_API_PKG.FETCH_LOG_SPEC ( IN_LOCAL_IP_VALUE, OUT_RESULT_SET );
END;
How can I see the dataset returnd by the OUT_RESULT_SET in SQLPlus or Quest ScriptRunner?A ref cursor doesn't really contain rows but you can use them to reference a SQL statement that fetches the rows.
Re: returning resultset from procedure...or pkg -
How to divide resultset of a query in different ref cursors in a package
Hi Oracle Gurus,
I need to create a package which counts the no of rows returned by a select query on multiple tables and according to the returned rowcount inputs the resultset in a ref cursor. Procedure will be called by a .NET program and output param refcursor will be assigned to a data reader which will redirect all the data to an Excel file.
All the above is done. Issue is due to Excel's limit of 64000 rows, if data returned by query is greater than 64K it wont be fit in 1 Excel sheet. So, in order to overcome this limit I need to do some looping in Oracle package which keeps on storing the query results (rows<64K) in different ref cursors so that these refcursors as OUT params can be redirected to separate Excel sheets in C# program.
NOTE : Earlier on I created 2 procedures in the package to fetch rows<64K and another one to fetch rows between 64K and rowcount of the query. My program was calling 2 different procedures to redirect data into 2 diff Excel sheets.
But this fails when query resultset is even greater than 128000 or more and demands 3-4 or even more Excel sheets to be created.
Please help.
Any idea how to do looping in Oracle to accomplish this?> So, in order to overcome this limit I need to do some looping in Oracle package which keeps on
storing the query results (rows<64K) in different ref cursors so that these refcursors as OUT params
can be redirected to separate Excel sheets in C# program.
Huh?
That is saying that "I need to change this road and build it straight through that lake as the road has a curve here".
It surely is a LOT easier to leave the road as is and simply turn the darn steering wheel in the car?
Have the .Net data reader keep a row count of rows read from the ref cursor - and when it reached a pre-set max, have the reader do a "control break"[1] and change to a new worksheet as the destination for writing the rows to.
[1] Google the term if you do not understand this basic concept that was among the very basic program control structures taught back in the 80's.. while I foam at the mouth how today's "wonder kids" turned programmers, that grew up with computers, do not even comprehend the most basic programming logic designs... -
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} -
Dynamic call for a ref cursor: ORA-21779
Hi,
Here is an environment:
create or replace
PACKAGE PKG_GETDATA AS
TYPE cursor_type IS REF CURSOR;
Procedure SimpleGet (cData In Out Cursor_type);
Procedure DynamicGet (cData In Out Cursor_type);
END PKG_GETDATA;
create or replace
PACKAGE BODY "PKG_GETDATA" AS
Procedure SimpleGet (cData In Out Cursor_type) As
Begin
Open cData For
Select 1 from Dual;
End SimpleGet;
Procedure DynamicGet (cData In Out Cursor_type) As
Begin
Execute Immediate 'Begin PKG_GETDATA.SIMPLEGET(:1); End;'
Using In Out cData;
End DynamicGet;
END PKG_GETDATA;
So- first simple get works fine:
Declare
cData PKG_GETDATA.Cursor_type;
aNumber Number;
Begin
PKG_GETDATA.SimpleGet (cData);
LOOP
FETCH cData INTO aNumber;
EXIT WHEN cData%ROWCOUNT > 5 OR cData%NOTFOUND;
dbms_output.put_line (aNumber);
END LOOP;
close cData;
End;
BUT dynamic call does not works at all!:
Declare
cData PKG_GETDATA.Cursor_type;
aNumber Number;
Begin
PKG_GETDATA.DynamicGet (cData);
LOOP
FETCH cData INTO aNumber;
EXIT WHEN cData%ROWCOUNT > 5 OR cData%NOTFOUND;
dbms_output.put_line (aNumber);
END LOOP;
close cData;
End;
It throws ORA-21779 exception; what is more- it does work on 10.2 db version but does not work on 11.2 version! Could anyone explain that?
Regards
Bartlomiej D.Hi,
Believe me, it may be very handful while working with handlers.
Anyway- could anyone help me on that?
Regards
Bartlomiej D. -
How to count no of rows affected by a ref cursor ?
Hi,
I have taken a ref cursor inside the function since I want to return resultset to the calling application. I also need the NO. OF ROWS AFFECTED by the ref cursor. When I used refcur%rowcount, it returned me 0. Whereas actual no. of rows inside the table is 11.
As a workaround I created a integer variable v_rcount and again executed the cursor's query using count() to store the no. of rows affected by the cursor query. See definition 1 and 2 :
How can I get no. of rows affected by the ref cursor without taking additional variable ??? Any other means available ???
DEFINITION ONE:
create or replace function f_ref()
RETURN curpkg.ref_cursor as
stock_cursor curpkg.ref_cursor;
v_rcount INTEGER;
BEGIN
OPEN stock_cursor FOR SELECT * FROM FIRSTTABLE;
select count(*) into v_rcount from firsttable;
dbms_output.put_line('['|| v_rcount||']');
RETURN stock_cursor;
END;
OUTPUT:
[11]
DEFINITION TWO:
create or replace function f_ref()
RETURN curpkg.ref_cursor as
stock_cursor curpkg.ref_cursor;
v_rcount INTEGER;
BEGIN
OPEN stock_cursor FOR SELECT * FROM FIRSTTABLE;
v_rcount := stock_cursor%rowcount;
dbms_output.put_line('['|| v_rcount||']');
RETURN stock_cursor;
END;
OUTPUT:
[0]michaels> DECLARE
emp_row emp%ROWTYPE;
cur sys_refcursor;
FUNCTION f_ref
RETURN sys_refcursor
AS
stock_cursor sys_refcursor;
BEGIN
OPEN stock_cursor FOR
SELECT *
FROM emp;
RETURN stock_cursor;
END f_ref;
BEGIN
cur := f_ref;
LOOP
FETCH cur
INTO emp_row;
EXIT WHEN cur%NOTFOUND;
END LOOP;
DBMS_OUTPUT.put_line ('Fetched rows: ' || cur%ROWCOUNT);
CLOSE cur;
END;
Fetched rows: 14 -
hi friends,
can somebody tell ,if i want find out my Ref Cursor having data or not.
can i use like below.never tried.
REFCURSORNAME%ROWCOUNT > 0;
if it is there other way please let me know with some example.
--RajnishIt is up to whatever calls the procedure or function to determine whether the returned cursor has rows or not. As Karthik says, the only way to do that is to fetch a row.
The procedure that is opening the cursor to return to a caller cannot do that because the caller would then not get the first row returned unless the called function closed and re-opened the cursor before returning it. However, it is possible that between opening the cursor and and fetching a row to determine if the cursor has records and re-opening it to return to the caller some other process has deleted all of the rows os the cursor will be empty this time.
John -
Getting resultset from out parameter ref cursor
hi,
i have written one procedure which return one refcursor as out parameter.
when i am calling that proceduer how can i retrive that resultsets in my current program.
ex
DECLARE
type A is ref cursor;
B A;
x NUMBER :=0;
BEGIN
APPSEARCH(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,B);
FOR i in b
loop
x:= x+1;
end loop;
DBMS_OUTPUT.PUT_LINE('ANS '||x);
END;
but it is giving error
please advice
thanks
sivaThanks alessandro,
SQL> DECLARE
2 type A is ref cursor;
B A;
3 4 C b%rowtype;
5 d NUMBER;
6 BEGIN
7 APPSEARCH(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,B);
8 loop
9 fetch b into c;
10 exit when b%notfound;
11 DBMS_OUTPUT.PUT_LINE('ANS '||c%rowcount);
12 end loop;
13 close b;
14 END;
15 /
C b%rowtype;
ERROR at line 4:
ORA-06550: line 4, column 4:
PLS-00320: the declaration of the type of this expression is incomplete or
malformed
ORA-06550: line 4, column 4:
PL/SQL: Item ignored
ORA-06550: line 9, column 17:
PLS-00320: the declaration of the type of this expression is incomplete or
malformed
ORA-06550: line 9, column 4:
PL/SQL: SQL Statement ignored
ORA-06550: line 11, column 35:
PLS-00320: the declaration of the type of this expression is incomplete or
malformed
ORA-06550: line 11, column 6:
PL/SQL: Statement ignored
i dont know how to transfer the resultset from the procedure refcursor out parameter to my local cursor variable please help -
Number of total rows returned by a ref cursor without using FETCH
Hi. How can we get the total number of rows returned by a ref cursor without doing the FETCH? I mean, if you use %ROWCOUNT, it only returns the current row number being returned in every fetch. This is not what I want. My purpose is to determine if my query using ref cursor returns greater than zero total rows without using fetch. Thanks.
As John pointed out in the thread you linked to, the only way to know how many rows a query will return is to actually fetch all the rows. Oracle doesn't know how many rows a query is going to return until it actually fetches the last row.
Plus, assuming the default transaction isolation level, if you run the same query multiple times in succession, there is no guarantee that the results will be the same.
If you just want to know whether a query will return a nonzero number of rows, why not just write the code to assume that it returns at least 1 row and handle the zero row result as an exception.
Justin -
Ref Cursor - how to access through parameter name
Hi,
I'm using the below table and sample data. The below script named 'Script1' works well, my concern is values for the first and second parameters need to be used for the thrid and fourth one as well.
When I try with 'Script2' it gives "ORA-01008: not all variables bound ORA-06512: at line 17" error. I know Paramterized cursor can handle this effecively, since it is a dynamic SQL, I need to use from a parameter table, I don't have any control over the number of parameteters, parameter name, type and other things. So, I cannot go for parameterized cursor.
As of now, for my requirement, Script1 works fine, is there any way to make Script2 to work as well, I need to pass paramters by name, not by position, please give your suggestions, thank you.
CREATE TABLE T1
F1 NUMBER(5),
F2 VARCHAR2(100),
F3 DATE
Insert into T1
(F1, F2, F3)
Values
(1, 'One', TO_DATE('08/02/2012 07:43:34', 'MM/DD/YYYY HH24:MI:SS'));
Insert into T1
(F1, F2, F3)
Values
(2, 'Two', TO_DATE('08/02/2012 08:15:24', 'MM/DD/YYYY HH24:MI:SS'));
Insert into T1
(F1, F2, F3)
Values
(3, 'Three', TO_DATE('08/02/2012 08:16:34', 'MM/DD/YYYY HH24:MI:SS'));
COMMIT;
Script1:
declare
TYPE t_ref_cursor IS REF CURSOR;
v_cursor t_ref_cursor;
v_query_str varchar2(3000);
v_f1 number(5);
v_f2 varchar2(100);
v_f3 date;
begin
v_query_str := 'SELECT f1, f2, f3 from t1 where f1 = :p1 and f3 = to_date(:p2, ''DD-MON-YYYY hh24:mi:ss'') union ';
v_query_str := v_query_str || 'select 1, ''c1'', sysdate from dual where not exists (select 1 from t1 where f1 = :p3 and f3 = to_date(:p4, ''DD-MON-YYYY hh24:mi:ss''))';
--dbms_output.put_line(v_query_str);
open v_cursor for v_query_str using 1, '02-AUG-2012 07:43:34', 1, '02-AUG-2012 07:43:34';
loop
fetch v_cursor into v_f1, v_f2, v_f3;
exit when v_cursor%notfound;
dbms_output.put_line(v_f1 || ' ' || v_f2 || '' || v_f3);
end loop;
dbms_output.put_line('rowcount ' || v_cursor%rowcount);
close v_cursor;
end;
Script2:
declare
TYPE t_ref_cursor IS REF CURSOR;
v_cursor t_ref_cursor;
v_query_str varchar2(3000);
v_f1 number(5);
v_f2 varchar2(100);
v_f3 date;
begin
v_query_str := 'SELECT f1, f2, f3 from t1 where f1 = :p1 and f3 = to_date(:p2, ''DD-MON-YYYY hh24:mi:ss'') union ';
v_query_str := v_query_str || 'select 1, ''c1'', sysdate from dual where not exists (select 1 from t1 where f1 = :p1 and f3 = to_date(:p2, ''DD-MON-YYYY hh24:mi:ss''))';
--dbms_output.put_line(v_query_str);
open v_cursor for v_query_str using 1, '02-AUG-2012 07:43:34';
loop
fetch v_cursor into v_f1, v_f2, v_f3;
exit when v_cursor%notfound;
dbms_output.put_line(v_f1 || ' ' || v_f2 || '' || v_f3);
end loop;
dbms_output.put_line('rowcount ' || v_cursor%rowcount);
close v_cursor;
end;
/This link shall answer your Question. PL/SQL Dynamic SQL.
If it had been an Anonymous Block, your code would work through.
Please see demonstration below:
create or replace procedure emp_data (dep_id number, sal number, emp_id number)
is
l_cnt number;
begin
select count(*)
into l_cnt
from hr.employees
where department_id = dep_id
and salary >= sal
and employee_id > emp_id;
dbms_output.put_line('Count :: ' || l_cnt);
end;
declare
l_cnt number;
begin
execute immediate 'begin emp_data(:1, :2, :2); end;' using 20, 100;
end;
anonymous block completed
Count :: 2
--Trying the Similar example as in your OP.
--Execute the same Select statement as in emp_Data with Bind Variables;
declare
l_cnt number;
begin
--execute immediate 'begin emp_data(:1, :2, :2); end;' using 20, 100;
execute immediate 'select count(*)
from hr.employees
where department_id = :1
and salary >= :2
and employee_id > :2' into l_cnt using 20, 100;
dbms_output.put_line('Count :: ' || l_cnt);
end;
Results in error :- ORA-01008: not all variables bound -
Hi
I wanted to take count of ref cursors return records.
I have added OUT parameter for procedure and i m returning records from this OUT parameter,
so i wanted to check count of record before returning it from procedure.
please do the needful.also
there is no way way to find out how many records at all will be retrieved in a cursor BEFORE you fetch the very last row from it. Cursor_name%rowcount gives the number of rows selected so far and that count increments every time you fetch.
You use %rowcount only with implicit cursors that do insert/update/delete. -
Odd error while opening a ref cursor
Hi.
I have a procedure in a package that has both in and out parameters. One of those out parameters is a ref cursor. The procedure creates a dynamic query and then executes it, then it opens the cursor:
PROCEDURE PROC(
A IN VARCHAR2,
B IN VARCHAR2,
C OUT TYPES.cursorType; --(TYPES is a package whose only use is to declare a cursor type)
) IS
--DECLARATIONS
OPEN C FOR 'SELECT A, B, C, D...';
END;
When I execute the package in an anonymous block it throws the error:
ORA-00938: not enough arguments for function, just in the line where the cursor is being opened.
Any ideas?is everything defined correctly?
create or replace package types as
type cursorType is ref cursor;
end types;
SQL> set serveroutput on
SQL> declare
2
3 ref_C types.cursorType;
4
5 v_a varchar2(1);
6 v_b varchar2(1);
7 v_c varchar2(1);
8 v_d varchar2(1);
9
10 procedure Proc (a in varchar2
11 ,b in varchar2
12 ,C out types.cursorType) as
13
14 begin
15 open C for 'select :1, :2, ''c'', ''d'' from dual' using a, b;
16 end Proc;
17 begin
18
19
20 Proc('a', 'b', ref_C);
21
22 fetch ref_C into v_a, v_b, v_c, v_d;
23 if (ref_C%found) then
24 dbms_output.put_line(v_a);
25 dbms_output.put_line(v_b);
26 dbms_output.put_line(v_c);
27 dbms_output.put_line(v_d);
28 end if;
29
30
31 end;
32 /
a
b
c
dP;
Edited by: bluefrog on Feb 18, 2010 6:07 PM -
The query below will return values in the form of
bu seq eligible
22 2345 Y
22 2345 N
22 1288 N
22 1458 Y
22 1458 N
22 1234 Y
22 1333 N
What I am trying to accomplish is to loop through the records returned.
for each seq if there is a 'N' in the eligible column return no record for that seq
eg seq 2345 has 'Y' and 'N' thus no record should be returned.
seq 1234 has only a 'Y' then return the record
seq 1333 has 'N' so return no record.
How would I accomplish this with a ref Cursor and pass the values to the front end application.
Procedure InvalidNOs(io_CURSOR OUT T_CURSOR)
IS
v_CURSOR T_CURSOR;
BEGIN
OPEN v_CURSOR FOR
' select bu, seq, eligible ' ||
' from (select bu, seq, po, tunit, tdollar,eligible,max(eligible) over () re ' ||
' from (select bu, seq, po, tunit, tdollar,eligible ' ||
' from ( ' ||
' select bu, seq, po, tunit, tdollar, eligible, sum(qty) qty, sum(price*qty) dollars ' ||
' from ' ||
' ( select /*+ use_nl(t,h,d,s) */ ' ||
' h.business_unit_id bu, h.edi_sequence_id seq, d.edi_det_sequ_id dseq, ' ||
' s.edi_size_sequ_id sseq, h.po_number po, h.total_unit tUnit, h.total_amount tDollar, ' ||
' s.quantity qty, s.unit_price price,' ||
' (select (case when count(*) = 0 then ''Y'' else ''N'' end) ' ||
' from sewn.NT_edii_po_det_error ' ||
' where edi_det_sequ_id = d.edi_det_sequ_id ' ||
' ) eligible ' ||
' from sewn.nt_edii_purchase_size s, sewn.nt_edii_purchase_det d, ' ||
' sewn.nt_edii_purchase_hdr h, sewn.nt_edii_param_temp t ' ||
' where h.business_unit_id = t.business_unit_id ' ||
' and h.edi_sequence_id = t.edi_sequence_id ' ||
' and h.business_unit_id = d.business_unit_id ' ||
' and h.edi_sequence_id = d.edi_sequence_id ' ||
' and d.business_unit_id = s.business_unit_id ' ||
' and d.edi_sequence_id = s.edi_sequence_id ' ||
' and d.edi_det_sequ_id = s.edi_det_sequ_id ' ||
' ) group by bu, seq, po, tunit, tdollar, eligible ' ||
' ) ' ||
' group by bu, seq, po, tunit, tdollar, eligible)) ';
io_CURSOR := v_CURSOR;
END InvalidNOs;One remark why you should not use the assignment between ref cursor
variables.
(I remembered I saw already such thing in your code).
Technically you can do it but it does not make sense and it can confuse your results.
In the opposite to usual variables, when your assignment copies value
from one variable to another, cursor variables are pointers to the memory.
Because of this when you assign one cursor variable to another you just
duplicate memory pointers. You don't copy result sets. What you do for
one pointer is that you do for another and vice versa. They are the same.
I think the below example is self-explained:
SQL> /* usual variables */
SQL> declare
2 a number;
3 b number;
4 begin
5 a := 1;
6 b := a;
7 a := a + 1;
8 dbms_output.put_line('a = ' || a);
9 dbms_output.put_line('b = ' || b);
10 end;
11 /
a = 2
b = 1
PL/SQL procedure successfully completed.
SQL> /* cursor variables */
SQL> declare
2 a sys_refcursor;
3 b sys_refcursor;
4 begin
5 open a for select empno from emp;
6 b := a;
7 close b;
8
9 /* next action is impossible - cursor already closed */
10 /* a and b are the same ! */
11 close a;
12 end;
13 /
declare
ERROR at line 1:
ORA-01001: invalid cursor
ORA-06512: at line 11
SQL> declare
2 a sys_refcursor;
3 b sys_refcursor;
4 vempno emp.empno%type;
5
6 begin
7 open a for select empno from emp;
8 b := a;
9
10 /* Fetch first row from a */
11 fetch a into vempno;
12 dbms_output.put_line(vempno);
13
14 /* Fetch from b gives us SECOND row, not first -
15 a and b are the SAME */
16
17 fetch b into vempno;
18 dbms_output.put_line(vempno);
19
20
21 end;
22 /
7369
7499
PL/SQL procedure successfully completed.Rgds.
Message was edited by:
dnikiforov -
ORA-01008 with ref cursor and dynamic sql
When I run the follwing procedure:
variable x refcursor
set autoprint on
begin
Crosstab.pivot(p_max_cols => 4,
p_query => 'select job, count(*) cnt, deptno, row_number() over (partition by job order by deptno) rn from scott.emp group by job, deptno',
p_anchor => Crosstab.array('JOB'),
p_pivot => Crosstab.array('DEPTNO', 'CNT'),
p_cursor => :x );
end;I get the following error:
^----------------
Statement Ignored
set autoprint on
begin
adsmgr.Crosstab.pivot(p_max_cols => 4,
p_query => 'select job, count(*) cnt, deptno, row_number() over (partition by
p_anchor => adsmgr.Crosstab.array('JOB'),
p_pivot => adsmgr.Crosstab.array('DEPTNO', 'CNT'),
p_cursor => :x );
end;
ORA-01008: not all variables bound
I am running this on a stored procedure as follows:
create or replace package Crosstab
as
type refcursor is ref cursor;
type array is table of varchar2(30);
procedure pivot( p_max_cols in number default null,
p_max_cols_query in varchar2 default null,
p_query in varchar2,
p_anchor in array,
p_pivot in array,
p_cursor in out refcursor );
end;
create or replace package body Crosstab
as
procedure pivot( p_max_cols in number default null,
p_max_cols_query in varchar2 default null,
p_query in varchar2,
p_anchor in array,
p_pivot in array,
p_cursor in out refcursor )
as
l_max_cols number;
l_query long;
l_cnames array;
begin
-- figure out the number of columns we must support
-- we either KNOW this or we have a query that can tell us
if ( p_max_cols is not null )
then
l_max_cols := p_max_cols;
elsif ( p_max_cols_query is not null )
then
execute immediate p_max_cols_query into l_max_cols;
else
RAISE_APPLICATION_ERROR(-20001, 'Cannot figure out max cols');
end if;
-- Now, construct the query that can answer the question for us...
-- start with the C1, C2, ... CX columns:
l_query := 'select ';
for i in 1 .. p_anchor.count
loop
l_query := l_query || p_anchor(i) || ',';
end loop;
-- Now add in the C{x+1}... CN columns to be pivoted:
-- the format is "max(decode(rn,1,C{X+1},null)) cx+1_1"
for i in 1 .. l_max_cols
loop
for j in 1 .. p_pivot.count
loop
l_query := l_query ||
'max(decode(rn,'||i||','||
p_pivot(j)||',null)) ' ||
p_pivot(j) || '_' || i || ',';
end loop;
end loop;
-- Now just add in the original query
l_query := rtrim(l_query,',')||' from ( '||p_query||') group by ';
-- and then the group by columns...
for i in 1 .. p_anchor.count
loop
l_query := l_query || p_anchor(i) || ',';
end loop;
l_query := rtrim(l_query,',');
-- and return it
execute immediate 'alter session set cursor_sharing=force';
open p_cursor for l_query;
execute immediate 'alter session set cursor_sharing=exact';
end;
end;
/I can see from the error message that it is ignoring the x declaration, I assume it is because it does not recognise the type refcursor from the procedure.
How do I get it to recognise this?
Thank you in advanceThank you for your help
This is the version of Oracle I am running, so this may have something to do with that.
Oracle9i Enterprise Edition Release 9.2.0.8.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.8.0 - Production
I found this on Ask Tom (http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:3027089372477)
Hello, Tom.
I have one bind variable in a dynamic SQL expression.
When I open cursor for this sql, it gets me to ora-01008.
Please consider:
Connected to:
Oracle8i Enterprise Edition Release 8.1.7.4.1 - Production
JServer Release 8.1.7.4.1 - Production
SQL> declare
2 type cur is ref cursor;
3 res cur;
4 begin
5 open res for
6 'select * from (select * from dual where :p = 1) connect by 1 = 1'
7 using 1;
8 end;
9 /
declare
ERROR at line 1:
ORA-01008: not all variables bound
ORA-06512: at line 5
SQL> declare
2 type cur is ref cursor;
3 res cur;
4 begin
5 open res for
6 'select * from (select * from dual where :p = 1) connect by 1 = 1'
7 using 1, 2;
8 end;
9 /
PL/SQL procedure successfully completed.
And if I run the same thing on 10g -- all goes conversely. The first part runs ok, and the second
part reports "ORA-01006: bind variable does not exist" (as it should be, I think). Remember, there
is ONE bind variable in sql, not two. Is it a bug in 8i?
What should we do to avoid this error running the same plsql program code on different Oracle
versions?
P.S. Thank you for your invaluable work on this site.
Followup June 9, 2005 - 6pm US/Eastern:
what is the purpose of this query really?
but it would appear to be a bug in 8i (since it should need but one). You will have to work that
via support. I changed the type to tarray to see if the reserved word was causing a problem.
variable v_refcursor refcursor;
set autoprint on;
begin
crosstab.pivot (p_max_cols => 4,
p_query =>
'SELECT job, COUNT (*) cnt, deptno, ' ||
' ROW_NUMBER () OVER ( ' ||
' PARTITION BY job ' ||
' ORDER BY deptno) rn ' ||
'FROM emp ' ||
'GROUP BY job, deptno',
p_anchor => crosstab.tarray ('JOB'),
p_pivot => crosstab.tarray ('DEPTNO', 'CNT'),
p_cursor => :v_refcursor);
end;
/Was going to use this package as a stored procedure in forms but I not sure it's going to work now.
Maybe you are looking for
-
Cannot view streamed photos in web browser
I have set up a photo stream from my iPhone and have set it up as a "Public Website" so that friends and family that do not have Apple devices can view the photos. Everything was working fine for about two months, but in the past couple of days peopl
-
Tiger install not recognizing hard drive
G3 desktop/400MHz/512 MB RAM/20 GB Western Digital EIDE HD/ OS X 10.4 retail install DVD. My friend gave me the aforementioned Mac, minus the HD which he kept, but with the 10.4 install disk. The computer was working fine before. I had a blank NTFS-f
-
Can't select file names in list view
System: Mac Pro 2.93 Quad-Core, 6GB RAM, 10.6.2 I updated from 10.6.1 to 10.6.2 using software update AND from 10.6 to 10.6.2 doing a clean install. Both times I had problems with the finder: first, the icons in the sidebar turned into "page" icons (
-
Are non-purchased songs on iTunes backed up on iCloud?
I have a lot of music that I transferred to iTunes from friends CDs or CDs that I didn't want to take up space in my house. I'm thinking of getting a new macbook pro and I would like to know if all of this music will be lost if and when I do so? Onli
-
Windows 2008 R2 Oracle 11gR2 Got errors that I have never seen before. H:\>impdp blah@blah11g schemas=blah directory=data_pump_dir dumpfile=blah.dmp logfile=blah.log Import: Release 10.1.0.4.2 - Production on Thursday, 16 September, 2010 13:36 Copyri