Are ref cursors supported in APEX??
Apex version 3.2
ORacle 10G
Tony,
Please see http://apex.oracle.com/pls/apex/f?p=34598:1
This is a demo illustrating ApEx consuming a REF CURSOR for processing, and consuming the same REF CURSOR for a report.
Behind the scenes code:
-- defines the cursor type
create or replace PACKAGE emp_ref_cursor_pkg AS
TYPE emp_ref_cursor IS REF CURSOR
RETURN emp%ROWTYPE;
END emp_ref_cursor_pkg;
-- procedure returning a REF CURSOR of emp rows for specified department - pretend this is one of the original
-- poster's legacy REF CURSOR routines
create or replace PROCEDURE test_ref_cursor(
p_deptno IN NUMBER,
p_cursor OUT emp_ref_cursor_pkg.emp_ref_cursor
) IS
BEGIN
OPEN p_cursor FOR
SELECT *
FROM emp
WHERE deptno = p_deptno;
END test_ref_cursor;
-- table type to support pipelined function
create or replace package emp_pkg
is
type emp_tbl is table of emp%rowtype;
end;
-- pipelined function wrapping the test_ref_cursor procedure, pipes rows for specified department
create or replace FUNCTION showit(p_deptno IN NUMBER)
RETURN emp_pkg.emp_tbl
PIPELINED IS
c_cursor emp_ref_cursor_pkg.emp_ref_cursor;
r_emp c_cursor%ROWTYPE;
BEGIN
test_ref_cursor(p_deptno, c_cursor);
LOOP
FETCH c_cursor
INTO r_emp;
EXIT WHEN c_cursor%NOTFOUND;
PIPE ROW (r_emp);
END LOOP;
CLOSE c_cursor;
RETURN;
END;Source of PL/SQL Region in ApEx application showing consumption of REF CURSOR:
DECLARE
c_cursor emp_ref_cursor_pkg.emp_ref_cursor;
r_emp c_cursor%ROWTYPE;
BEGIN
test_ref_cursor(10, c_cursor);
LOOP
FETCH c_cursor
INTO r_emp;
EXIT WHEN c_cursor%NOTFOUND;
-- just output emp name - but could be any sort of processing going on here
HTP.p(r_emp.ename || '<br />');
END LOOP;
CLOSE c_cursor;
END;Source of Report Region in ApEx application showing consumption of REF CURSOR via pipelined function from above:
SELECT *
FROM table(showit(10))Does that answer the question sufficiently enough for you? Again, Tony, I NEVER said that ApEx can process a REF CURSOR - I simply said that, via PL/SQL, the original poster CAN still use his/her previously defined REF CURSORS in an ApEx application.
Please try to concentrate on helping the new users get up to speed on one of the best web-database RAD tools out there and not so much on trying to one-up the people that are just trying to help.
Regards,
John
Similar Messages
-
Will REF CURSOR support for Oracle Forms 6i?
Hi,
I need to use ref cursor in my from. My cursor query should be dynamically append the "where clause". Hence I used the dynamic query with ref cursor.
But my problem is , when I compile the form it gives error for the line " OPEN emp_record FOR l_query;"
You need to use "select" statement.
Is there any solution for this in forms?
I know it supports for other PL/SQL areas.
Please help me. below is my code sample,
DECLARE
TYPE emp_refcur IS REF CURSOR;
emp_record emp_refcur;
TYPE rec_emp_data IS RECORD
emp_no VARCHAR2(40),
emp_rec rec_emp_data;
l_query VARCHAR2(4000);
BEGIN
l_query := 'SELECT empno
FROM emp ';
IF :CONTROL.ename IS NOT NULL THEN
l_query := l_query||' AND ename = '''||:CONTROL.ename||''' ';
END IF;
OPEN emp_record FOR l_query;
LOOP
FETCH emp_record INTO emp_rec;
EXIT WHEN emp_record%NOTFOUND;
dbms_output.put_line(emp_rec.emp_no);
END LOOP;
CLOSE emp_record;
END; Thanks
RajeshHi,
It's been a while since I used Forms 6i, but I remember hitting a similar problem. I don't think (and stress think!) that the PLSQL engine that comes with Forms 6i recognises ref_cursors.
The work-around I used was to move the functionality to the database and call it from forms.
Hope this helps.
Regards
Ian -
Hi,
I thought this Add-In would finally allow developers to execute package procedures that use OUTPUT REF CURSORs to return result sets.
When I try to do this, I receive an error dialog stating that system ref cursors are not supported.
Will the add-in ever support this? This is a common scenario for developers, and even Toad still cannot support it properly.
Thanks.Hi Steve,
It does work (and I will be demoing it at VSLive!) :)
Here is a quick demo you can try:
CREATE PROCEDURE "GET4CURSORS" ("MAXROWS" IN NUMBER, "EMPCUR" OUT SYS_REFCURSOR, "DEPTCUR" OUT SYS_REFCURSOR, "SALGRADECUR" OUT SYS_REFCURSOR, "BONUSCUR" OUT NOCOPY SYS_REFCURSOR) AUTHID DEFINER IS
BEGIN
open empcur for select * from emp;
open deptcur for select * from dept;
open bonuscur for select * from bonus;
open salgradecur for select * from salgrade;
END;
In the toolbox, add a datagrid and a horizontal scroll bar to a form.
Also drag and drop the "Get4Cursors" stored procedure on to the form.
The modify the code:
public Form1()
InitializeComponent();
DataSet ds = new DataSet();
oracleDataAdapter1.Fill(ds);
dataGrid1.DataSource = ds.Tables[0];
private void hScrollBar1_Scroll(object sender, System.Windows.Forms.ScrollEventArgs e)
DataSet ds = new DataSet();
oracleDataAdapter1.Fill(ds);
dataGrid1.DataSource = ds.Tables[hScrollBar1.Value]; -
Is Ref Cursor Supported in Froms 10g . If not is there any built-ins
Hi Experts,
I need to use ref cursor in my from 10g. My cursor query should be dynamically append the "where clause column name". Hence I used the dynamic query with ref cursor.
But my problem is , when I compile the form it gives error "this feature is not supported in clinet-side programs'
Is there any solution for this in forms?
Will "EXEC_SQL" package works.
Is there any alternative other than writing pl/sql refcursor....
Thanks
JanaThere are only strong ref cursors allowed in forms (they are not dynamic). you can use exec_sql in forms, or you can use a record group to do dynamic sql. Third option would be to write a database procedure where you can make use ref cursors.
regards -
Best practice: bulk update (inverse of REF CURSOR SELECT)??
To move data from the database to the application, there are REF CURSORS. However, there is no easy way to move updates/inserts from a dataset back to the database.
Could someone provide some guidelines or simple examples of how to do bulk updates (and I'm talking multiple columns for multiple rows).
I guess the way to go is arraybind. Are there any guidelines on how to handle them in .Net and PL/SQL ?You don't use the DECLARE keyword when defining stored procedures. The IS/ AS keyword is what you use instead.
CREATE OR REPLACE PROCEDURE TEST_REF
IS
TYPE REF_EMP IS REF CURSOR RETURN EMPLOYEES%ROWTYPE;
RF_EMP REF_EMP;
V_EMP EMPLOYEES%ROWTYPE;
BEGIN
DBMS_OUTPUT.ENABLE(1000000);
OPEN RF_EMP FOR
SELECT *
FROM EMPLOYEES
WHERE EMPLOYEE_ID > 100;
FETCH RF_EMP INTO V_EMP;
DBMS_OUTPUT.PUT_LINE(V_EMP.FIRST_NAME || ' ' || V_EMP.LAST_NAME);
CLOSE RF_EMP;
EXCEPTION
WHEN OTHERS
THEN DBMS_OUTPUT.PUT_LINE(SQLERRM);
END TEST_REF;will compile. It seems a bit odd that you are opening a cursor and only fetching the first row from it. I would tend to suspect that you want to loop over every row that is returned.
Justin -
Slow performance of getObject on ref cursor
Hi guys and gals,
I have a performance issue in accessing data from a ref cursor. The getObject statement is unbelievably slow. In one case, it takes as long as 3 seconds to execute a single getObject statement. I have tested this using a simple System.currentTimeMillis() before and after the statement in question.
The basic scenario is as follows :
I utilise a class that calls an Oracle PL/SQL Stored Procedure using a CallableStatement. The calling class executes on a Web Server, the Oracle ( DB Server ) resides on a different machine ( standard 3 tier stuff ). Network traffic is not a problem. A number of the output parameters registered for the CallableStatement are ref cursors. After the CallableStatement is executed, I use a getObject and cast it to a Result Set object as follows :
objResults = (ResultSet) objCallable.getObject(18);
Where the 18th param has been registered like so :
objCallable.registerOutParameter (18, OracleTypes.CURSOR);
The volume of data is certainly not excessive, typically 80 - 100 rows of data that (eventually) find their way into the drop down list on a Web Page.
About 5 other ref cursors are used and their data accessed in like manner, some of these taking between 1 & 1.5 seconds each to execute. So the whole process of retrieving from these ref cursors via getObject can take almost 10 seconds.
Has anyone experienced this kind of performance problem before, and if so, how can this be optimized ?Hey folks. Has anybody out there got to the bottom of this? I currently have a situation where my querys can take less than half a second to execute and only return a few rows (which contain only 4 columns of data) taking at most a second to run and yet take up to 30 seconds to return the ResultSet. The most annoying thing is the lack of consistancy, it seems no matter how many times you run it you get different results.
I'm using classes12.jar driver and running on both Windows (development) and Linux(production) on Oracle 8.0.5.
Any help would be hugely appreciated. -
Adding ability to use ref cursors in future versions of Apex
Currently it has been documented that Apex does not play well with ref cursors and how to get around that. Is this a feature that the Apex team is looking into for future versions? Currently we are using Oracle 11g and 1 g with Apex 4.0.2. Your reply is most appreciated.
JudJasRisHi Tony Miller,
Thank you for the prompt reply. I see your name in many of the replies in this Apex forum.
We currently have several package functions that use out ref cursors. We are looking to use the result of that ref cursor for our reports. We have found a way to get around the ref cursor by creating a table collection of the row type and return it in a specific function declaration in a pipelined function. I am fairly new to creating pkgs, functions and specifically pipeline functions as well as learning the many nooks and crannies of Apex. It would be nice to be able to call a predefined ref cursor within Apex. I was just curious if that was a feature that could be developed. Please excuse my lack of knowledge, I am learning though by asking these type of questions.
Again thank you.
JudJasRis -
Cursors are not closed when using Ref Cursor Query in a report ORA-01000
Dear Experts
Oracel database 11g,
developer suite 10.1.2.0.2,
application server 10.1.2.0.2,
Windows xp platform
For a long time, I'm hitting ORA-01000
I have a 2 group report (master and detail) using Ref Cusor query, when this report is run, I found that it opens several cursors (should be only one cursor) for the detail query although it should not, I found that the number of these cursors is equal to the number of master records.
Moreover, after the report is finished, these cursors are not closed, and they are increasing cumulatively each time I run the report, and finally the maximum number of open cursors is exceeded, and thus I get ORA-01000.
I increased the open cursors parameter for the database to an unbeleivable value 30000, but of course it will be exceeded during the session because the cursors are increasing cumulatively.
I Found that this problem is solved when using only one master Ref Cursor Query and create a breake group, the problem is solved also if we use SQL Query instead of Ref Query for the master and detail queries, but for some considerations, I should not use neither breake group nor SQL Query, I have to use REF Cursor queries.
Is this an oracle bug , and how can I overcome ?
Thanks
Edited by: Mostafa Abolaynain on May 6, 2012 9:58 AMThank you Inol for your answer, However
Ref Cursor give me felxibility to control the query, for example see the following query :
function QR_1RefCurDS return DEF_CURSORS.JOURHEAD_REFCUR is
temp_JOURHEAD DEF_CURSORS.JOURHEAD_refcur;
v_from_date DATE;
v_to_date DATE;
V_SERIAL_TYPE number;
begin
SELECT SERIAL_TYPE INTO V_SERIAL_TYPE
FROM ACC_VOUCHER_TYPES
where voucher_type='J'
and IDENT_NO=:IDENT
AND COMP_NO=TO_NUMBER(:COMPANY_NO);
IF :no_date=1 then
IF V_SERIAL_TYPE =1 THEN
open temp_JOURHEAD for select VOCH_NO, VOCH_DATE
FROM JOURHEAD
WHERE COMP_NO=TO_NUMBER(:COMPANY_NO)
AND IDENT=:IDENT
AND ((TO_NUMBER(VOCH_NO)=:FROM_NO and :FROM_NO IS NOT NULL AND :TO_NO IS NULL)
OR (TO_NUMBER(VOCH_NO) BETWEEN :FROM_NO AND :TO_NO and :FROM_NO IS NOT NULL AND :TO_NO IS NOT NULL )
OR (TO_NUMBER(VOCH_NO)<=:TO_NO and :FROM_NO IS NULL AND :TO_NO IS NOT NULL )
OR (:FROM_NO IS NULL AND :TO_NO IS NULL ))
ORDER BY TO_NUMBER(VOCH_NO);
ELSE
open temp_JOURHEAD for select VOCH_NO, VOCH_DATE
FROM JOURHEAD
WHERE COMP_NO=TO_NUMBER(:COMPANY_NO)
AND IDENT=:IDENT
AND ((VOCH_NO=:FROM_NO and :FROM_NO IS NOT NULL AND :TO_NO IS NULL)
OR (VOCH_NO BETWEEN :FROM_NO AND :TO_NO and :FROM_NO IS NOT NULL AND :TO_NO IS NOT NULL )
OR (VOCH_NO<=:TO_NO and :FROM_NO IS NULL AND :TO_NO IS NOT NULL )
OR (:FROM_NO IS NULL AND :TO_NO IS NULL ))
ORDER BY VOCH_NO;
END IF;
ELSE
v_from_date:=to_DATE(:from_date);
v_to_date:=to_DATE(:to_date);
IF V_SERIAL_TYPE =1 THEN
open temp_JOURHEAD for select VOCH_NO, VOCH_DATE
FROM JOURHEAD
WHERE COMP_NO=TO_NUMBER(:COMPANY_NO)
AND IDENT=:IDENT
AND ((voch_date between v_from_date and v_to_date and :from_date is not null and :to_date is not null)
OR (voch_date <= v_to_date and :from_date is null and :to_date is not null)
OR (voch_date = v_from_date and :from_date is not null and :to_date is null)
OR (:from_date is null and :to_date is null ))
ORDER BY VOCH_DATE,TO_NUMBER(VOCH_NO);
ELSE
open temp_JOURHEAD for select VOCH_NO, VOCH_DATE
FROM JOURHEAD
WHERE COMP_NO=TO_NUMBER(:COMPANY_NO)
AND IDENT=:IDENT
AND ((voch_date between v_from_date and v_to_date and :from_date is not null and :to_date is not null)
OR (voch_date <= v_to_date and :from_date is null and :to_date is not null)
OR (voch_date = v_from_date and :from_date is not null and :to_date is null)
OR (:from_date is null and :to_date is null ))
ORDER BY VOCH_DATE,VOCH_NO;
END IF;
END IF;
return temp_JOURHEAD;
end; -
What are the advantages to using a REF cursor
When would I want to use a REF cursor?
REF CURSORs are not cursors, they're references to cursors. This means they're dynamic. So you can completely change the query executed by the cursor.
For example you can use a REF CURSOR to select from one of a number of tables (depending on an input parameter or other sort of flag). The results are fetched into the same resultset holder and hence you only need a single lot of code to process the results.
Also you can also pass a REF CURSOR as a argument to other PL/SQL procedures and functions.
rgds, APC -
Toplink support for stored procedure with 2 OUT REF CURSOR ?
Can Toplink StoredProcedureCall be used with Oracle PLSql procedure with 2 OUT parameters. Parameter type is Ref Cursor (Oracle PLSQL resulset)
RegardsIn a TopLink StoredProcedureCall using an OUT CURSOR the cursor is assumed to map to the result set for the TopLink query.
For example if you had a stored procedure READ_ALL_EMP that returned a out cursor of EMP rows, you could use that procedure in a TopLink mapped Employee class mapped to the EMP table and use the stored procedure in a ReadAllQuery for the Employee class.
If the procedure does not return data that maps to objects, you can use a DataReadQuery to access the data. The out cursor would be returned as a Vector of DatabaseRows that contain the data from the cursor rows.
If the procedures data is complex and does not map to objects, it may be better to access the procedure directly through JDBC. -
MS Access, ODBC and SPs returning ref cursor
I have some functions and procedures in a package returning ref cursors that work fine in my C++ batch applications. I would like for the GUI to be able to call these as well.
Unfortunately, we are using Access as the front end (for now), and we have not been able to get the ref cursors to work. Is this supported? We are using Oracle 8.0.5 on Solaris, and our clients is Access 97 on NT using Intersolv's ODBC driver.
My procedure looks something like:
package jec is
procedure open_sale_cur(
p_client_id number,
sale_curvar out sale_curtype)
is begin
open sale_curtype for select ... ;
end;
end;
And the Access code looks like this:
strSql = "begin jec.open_sale_cur(27, ?); end;"
qdfTemp = conMain.CreateQueryDef("", strSql)
qdfTemp.Parameters(0).Direction = dbParamOutput
qdfTemp.Execute()
This is the error when Execute() is called:
PLS-00306: wrong number or types of arguments in call to 'OPEN_SALE_CUR'
I am not an Access programmer; I am simply passing along this information. Any help would be greatly appreciated.We tried the {call...} syntax originally, but when we use it, we get an Oracle syntax error for the statement
SELECT * FROM {call ...}
Apparently Access prepends "SELECT..." before passing the SQL text to Oracle.
This is also the case for procedures with normal scalars, such as numbers, returned as OUT values. When we use anon PL/SQL syntax and "?" placeholders with such procedures, they work. When we use {call ...} syntax or omit OUT placeholders, they do not.
<BLOCKQUOTE><font size="1" face="Verdana, Arial">quote:</font><HR>Originally posted by Justin Cave ([email protected]):
I suspect that you want to simply execute the statement
strSql = {call open_sale_cur( 27 )}
The ODBC driver will automatically figure out that there's an output parameter which is a ref cursor and return that as the result set. Note that you may want to download the latest 8.0.5 ODBC driver (8.0.5.10 I believe) if there are any problems.
Justin<HR></BLOCKQUOTE>
null -
How to give ref cursor in VB procedure call
This is my Oracle Sp
CREATE OR REPLACE PROCEDURE CRD_DMAN.infy_usp_trades_by_broker_bkr
** Procedure name: CRD_DMAN.USP_TRADES_BY_BROKER
** Author's name: Infosys
** Date written: 04/11/07
** Description: Compliance Trade by Borker
** Maintenance history:
** Date Chg req# Name Remarks
** 04/11/07 Infosys Created
p_ordercursor IN OUT infy_pkg_compliance_transact.cur_compliancetrade,
p_startdate IN VARCHAR,
p_enddate IN VARCHAR,
p_fundcode IN cs_fund_config.parent_acct_cd%TYPE,
p_clientcode IN ts_order_alloc.acct_cd%TYPE,
p_brokercode IN ts_order_alloc.exec_broker%TYPE,
p_reportname IN report_log.report_name%TYPE,
p_callingapplication IN report_log.calling_application%TYPE,
p_callinguser IN report_log.calling_user%TYPE
IS
--Declaring Local Variables
v_owner VARCHAR2 (30);
v_startdate VARCHAR2 (10);
v_enddate VARCHAR2 (10);
v_rowcount NUMBER:=0;
v_logrec base_util_pkg.crd_log_record;
exp_error EXCEPTION;
v_fundcodevalue NUMBER;
BEGIN
BEGIN
/*checking if the start date and end date are null and
assigning the sysdate accordingly*/
IF (TRIM(p_startdate) IS NULL )
THEN
v_startdate := TO_CHAR (SYSDATE, 'mm/dd/yy');
ELSE
v_startdate := p_startdate;
END IF;
IF (TRIM(p_enddate) IS NULL )
THEN
v_enddate := TO_CHAR (SYSDATE, 'mm/dd/yy');
ELSE
v_enddate := p_enddate;
END IF;
/*checking if fund code is null and assigning value accordingly*/
IF TRIM (p_fundcode) IS NULL
THEN
v_fundcodevalue := 0;
ELSE
v_fundcodevalue := 1;
END IF;
/*checking if the reportname or calling user or calling
application name*/
IF (p_reportname IS NULL OR p_callinguser IS NULL
OR p_callingapplication IS NULL)
THEN
RAISE exp_error;
END IF;
END;
--opening and fetching the data into cursor
v_logrec.start_time := SYSDATE;
BEGIN
OPEN p_ordercursor
FOR
SELECT
oa.exec_broker EXEC_BROKER_CODE,
b.bkr_name EXEC_BROKER_NAME,
oa.acct_cd CLIENT_CODE,
f.acct_name CLIENT_NAME,
CASE WHEN (Exists (SELECT 1
FROM cs_fund_broker fb
WHERE rel_typ_cd IN('P','M')
AND oa.exec_broker=fb.BKR_CD
AND oa.acct_cd =fb.acct_cd))
THEN 'Y'
ELSE 'N' END DIRECTED_BROKER,
COUNT ( distinct o.order_id) COUNT_TICKNUM,
MAX (o.trade_date) TRADE_DATE,
SUM (oa.exec_amt) BASE_COST,
SUM (oa.commision_amt) TOTAL_COMMISSION,
(SELECT ab.bkr_typ_cd FROM au_broker ab
WHERE ab.au_change_date =(SELECT TO_TIMESTAMP(MAX(ab.au_change_date))
FROM au_broker ab WHERE b.bkr_typ_cd != ab.bkr_typ_cd AND b.bkr_cd = ab.bkr_cd))
BROKER_HISTORY
FROM
ts_order o
JOIN ts_order_alloc oa ON (o.order_id = oa.order_id)
JOIN cs_broker b ON(oa.exec_broker = b.bkr_cd)
JOIN cs_fund f ON(oa.acct_cd = f.acct_cd)
WHERE
o.status = 'ACCT'
AND oa.exec_broker = CASE WHEN TRIM (p_brokercode) IS NULL
THEN oa.exec_broker
ELSE TRIM(p_brokercode) END
AND oa.acct_cd = CASE WHEN TRIM(p_clientcode) IS NULL
THEN oa.acct_cd
ELSE TRIM(p_clientcode) END
AND ((0 = v_fundcodevalue) OR EXISTS (SELECT 1 FROM crd.cs_fund_config cf
WHERE cf.parent_acct_cd =TRIM (p_fundcode)
AND oa.acct_cd = cf.child_acct_cd))
AND o.trade_date BETWEEN TO_DATE (v_startdate, 'mm/dd/yy')
AND TO_DATE (v_enddate, 'mm/dd/yy')
GROUP BY oa.exec_broker, b.bkr_name ,oa.acct_cd ,f.acct_name,oa.directed_broker,b.bkr_typ_cd,b.bkr_cd;
END;
BEGIN
SELECT
owner
INTO
v_owner
FROM
all_objects
WHERE
object_name = 'INFY_USP_TRADES_BY_BROKER_BKR';
v_logrec.end_time := SYSDATE;
v_logrec.user_code := v_owner;
v_logrec.input_param_values := 'INFY_USP_TRADES_BY_BROKER_BKR,'
|| v_startdate
|| ','
|| v_enddate
|| ','
|| p_fundcode
|| ','
|| p_clientcode
|| ','
|| p_brokercode;
v_logrec.report_name := p_reportname;
v_logrec.object_name := 'INFY_USP_TRADES_BY_BROKER_BKR';
v_logrec.rows_returned := v_rowcount;
v_logrec.calling_application := p_callingapplication;
v_logrec.calling_user := p_callinguser;
END;
BEGIN
--calling the procedure to insert values into the report_log table
COMMIT;
SET TRANSACTION READ WRITE;
base_util_pkg.crd_base_util_proc (v_logrec);
SET TRANSACTION READ ONLY;
END;
EXCEPTION
WHEN exp_error
THEN
DBMS_OUTPUT.put_line ('ERROR');
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ('ERROR OCCURED' || SQLCODE);
DBMS_OUTPUT.put_line (SQLERRM);
END infy_usp_trades_by_broker_bkr;
END OF CRD_DMAN.USP_TRADES_BY_BROKER
This is my Pakage from where i am using ref cursor
CREATE OR REPLACE PACKAGE CRD_DMAN.infy_pkg_compliance_transact
AS
** Package name : CRD.INFY_PKG_COMPLIANCE_TRANSACTIONS
** Author's name : Infosys
** Date written : 06/11/07
** Project/System : CRD
** Description : Compliance Trades By Borker Package
** Maintenance history:
** Date Chg req# Name Remarks
** 06/11/07 CRD Infosys Created
--Defining The ComplianceTrade Record DataType
TYPE rec_compliancetrade IS RECORD (
exec_broker_code crd.ts_order_alloc.exec_broker%TYPE,
exec_broker_name crd.cs_broker.bkr_name%TYPE,
client_code crd.ts_order_alloc.acct_cd%TYPE,
client_name crd.cs_fund.acct_name%TYPE,
directed_broker crd.ts_order_alloc.directed_broker%TYPE,
count_ticknum crd.ts_order.order_id%TYPE,
trade_date crd.ts_order.trade_date%TYPE,
base_cost crd.ts_order_alloc.cur_base_mkt_val%TYPE,
total_commission crd.ts_order_alloc.commision_amt%TYPE,
broker_history crd.au_broker.bkr_typ_cd%TYPE
--Declaring a variable of rec_auditdata data type
TYPE cur_compliancetrade IS REF CURSOR
RETURN rec_compliancetrade;
END infy_pkg_compliance_transact;
END OF CRD.INFY_PKG_COMPLIANCE_TRANSACTIONS
How to call this SP from VB code with ref cursor parameter?I'm fairly sure that's not possible, since there's nothing in the ODBC spec to allow for ref cursors. The driver has built in support to check for ref cursors that are returned via a stored procedure call, but there's nothing built into the driver to pass one IN. Since a ref cursor can't be constructed on the client side, you'd have to have some sort of structure that allowed you to reference the ref cursor directly in order to be able to pass one back to the database.
Since you're using VB.NET anyway, the better solution is probably just to use ODP.NET instead, which DOES allow you to reference a ref cursor directly, and there are samples that install with ODP.NET that show you how to do that.
Greg -
[Solved] 27.8.4 How to Create a VO on a REF CURSOR - Missing first row
Searching the forum I found: BC4J - Get one less row from view object.
Dive into BC4J related --REF CURSOR (Resultset)
The first message did not have any answers, and the second had a follow up question - still no answers though - and I thought I would try a different title.
(This is off topic, but it would be a great help if the search results also displayed the number of replys in the thread. That way, I wouldn't have to view the messages that don't have responses.)
(This will be deployed on a server that has the ADF for JDeveloper 10.1.2 installed, so using that version of JDeveloper to develop the app.)
Okay, back to the problem ==>
I created a VO from a ref cursor, using the manual as a guide. When I run a page that displays a read only table of the view object, I am missing the first row. (Always the first row!) I don't have any order set, and if I call the ref cursor in a Java program for testing, I see all rows and the count is correct.
One other point, when I call the page, I get the following validation error:
Validation Error
You must correct the following error(s) before proceeding:
* JBO-29000: Unexpected exception caught: java.lang.ClassCastException, msg=null
* null
I still see the table, it is just missing the first row of data.
In my form I have first, previous set, next set , and last
navigation buttons. If I press last then first, the error goes away. I still don't see the missing row though.
Any guidance would be appreciated! I can post my code, but it is pretty much the same code in the AdvancedViewObjectExamples.zip in the ViewObjectOnRefCursor example. I just substituted my two package calls (getRefCursor and getRefCursorCount).
Thanks, KenWent back to a backup copy of the source. Fixed the error. Now I'm back to just not being able to see the first row of data.
Additional Note: I had removed fields in the display. Once I truncated the ps_txn table in the schema defined by the model, the data would display (Still without the first record.)
Are there any examples that are more in depth than the few pages in the developer guide?
Here is the code for my VOImpl class:
package newslinearchive.model.datamodel;
import java.math.BigDecimal;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import oracle.jbo.InvalidParamException;
import oracle.jbo.JboException;
import oracle.jbo.domain.Date;
import oracle.jbo.domain.Number;
import oracle.jbo.server.DBTransaction;
import oracle.jbo.server.QueryCollection;
import oracle.jbo.server.SQLBuilder;
import oracle.jbo.server.ViewObjectImpl;
import oracle.jbo.server.ViewRowImpl;
import oracle.jbo.server.ViewRowSetImpl;
import oracle.jdbc.driver.OracleCallableStatement;
import oracle.jdbc.driver.OracleTypes;
// --- File generated by Oracle ADF Business Components Design Time.
// --- Custom code may be added to this class.
// --- Warning: Do not modify method signatures of generated methods.
public class SearchRefCursorImpl extends ViewObjectImpl {
* This is the default constructor (do not remove)
public SearchRefCursorImpl() {
* Overridden framework method.
* Executed when the framework needs to issue the database query for
* the query collection based on this view object. One view object
* can produce many related result sets, each potentially the result
* of different bind variable values. If the rowset in query is involved
* in a framework-coordinated master/detail viewlink, then the params array
* will contain one or more framework-supplied bind parameters. If there
* are any user-supplied bind parameter values, they will PRECEED the
* framework-supplied bind variable values in the params array, and the
* number of user parameters will be indicated by the value of the
* numUserParams argument.
protected void executeQueryForCollection(Object qc,Object[] params,int numUserParams) {
storeNewResultSet(qc,retrieveRefCursor(qc,params));
super.executeQueryForCollection(qc, params, numUserParams);
* Overridden framework method.
* Wipe out all traces of a built-in query for this VO
protected void create() {
getViewDef().setQuery(null);
getViewDef().setSelectClause(null);
setQuery(null);
* Overridden framework method.
* The role of this method is to "fetch", populate, and return a single row
* from the datasource by calling createNewRowForCollection() and populating
* its attributes using populateAttributeForRow().
protected ViewRowImpl createRowFromResultSet(Object qc, ResultSet rs) {
* We ignore the JDBC ResultSet passed by the framework (null anyway) and
* use the resultset that we've stored in the query-collection-private
* user data storage
rs = getResultSet(qc);
* Create a new row to populate
ViewRowImpl r = createNewRowForCollection(qc);
try {
* Populate new row by attribute slot number for current row in Result Set
// populateAttributeForRow(r,0, rs.getLong(1));
// populateAttributeForRow(r,1, rs.getString(2));
// populateAttributeForRow(r,2, rs.getString(3));
// MASTERID NOT NULL NUMBER
populateAttributeForRow(r,0, rs.getBigDecimal(1));
//ID NOT NULL NUMBER
populateAttributeForRow(r,1, rs.getBigDecimal(2));
// CAID NOT NULL NUMBER
populateAttributeForRow(r,2, rs.getBigDecimal(3));
// LANGUAGE NOT NULL VARCHAR2(30)
populateAttributeForRow(r,3, rs.getString(4));
// IS_CURRENT_VERSION NOT NULL NUMBER(1)
populateAttributeForRow(r,4, rs.getBigDecimal(5));
// FOLDER_ID NOT NULL NUMBER
populateAttributeForRow(r,5, rs.getBigDecimal(6));
// FOLDER_REGION_ID NOT NULL NUMBER
populateAttributeForRow(r,6, rs.getBigDecimal(7));
// NAME NOT NULL VARCHAR2(256)
populateAttributeForRow(r,7, rs.getString(8));
// DISPLAY_NAME VARCHAR2(256)
populateAttributeForRow(r,8, rs.getString(9));
// ITEMTYPE NOT NULL VARCHAR2(30)
populateAttributeForRow(r,9, rs.getString(10));
// SUBTYPE VARCHAR2(40)
populateAttributeForRow(r,10, rs.getString(11));
// SUBTYPE_CAID NUMBER
populateAttributeForRow(r,11, rs.getBigDecimal(12));
// PARENT_ITEM_ID NUMBER
populateAttributeForRow(r,12, rs.getBigDecimal(13));
// CATEGORY_ID NUMBER
populateAttributeForRow(r,13, rs.getBigDecimal(14));
// CATEGORY_CAID NUMBER
populateAttributeForRow(r,14, rs.getBigDecimal(15));
// AUTHOR VARCHAR2(50)
populateAttributeForRow(r,15, rs.getString(16));
// DESCRIPTION VARCHAR2(2000)
populateAttributeForRow(r,16, rs.getString(17));
// PUBLISH_DATE NOT NULL DATE
populateAttributeForRow(r,17, rs.getDate(18));
// EXPIREMODE VARCHAR2(90)
populateAttributeForRow(r,18, rs.getString(19));
// EXPIRENUMBER NUMBER
populateAttributeForRow(r,19, rs.getBigDecimal(20));
// EXPIREDATE DATE
populateAttributeForRow(r,20, rs.getDate(21));
// IMAGE VARCHAR2(350)
populateAttributeForRow(r,21, rs.getString(22));
// KEYWORDS VARCHAR2(2000)
populateAttributeForRow(r,22, rs.getString(23));
// URL VARCHAR2(4000)
populateAttributeForRow(r,23, rs.getString(24));
// FILENAME VARCHAR2(350)
populateAttributeForRow(r,24, rs.getString(25));
// TEXT CLOB()
populateAttributeForRow(r,25, rs.getClob(26));
// FOLDER_LINK_ID NUMBER
populateAttributeForRow(r,26, rs.getBigDecimal(27));
// FOLDER_LINK_CAID NUMBER
populateAttributeForRow(r,27, rs.getBigDecimal(28));
// ACTIVE NOT NULL NUMBER(1)
populateAttributeForRow(r,28, rs.getBigDecimal(29));
// CAN_BE_CHECKEDOUT NUMBER(1)
populateAttributeForRow(r,29, rs.getBigDecimal(30));
// IS_ITEM_CHECKEDOUT NUMBER(1)
populateAttributeForRow(r,30, rs.getBigDecimal(31));
// CHECKER_USERNAME VARCHAR2(256)
populateAttributeForRow(r,31, rs.getString(32));
// CHECKOUT_DATE DATE
populateAttributeForRow(r,32, rs.getDate(33));
// FULLSCREEN NOT NULL NUMBER(1)
populateAttributeForRow(r,33, rs.getBigDecimal(34));
// INPLACE NOT NULL NUMBER(1)
populateAttributeForRow(r,34, rs.getBigDecimal(35));
// CREATEDATE NOT NULL DATE
populateAttributeForRow(r,35, rs.getDate(36));
// CREATOR NOT NULL VARCHAR2(256)
populateAttributeForRow(r,36, rs.getString(37));
// UPDATEDATE DATE
populateAttributeForRow(r,37, rs.getDate(38));
// UPDATOR VARCHAR2(256)
populateAttributeForRow(r,38, rs.getString(39));
// SECURITY VARCHAR2(25)
populateAttributeForRow(r,39, rs.getString(40));
// VISIBLE NOT NULL NUMBER(1)
populateAttributeForRow(r,40, rs.getBigDecimal(41));
// SEQUENCE NOT NULL NUMBER
populateAttributeForRow(r,41, rs.getBigDecimal(42));
// CATEGORY_SEQUENCE NOT NULL NUMBER
populateAttributeForRow(r,42, rs.getBigDecimal(43));
// AUTHOR_SEQUENCE NOT NULL NUMBER
populateAttributeForRow(r,43, rs.getBigDecimal(44));
// CREATE_DATE_SEQUENCE NOT NULL NUMBER
populateAttributeForRow(r,44, rs.getBigDecimal(45));
// ITEMTYPE_SEQUENCE NOT NULL NUMBER
populateAttributeForRow(r,45, rs.getBigDecimal(46));
catch (SQLException s) {
throw new JboException(s);
return r;
* Overridden framework method.
* Return true if the datasource has at least one more record to fetch.
protected boolean hasNextForCollection(Object qc) {
ResultSet rs = getResultSet(qc);
boolean nextOne = false;
try {
nextOne = rs.next();
* When were at the end of the result set, mark the query collection
* as "FetchComplete".
if (!nextOne) {
setFetchCompleteForCollection(qc, true);
* Close the result set, we're done with it
rs.close();
catch (SQLException s) {
throw new JboException(s);
return nextOne;
* Overridden framework method.
* The framework gives us a chance to clean up any resources related
* to the datasource when a query collection is done being used.
protected void releaseUserDataForCollection(Object qc, Object rs) {
* Ignore the ResultSet passed in since we've created our own.
* Fetch the ResultSet from the User-Data context instead
ResultSet userDataRS = getResultSet(qc);
if (userDataRS != null) {
try {
userDataRS.close();
catch (SQLException s) {
/* Ignore */
super.releaseUserDataForCollection(qc, rs);
* Overridden framework method
* Return the number of rows that would be returned by executing
* the query implied by the datasource. This gives the developer a
* chance to perform a fast count of the rows that would be retrieved
* if all rows were fetched from the database. In the default implementation
* the framework will perform a SELECT COUNT(*) FROM (...) wrapper query
* to let the database return the count. This count might only be an estimate
* depending on how resource-intensive it would be to actually count the rows.
public long getQueryHitCount(ViewRowSetImpl viewRowSet) {
Long result = (Long)callStoredFunction(NUMBER,
"PORTAL.SEARCH_REFCURSOR.getRefCursorCount",
viewRowSet.getParameters(true));
return result.longValue();
// ------------- PRIVATE METHODS ----------------
* Return a JDBC ResultSet representing the REF CURSOR return
* value from our stored package function.
* new Object[]{getNamedBindParamValue("Email",params)}
private ResultSet retrieveRefCursor(Object qc, Object[] params) {
ResultSet rs = (ResultSet)callStoredFunction(OracleTypes.CURSOR,
"PORTAL.SEARCH_REFCURSOR.getRefCursor",
null);
return rs ;
private Object getNamedBindParamValue(String varName, Object[] params) {
Object result = null;
if (getBindingStyle() == SQLBuilder.BINDING_STYLE_ORACLE_NAME) {
if (params != null) {
for (Object param : params) {
Object[] nameValue = (Object[])param;
String name = (String)nameValue[0];
if (name.equals(varName)) {
return (String)nameValue[1];
throw new JboException("No bind variable named '"+varName+"'");
* Store a new result set in the query-collection-private user-data context
private void storeNewResultSet(Object qc, ResultSet rs) {
ResultSet existingRs = getResultSet(qc);
// If this query collection is getting reused, close out any previous rowset
if (existingRs != null) {
try {existingRs.close();} catch (SQLException s) {}
setUserDataForCollection(qc,rs);
hasNextForCollection(qc); // Prime the pump with the first row.
* Retrieve the result set wrapper from the query-collection user-data
private ResultSet getResultSet(Object qc) {
return (ResultSet)getUserDataForCollection(qc);
* Return either null or a new oracle.jbo.domain.Date
private static Date nullOrNewDate(Timestamp t) {
return t != null ? new Date(t) : null;
* Return either null or a new oracle.jbo.domain.Number
private static Number nullOrNewNumber(BigDecimal b) {
try {
return b != null ? new Number(b) : null;
catch (SQLException s) { }
return null;
//----------------[ Begin Helper Code ]------------------------------
public static int NUMBER = Types.NUMERIC;
public static int DATE = Types.DATE;
public static int VARCHAR2 = Types.VARCHAR;
public static int CLOB = Types.CLOB;
* Simplifies calling a stored function with bind variables
* You can use the NUMBER, DATE, and VARCHAR2 constants in this
* class to indicate the function return type for these three common types,
* otherwise use one of the JDBC types in the java.sql.Types class.
* NOTE: If you want to invoke a stored procedure without any bind variables
* ==== then you can just use the basic getDBTransaction().executeCommand()
* @param sqlReturnType JDBC datatype constant of function return value
* @param stmt stored function statement
* @param bindVars Object array of parameters
* @return function return value as an Object
protected Object callStoredFunction(int sqlReturnType, String stmt,
Object[] bindVars) {
CallableStatement st = null;
try {
st = getDBTransaction().createCallableStatement("begin ? := " + stmt +
"; end;", 0);
st.registerOutParameter(1, sqlReturnType);
if (bindVars != null) {
for (int z = 0; z < bindVars.length; z++) {
st.setObject(z + 2, bindVars[z]);
st.executeUpdate();
return st.getObject(1);
catch (SQLException e) {
throw new JboException(e);
finally {
if (st != null) {
try {
st.close();
catch (SQLException e) {}
/**Gets the bind variable value for Email
public String getEmail() {
return (String)getNamedWhereClauseParam("Email");
/**Sets <code>value</code> for bind variable Email
public void setEmail(String value) {
setNamedWhereClauseParam("Email", value);
/**getEstimatedRowCount - overridden for custom java data source support.
public long getEstimatedRowCount() {
long value = super.getEstimatedRowCount();
return value;
Thanks, Ken -
Using CRUD procedures to update data and ref cursors to return data
Hi:
I am currently evaluating Apex 3.x to replace an existing app that uses lots of procedures to update and return data.
1. Is it possible to return data from a function that returns a cursor (or from a procedure that has an input/output ref cursor parameter for that matter) ? Example: Let's say I have the following function in a package:
function get_data return sys_refcursor
is
l_cursor sys_refcursor;
begin
open l_cursor for select sysdate as field from sys.dual;
return l_cursor;
end;
Can I add a page with a table that is populated based on this function? Based on my research it is not possible, but I want an APEX expert to confirm it
2. The old application uses CRUD procedures to update date, that is for each table there are 3 procedures, insert update and delete. Question: is it possible to channel all the update, inserts and deletes through these procedures? Furthermore, in lots of cases I use sequences to populate the primary keys, and the new value is returned as output parameter. Can I retrieve the output value and use it maybe in the next page I am branching to?
In the samples that I've seen the same form is used for insert and update. How do I distinguish between the two modes?
3. Can you please point me to some samples that show how to do 1 & 2. The standard samples that I've seen use the automatic row processing.
4. Could you please recommend some good books about Apex or HTML db? I found the documentation unintuitive. It is hard to picture quickly how things tie together by reading this documention. I wish the documentation was more task oriented and presented 'how to...' implement generic patterns used in web apps.
Thank you in advanceHi guys
Check out the last 2 posts in this thread for ideas on how to implement 1.
Report on user data from LDAP
Varad -
VC 7.0 Oracle stored procedures resultset with ref cursor
Can VC (we are on NW7 SP13) handle Oracle's datatype ref cursor - which is the standard solution in Oracle to return result sets - as the return value of a stored procedure?
When testing a data service in the VC story board based upon a simple Oracle function like:
create or replace package pkg_dev
is
type t_cursor is ref cursor;
end;
create or replace function vc_stub return pkg_dev.t_cursor
as
l_cursor pkg_dev.t_cursor;
begin
open l_cursor for select ename from emp;
return l_cursor;
end;
(just as example - I know that could be easily retrieved using the BI JDBC connector framework and accessing tables / views)
I am always running in the "portal request failed ( Could not execute Stored Procedure)" error - so I am not able to use the "add fields" function to bind the output.
The defaulttrace contains entries like:
Text: com.sap.portal.vc.HTMLBRunTime
[EXCEPTION]
com.sapportals.connector.execution.ExecutionException: Could not execute stored procedure
Caused by: java.sql.SQLException: Invalid column type
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
We deployed Oracle's own jdbc-driver for Oracle 10g. Using that driver and a portal jdbc connector framework entry the stored procedures of the Oracle database user mapped to the portal user are discovered and available in the "Find Data Services" section.We deployed the drivers as described in the HowTo Papers (e.g.Hwo to Configure UD Connect on the J2EE Server for JDBC Access to External Databases). When deploying the drivers you assign a freely definable name for the set of Oracle's jar-files (eg. oracle_10) as library name. Having deployed the drivers in that way only System Definitions via BI JDBC connector framework were working. With a little help from SAP Support (call lasted more than 2 months till a very capable member of the support team made things working in a very short time) we got the portal jdbc connection with Oracle's jar-files working:
Here are instructions how to add reference:
1. Connect to the j2ee using telnet, e.g in the cmd window type:
telnet <host> <port> + 8, enter uid and pwd of j2ee admin.
2. jump 0
3. add deploy
4. change_ref -m com.sapportals.connectors.database <your lib name> <your lib name = oracle_10>
Trying to manually add this reference in visual admin connector container for JDBCFactory failed - reference could be added and saved, but then disappeared (at least in NW7 with SP12). Adding the reference as described above solved the problem.
Maybe you are looking for
-
Phone is sending out texts on it's own.
I rarely send any texts on my Razr V3M. This weekend it began sending info. to 0000006245 on it's own while I was sleeping (24 in one day). The info. / texts were intercepted by a security company and replied to by sending texts back to my phone s
-
Hello, I wish for all Word documents to open in the browser for my SharePoint document library on my team site. The feature 'open in client application' is not activated in Features for the site collection and the setting in the document library is s
-
Calling another procedure in a procedure
How can we execute procedure in another procedure?
-
I have been trying...but still failed! Please help...
Here is my java code: public class BPUSBFinger200 { private final static BPUSBFinger200 instance = new BPUSBFinger200(); static { System.loadLibrary("lib/BPUSBFinger200"); private BPUSBFinger200() { public static BPUSBFinger200 getInstanc
-
I seriously don't know what to do, the screen says: "Your iPhone could not be activated because the activation server cannot be reached. Try connecting your phone to iTunes to activate it or try in a couple of minutes if this problem persists, contac