Regarding REF cursor
Hi all,
Well, I am trying to find out why the REF cursor is used in the documentation .. But, I couldnt find a satisfying answer .. Can anybody pass on any link or can anyone give me the answers for the below queries
1)what is REF cursor
2)what's the use
3)where to use the REF cursor
4)why to use the REF cursor ..
Regards
Something more informative than this ?
http://scarlet.ucc.nau.edu/oracle10.2.0/appdev.102/b14261/sqloperations.htm#sthref1392
Similar Messages
-
Regarding the Ref Cursor functional;ity
HI,
I am using ref cursor to return Result Set to .Net.
I am in doubt that , Is it requires multiple server trips to fill the DataSet at front end.
As my assumption it will return the address of the work area provided in Oracle server. After that for each row it make a server trip .
Is my assumption is right ?
Can any one tell me the functionality behind returning a Ref Cursor .
Thank you....This is (or ought to be) configurable on the .NET side. There will be a server round-trip to fetch every N records where N is a setting on the client. I'm not particularly experienced with .NET, so I'm not sure where this setting is set, but the folks over in the .NET forum might.
Justin
Distributed Database Consulting, Inc.
http://www.ddbcinc.com/askDDBC -
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 -
Performance problem with sproc and out parameter ref cursor
Hi
I have sproc with Ref Cursor as an OUT parameter.
It is extremely slow looping over the ResultSet (does it record by record in the fetch).
so I have added setPrefetchRowCount(100) and setPrefetchMemorySize(6000)
pseudo code below:
string sqlSmt = "BEGIN get_tick_data( :v1 , :v2); END;";
Statement* s = connection->createStatement(sqlStmt);
s->setString(1, i1);
// cursor ( f1 , f2, f3 , f4 , i1 ) f for float type and i for interger value.
// 5 columns as part of cursor with 4 columns are having float value and
// 1 column is having int value assuming 40 bytes for one rec.
s->setPrefetchRowCount (100);
s->PrefetchMemorySize(6000);
s->registerOutParam(2,OCCICURSOR);
s->execute();
ResultSet* rs = s->getCursor(2);
while (rs->next()) {
// do, and do v slowly!
}Hi,
I have the same problem. It seems, when retrieving cursor, that "setPrefetchRowCount" is not taking into account by OCCI. If you have a SQL statement like "SELECT STR1, STR2, STR3 FROM TABLE1" that works fine but if your SQL statement is a call to a stored procedure returning a cursor each row fetching need a roudtrip.
To avoid this problem you need to use the method "setDataBuffer" from the object "ResultSet" for each column of your cursor. It's easy to use with INT type and STRING type, a lit bit more complex with DATE type. But until now, I'm not able to do the same thing with REF type.
Below a sample with STRING TYPE (It's assuming that the cursor return only one column of STRING type):
try
l_Statement = m_Connection->createStatement("BEGIN :1 := PACKAGE1.GetCursor1(:2); END;");
l_Statement->registerOutParam(1, oracle::occi::OCCINUMBER, sizeof(l_CodeErreur));
l_Statement->registerOutParam(2, oracle::occi::OCCICURSOR);
l_Statement->executeQuery();
l_CodeErreur = l_Statement->getNumber(1);
if ((int) l_CodeErreur == 0)
char l_ArrayName[5][256];
ub2 l_ArrayNameSize[5];
l_ResultSet = l_Statement->getCursor(2);
l_ResultSet->setDataBuffer(1, l_ArrayName, OCCI_SQLT_STR, sizeof(l_ArrayName[0]), l_ArrayNameSize, NULL, NULL);
while (l_ResultSet->next(5))
for (int i = 0; i < l_ResultSet->getNumArrayRows(); i++)
l_Name = CString(l_ArrayName);
l_Statement->closeResultSet(l_ResultSet);
m_Connection->terminateStatement(l_Statement);
catch (SQLException &p_SQLException)
I hope that sample help you.
Regards -
How to descrbe a ref cursor from a PL/SQL prog?
Hi,
here is a sample of the my problem
let suppose a table country :
create table country(country_code VARCHAR2(3), country_name VARCHAR2(50));
then a package containing different procedures among them, this one :
PL/SQL prog
create or replace package country_pkg as
type rec1 is ref cursor return country%rowtype;
Procedure get_all_countries(rec in out rec1);
blablabla ...
END country_pkg;
in the package body, i have the following code :
create or replace package body country_pkg as
procedure get_all_countries(rec IN OUT rec1) is
begin
if not rec%open then
open rec for select * from country order by country_name;
end if;
exception
when NO_DATA_FOUND then
close rec;
end get_all_countries;
blablabla....
end;
Then in the C program
(*proc)->request->command = "begin get_all_countries(:rec); end;"
checkerr(&connect, \
OCIStmtPrepare(connect->stmthp,\
connect->errhp,\
(*proc)->request->command,\
strlen((*proc)->request->command),\
OCI_NTV_SYNTAX, OCI_DEFAULT));
checkerr(&connect, \
OCIHandleAlloc((dvoid*)(connect->envhp),\
(dvoid**) &((*proc)->stmthp), OCI_HTYPE_STMT,
(size_t) 0,\
(dvoid**) 0));
bndhp = (OCIBind**) g_malloc0((*proc)->argnum*sizeof(OCIBind*));
for(i = 0; i < (*proc)->argnum; i++)
switch ((*proc)->desc->type)
case 102:
checkerr(&connect,
OCIBindByPos(connect->stmthp, &bndhp[j],
connect->errhp,
i+1,&((*proc)->stmthp), (sb4) 0,
SQLT_REF, (dvoid*) 0, (ub2*) 0, (ub2*) 0,
(ub4) 0,
(ub4*) 0, (ub4) OCI_DEFAULT));
default:
some code ....
checkerr(&connect, \
OCIStmtExecute(connect->svchp, connect->stmthp,\
connect->errhp, 1, (ub4) 0, (OCISnapshot*) 0,\
(OCISnapshot*) 0, OCI_DEFAULT));
parm_status = OCIParamGet(connect->stmthp, OCI_HTYPE_STMT,connect->errhp, (dvoid**)&arg, 0);
while(parm_status == OCI_SUCCESS)
OCIAttrGet((dvoid*) arg, OCI_DTYPE_PARAM,
(dvoid*)type,0, (ub4) OCI_ATTR_NUM_PARAMS,
connect->errhp);
counter++;
parm_status = OCIParamGet(connect->stmthp,
OCII_HTYPE_STMT,connect->errhp,
(dvoid**)&arg, counter);
This piece of code doesn't work as 'arg' is always NULL
and OCIParamGet retruns OCI_SUCCESS.
I'm certainly missing something but I don't see what. Could anyone help me to get that piece of code working?
regards,
Raphaelunfortunately, not yet!
I dropped the matter for now, I'll come back on it later.
On your side, let me know if you find something interesting on that topic by posting a message here. -
Ora-01001 in procedures with ref cursor parameter after upgrade to 11.1.0.7
Hi,
after upgrading from 11.1.0.6.0 to 11.1.0.7.0, I get ora-01001 in procedure calls which have a ref cursor as an out parameter.
Even a new 11.1.0.7 instance throws this error. My OS is Linux SLES10SP2.
Please see atched sample code:
CREATE OR REPLACE PACKAGE test1_pck
IS
PROCEDURE run1; -- OK on 11.1.0.6; fails on 11.1.0.7
PROCEDURE run2; -- OK on 11.1.0.6; OK on 11.1.0.7
END test1_pck;
CREATE OR REPLACE PACKAGE BODY test1_pck
IS
TYPE t_rec IS RECORD(col dual.dummy%TYPE);
TYPE t_cur IS REF CURSOR RETURN t_rec;
PROCEDURE foo1(p_cur OUT t_cur)
IS
v_sql VARCHAR2(255) := 'BEGIN OPEN :1 FOR SELECT dummy FROM dual; END;';
BEGIN
EXECUTE IMMEDIATE v_sql USING p_cur;
END foo1;
PROCEDURE foo2
IS
v_sql VARCHAR2(255) := 'BEGIN OPEN :1 FOR SELECT dummy FROM dual; END;';
v_cur t_cur;
v_rec t_rec;
BEGIN
EXECUTE IMMEDIATE v_sql USING v_cur;
LOOP
FETCH v_cur INTO v_rec;
EXIT WHEN v_cur%NOTFOUND;
CASE v_rec.col
WHEN 'X' THEN dbms_output.put_line('success');
ELSE dbms_output.put_line('error');
END CASE;
END LOOP;
END foo2;
PROCEDURE run1
IS
v_cur t_cur;
v_rec t_rec;
BEGIN
foo1(v_cur);
LOOP
FETCH v_cur INTO v_rec;
EXIT WHEN v_cur%NOTFOUND;
CASE v_rec.col
WHEN 'X' THEN dbms_output.put_line('success');
ELSE dbms_output.put_line('error');
END CASE;
END LOOP;
END run1;
PROCEDURE run2
IS
BEGIN
foo2;
END run2;
END test1_pck;
Thanks for any hints.
Regards FrankHi Max,
the referenced thread discusses a .Net problem. A lot of layers are involved their. My problem is a very basic problem. You get this error even if you run the test in a sql session on the server.
It would be a great help for me
a) if someone could test this package on a 11.1.0.7 database
b) if someone could test this package on a 11.2 database (is it fixed in Release2?)
c) if someone could give me hints how I could modify the procedure to make it usable for 11.1.0.7
(I already tried a lot e.g. EXECUTE IMMEDIATE v_sql USING OUT p_cur;
Thank you
Frank -
Unable to use ref cursor as a input parameter at the time of inserting reco
Hi
i am unable to use ref cursor when inserting the data to oracle 11g from visual studio 2008. please help me as early as possible my code is bellows
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Web.Configuration;
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;
public partial class App_frmTest : System.Web.UI.Page
protected void Page_Load(object sender, EventArgs e)
protected void btnClick_Click(object sender, EventArgs e)
OracleCommand cmd=new OracleCommand();
Data objdata = new Data();
int i = 0;
string constr = "Data Source=Cwc;User Id=scott; Password=tiger;";// enlist=false; pooling=false;
OracleConnection con = new OracleConnection(constr);
/*Connection Open*/
con.Open();
cmd.Connection = con;
/*Connection Open End*/
/*Select Through Ref Cursor*/
cmd.CommandText = "scott.TEST_USER.getUSER";
cmd.CommandType = CommandType.StoredProcedure;
OracleParameter p_rc = cmd.Parameters.Add("p_rc", OracleDbType.RefCursor, DBNull.Value, ParameterDirection.Output);
OracleParameter p_rc1;
if (TextBox1.Text == "")
p_rc1 = cmd.Parameters.Add("p_rc", OracleDbType.Int16, DBNull.Value, ParameterDirection.Input);
else
p_rc1 = cmd.Parameters.Add("p_rc", OracleDbType.Int16, Convert.ToInt16(TextBox1.Text), ParameterDirection.Input);
// OracleParameter p_rc1 = cmd.Parameters.Add("p_rc", OracleDbType.Int16, 2, ParameterDirection.Input);
OracleDataReader reader = cmd.ExecuteReader();
DataSet ds = new DataSet();
DataTable dt1 = new DataTable();
dt1.Load(reader);
ds.Tables.Add(dt1);
GridView1.DataSource = ds;
GridView1.DataBind();
cmd.Parameters.Clear();
con.Close();
con.Dispose();
OracleCommand cmd1 = new OracleCommand();
OracleConnection con1 = new OracleConnection(constr);
con1.Open();
cmd1.Connection = con1;
cmd1.CommandText = "scott.TEST_USER.ADDUSER";
cmd1.CommandType = CommandType.StoredProcedure;
OracleParameter P_ADDUSER = cmd1.Parameters.Add("P_ADDUSER", OracleDbType.RefCursor, DBNull.Value, ParameterDirection.Input);
cmd1.ExecuteNonQuery(); // i am getting error when executing this line
Server Error in '/CWC' Application.
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Source Error:
Line 77: OracleParameter P_ADDUSER = cmd1.Parameters.Add("P_ADDUSER", OracleDbType.RefCursor, DBNull.Value, ParameterDirection.Input);
Line 78: //OracleParameter P_MSG = cmd.Parameters.Add("P_MSG", OracleDbType.Varchar2, DBNull.Value, ParameterDirection.Output);
Line 79: cmd1.ExecuteNonQuery();
Line 80:
Line 81: DataTable dt = new DataTable();
Source File: d:\CWC\App\frmTest.aspx.cs Line: 79
Stack Trace:
[AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.]
Oracle.DataAccess.Client.OpsSql.ExecuteNonQuery(IntPtr opsConCtx, IntPtr& opsErrCtx, IntPtr& opsSqlCtx, IntPtr& opsDacCtx, IntPtr opsSubscrCtx, Int32& isSubscrRegistered, Int32 bchgNTFNExcludeRowidInfo, Int32 bQueryBasedNTFNRegistration, Int64& query_id, OpoSqlValCtx*& pOpoSqlValCtx, String pCommandText, IntPtr& pUTF8CommandText, IntPtr[] pOpoPrmValCtx, String[] ppOpoPrmRefCtx, OpoMetValCtx*& pOpoMetValCtx, Int32 prmCnt, Int32 bFromPool) +0
Oracle.DataAccess.Client.OracleCommand.ExecuteNonQuery() +4731
App_frmTest.btnClick_Click(Object sender, EventArgs e) in d:\CWC\App\frmTest.aspx.cs:79
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +111
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +110
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1565Hi;
Its better to ask it at visual studio forum site:http://social.msdn.microsoft.com/Forums/en-US/category/visualstudio
Regard
Helios -
Ref Cursor Problem in Oracle Forms 6i
Hi all.
In Oracle Forms 6i, can not I do this?
DECLARE
TYPE CUR_REF IS REF CURSOR;
CUR_PRODUCTS CUR_REF;
VAR_QUERY VARCHAR2(3000) := 'SELECT something FROM table';
BEGIN
OPEN CUR_PRODUCTS FOR VAR_QUERY;
END;
It generates error on opening that it expects a SELECT statement.
How can I open a dynamic ref cursor in Oracle Forms 6i??? The same thing works fine in PL/SQL.
Regards,
Zaaf
Thanks in advance.It could be like this:
PROCEDURE dynamic_cursor ( PC$Clause IN Varchar2 )
IS
cursor_number EXEC_SQL.CursType;
-- Variables for the data to be returned into
LC$ACTYPE Number;
-- Control variables
LN$count Number;
LC$sql_order Varchar2(256);
BEGIN
-- Open the cursor --
cursor_number := Exec_SQL.Open_cursor;
-- build the complete SQL order --
LC$sql_order := PC$clause ;
-- Parse the SQL order --
EXEC_SQL.PARSE(cursor_number, LC$sql_order);
-- Define the columns for the data to be returned --
EXEC_SQL.DEFINE_COLUMN(cursor_number,1,LC$ACTYPE);
-- Execute the Cursor --
LN$count := EXEC_SQL.EXECUTE(cursor_number);
-- Loop and fetch each row from the result set --
While EXEC_SQL.FETCH_ROWS(cursor_number) > 0 Loop
EXEC_SQL.COLUMN_VALUE(cursor_number,1,LC$ACTYPE);
begin
select chqfac, pasfac, indbcr ,
staxfl, excise, incchg, cat001 , trntyp , subtyp
into s_chkbok, s_pasbok, s_intber,
s_staxfl, s_excise, s_incchg, s_cat001 , ss_trntyp , ss_subtyp
from stfeacty
where brancd = s_brancd
and actype = LC$ACTYPE;
s_actype := LC$ACTYPE ;
exception
when no_data_found then
NULL;
when too_many_rows then
NULL;
end;
End Loop ;
-- Close the cursors
EXEC_SQL.CLOSE_CURSOR(cursor_number);
EXCEPTION
When EXEC_SQL.INVALID_CONNECTION Then
message('Unexpected Invalid Connection error from EXEC_SQL');
When EXEC_SQL.PACKAGE_ERROR Then
message('Unexpected error from EXEC_SQL: '||to_char(EXEC_SQL.LAST_ERROR_CODE)|| EXEC_SQL.LAST_ERROR_MESG);
If EXEC_SQL.IS_OPEN(cursor_number) Then
EXEC_SQL.CLOSE_CURSOR(cursor_number);
message('Exception - Cleaned up Cursor');
End if;
END; That you could call with the following:
dynamic_cursor('SELECT ac_type FROM SYSADM.SAVINGS');But, if the query is as simple with only the table name change, you could aslo use a simpliest solution based on a record group.
Francois -
How to print/store in file the ref cursor in pl/sql block ?
How to print/store in file the ref cursor in pl/sql block ?.
How to print/store in file the ref cursor in pl/sql block ?.You question is quite confusing?
So, i'm providing link in this manner.
For RefCursor,
http://www.oracle-base.com/articles/misc/UsingRefCursorsToReturnRecordsets.php
http://www.oracle.com/technology/oramag/code/tips2003/042003.html
For UTL_FILE,
http://www.morganslibrary.org/reference/utl_file.html
Regards.
Satyaki De.
Updated with new morgan library link.
Edited by: Satyaki_De on Feb 24, 2010 9:03 PM -
Dynamic queries in report builder 6i ( ref cursor query )
Hi everyone,
My requirement is that I want to create a report where the query is dynamic. The dynamic part will be known at runtime as it is being passed via a parameter. My query looks like this :
select * from emp where sal :p1 :p2
Possible values for :p1 are - '>', '<', '>=', '<=', '=', '!='
Possible values for :p2 are - any value entered by the user
I tried creating a query in report builder based on a ref cursor. But it does not allow me to create the query for the ref cursor dynamically. That means I have to hardcode the query in the program.
I tried using place holder columns without success.
Can someone please help me ?
Regards,
AlHi,
You can use lexical paramters in the sql query
x - char - parameter
select * from emp &x
you need to pass the value for x in the parameter as
'where sal < 1234'.
Note : Lexical variable should be of char datatype.
This is an alternative to the ref cursors.
This works. Hope this is clear. -
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} -
Ref cursors in Database adapter
Hi,
Is the database adapter capable of handling ref cursors as the datatype of the output parameters of a pl/sql procedure?
For instance if I have the following in my package-spec:
TYPE SomeRecordType IS RECORD
( record_pk mut_table.record_pk%TYPE
, person_nr person_table.person_nr%TYPE
, field_1 mut_table.field_1%type
, field_2 mut_table.field_2%type
, field_3 mut_table.field_3%type
TYPE SomeCursorType IS REF CURSOR RETURN SomeRecordType;
PROCEDURE read_records
( cursor_out OUT SomeCursorType
, exception_code OUT number
, exception_message OUT varchar2
Can the database adapter call the read_records procedure?
I've never seen this in any doc. I know it can't handle record types (that is in 10.1.2 it couldn't as far as I know). So I figure that the above is not possible.
Thanks in advance.
Regards,
MartienWe have successfully used a sys_refcursor OUT parameter for a database procedure call and which is used by a DBAdapter to return a single dataset.
At the time I remember attempting to use a strongly typed ref cursor as the parameter. I think this is what you are attempting to do. I rejected this approach at the time as I was not able to do this. It was, in our case, as simple as using the system defined ref cursor type (i.e. weakly typed).
The handling of the returned dataset was not immediately obvious, but can be handled by as fairly simple XSL transformation to a locally defined variable of the requisite xml structure. I won't describe in detail how to do it as it is specific to our process. Suffice to say the transformation loops over all result rows assign via a test to the correct result field in our local variable.
e.g.
<xsl:template match="/">
<ns1:BatchRequest004>
<xsl:for-each select="/db:OutputParameters/db:P_SCHSHP_REF_CUR/db:Row">
<ns1:statusRqst>
<xsl:if test='db:Column/@name = "ID"'>
<xsl:attribute name="id">
<xsl:value-of select="db:Column[1.0]"/>
</xsl:attribute>
</xsl:if>
</ns1:statusRqst>
</xsl:for-each>
</ns1:BatchRequest004>
HTH and that I haven't misidentified your problem. -
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. -
XSQL ERROR with bind-params in ref-cursor-function
Hi Steve
I always get the error
ORA-01006 bind variable does not exist
when using a bind variable in a <xsql:ref-cursor-function> action element.
when I replace the bind variable with a @ - parameter substitution, all works fine.
My configuration:
XSQL 1.0.4.1 on Win200Pro ,Apache + Jserv + DB from ORA 8.1.7 installation
My Source
<xsql:ref-cursor-function
dbconn="ekat"
eblike="%"
list="a0"
bind-params="eblike"
include-schema="no"
null-indicator="no"
id-attribute=""
fetch-size="500"
>
{@dbconn}o.ekatkategcv.open_cv_ebh ('{@list}', :1)
</xsql:ref-cursor-function>
( dbconn selects my schema, not changed often, which contains package ekatkategcv with
function open_cv_ebh returning a cursor)
Any fix would be appreciated to avoid reparsing on each call.
BTW, is it right, that a ref-cursor funtion is reparsed whenever the content of
a parameter used with @ changes?
Best regards
H.Buschmann ([email protected])
nullI have tried it using ? instead of :1, this method works fine.
I haven't tried the name method (:bindvar) yet.
Until now, I only used xsl:query and xsql:ref-cursor-function, so I didn't check
the other action handlers with bind variables like :1
null -
Create view With Ref cursor data
Hi friends,
I want to create view as follows.
Example:
Create or replace v_name
select job,sal, <funcation>
from emp;
Note:- Function not having out parameter.
Function returning ref cursor values datatype.
Requirement:-
I want to create view even function returing ref cursor datatype.
Please advise how to create view.
Regards,
Kishoreuser7284612 wrote:
Hi friends,
I want to create view as follows.
Example:
Create or replace v_name
select job,sal, <funcation>
from emp;
Note:- Function not having out parameter.
Function returning ref cursor values datatype.
Requirement:-
I want to create view even function returing ref cursor datatype.
Please advise how to create view.You perhaps are misunderstanding what a ref cursor is. It does not contain data like a table, so cannot be treated as one.
Take a read of this:
PL/SQL 101 : Understanding Ref Cursors
Maybe you are looking for
-
Need help installing the software. Keep getting the error message above
-
Sync does not work- multiple desktop FF
Sync does not allow adding more than one DESKTOP FF in order to sync multiple desktop FF (e.g: work, home, & friends , etc..) I do not like to use an add-on.
-
Other tools/option to achieve Health check
Hi guys, I saw that there are a lot threads open regarding health check. I`m searching for an open source tool/commercial tool, manually created scripts that can check all oracle prerequisite (system information, oracle kernel parameters, packages) a
-
OS X v10.6.2 update problems
I am currently using version 10.6.2 but when I run system update I get a list of updates needed, I will proceed the update process untill my computer restarts. My issue is that im finding the mac will still be on the same version and has not updated.
-
Addressbook uses depractated certificates
I'm using X.509-ceritificates to encrypt and sign my e-mail correspondence whenever needed. So I have my own certificate together with my private key and some certificates from other users loaded into the keychain-application. In the addressbook I ca