Refcursor or object?
Working on stored procedure which will be called by java app.
I don't know which of the following option is better and in what cases:
1. stored procedure returning/accepting a parameter of SYS_REFCURSOR
or
2. at schema level:
TYPE emp_attrb_obj AS OBJECT (attribute_type_id NUMBER(10),
attribute_val VARCHAR2(50)
create or replace
TYPE emp_attrb_type AS TABLE OF emp_attrb_obj;
and then have a stored procedure accepting or returning a parameter of type emp_attrb_type
Thanks,
RN
RN wrote:
Working on stored procedure which will be called by java app.
I don't know which of the following option is better and in what cases:
1. stored procedure returning/accepting a parameter of SYS_REFCURSOR
or
2. at schema level:
TYPE emp_attrb_obj AS OBJECT (attribute_type_id NUMBER(10),
attribute_val VARCHAR2(50)
create or replace
TYPE emp_attrb_type AS TABLE OF emp_attrb_obj;
and then have a stored procedure accepting or returning a parameter of type emp_attrb_type
Thanks,
RNWell, a java app is unlikely to be able to pass you a ref cursor, so your procedure will not need to accept one. Other than that, it really depends on how much data you expect to get passed back and forth.
I have a number of stored procs called by java apps that return a single row from a table. In those cases, I often return an object, since it saves a step for the jave guys who can use it more or less directly. If there is not an exlplicit limit on the number of rows returned, then I would always return a refcursor.
If the java app needs to pass a set of values into the stored procedure (e.g. get me information about this list of employees), then I would have java pass a table of objects (an array of records) to the stored procedure. This saves me from having to parse out a delimited string of values.
John
Similar Messages
-
Mapping refcursors with object types in a procedure
Hi all,
I need some help regarding the mapping of refcursors with object types .
Example: Procedure "A" has object types as input/output parameters which lies in the Web Method Application as a API.
We are creating a procedure "B" which has ref cursors as input/ouput parameters
which will map to the Procedure "A"'s object type parameters.
It will be highly needful for the solution.
Regards
SaugataYour pseudocode has a lot of steps in it, but you didn't say which step you need help with. Since I already covered going from a nested table type to a refcursor, I'll assume you want an example that goes the other way now, like from a refcursor to a nested table type. Here's one ...
SQL>
SQL>
SQL> set serveroutput on
SQL>
SQL> create type nested_table_type as table of varchar2(14) ;
2 /
Type created.
SQL> show errors
No errors.
SQL>
SQL>
SQL> create function func
2 ( p_cursor in sys_refcursor )
3 return nested_table_type
4 as
5 v_nested_table nested_table_type ;
6 begin
7
8 fetch p_cursor bulk collect into v_nested_table ;
9 return( v_nested_table );
10
11 end;
12 /
Function created.
SQL> show errors
No errors.
SQL>
SQL> select func( cursor( select dname from dept ) ) as nested_table from dual ;
NESTED_TABLE
NESTED_TABLE_TYPE('ACCOUNTING', 'RESEARCH', 'SALES', 'OPERATIONS')If your cursor selects objects instead of simple data types, the code is pretty much the same.
SQL> create type object_type as object ( c1 varchar2(14), c2 varchar2(13) );
2 /
Type created.
SQL> show errors
No errors.
SQL>
SQL> create type nested_table_type as table of object_type ;
2 /
Type created.
SQL> show errors
No errors.
SQL>
SQL>
SQL>
SQL> create function func
2 ( p_cursor in sys_refcursor )
3 return nested_table_type
4 as
5 v_nested_table nested_table_type ;
6 begin
7
8 fetch p_cursor bulk collect into v_nested_table ;
9 return( v_nested_table );
10
11 end;
12 /
Function created.
SQL> show errors
No errors.
SQL>
SQL> select
2 func( cursor( select object_type( dname, loc ) from dept ) ) as object_table
3 from dual ;
OBJECT_TABLE(C1, C2)
NESTED_TABLE_TYPE
( OBJECT_TYPE('ACCOUNTING', 'NEW YORK'),
OBJECT_TYPE('RESEARCH', 'DALLAS'),
OBJECT_TYPE('SALES', 'CHICAGO'),
OBJECT_TYPE('OPERATIONS', 'BOSTON')
)(NB I manually reformated the query results for clarity). -
Transient View Object based on a RefCursor?
Hi!
I have a ViewObject named VO1 which is based on an EO mapped to a db table. Now I have a Transient ViewObject TVO2 which is based on a PL/SQL ref cursor. The example on Steve Muench site is a ViewObject based on an EO but overrides the viewobject framework functions to make it ref cursor based. What I am trying to do is different from the example, so I'm wondering if this is possible?
I had a viewlink to connect VO1 and TVO2 because the viewlink attribute values from VO1 will be input parameters to the PL/SQL function in TVO2. When I tested this scenario, I get a ClassCastException inside the overriden function
executeQueryForCollection(...) {
... params[0] //when this line executes I get a ClassCastException Ljava.lang.Object...
super.executeQueryForCollection(...);
}Hi!
I encountered the same problem, and found out that each param[] entry is itself an Object[]. So with the following code you can find the contents:
Object[] bindvar = (Object[])params[0];
String varName = (String)bindvar[0];
Object varValue = bindvar[1];Hope this helps,
Jeroen -
Hello,
I have a problem with refcursor in a project migrated from 10 to 11g.
I found this thread from a few years ago that talks about the same problem.
It has no final answer - is it ok to comment the st.close(); in callStoredFunction in the AMImpl.
Re: TP4 - View Object with REF CURSOR - SQLException
Please tell me if the suggested solution on that thread is fine, or ot will cause many unclosed statetements?
Thank you, NinaHello All,
I got the solution to the problem.
I was trying to surround the region component using the Structure pane. But instead drag and drop the strechable components on to the region.
Ex: Region got expanded 100% if I surround it with PanelStrechLayout with width and height set to 100%. But I didnit find this Panel StrechLayout when I try to surround it using Structure Pane.
Refer to this: http://www.oracle.com/technology/products/adf/patterns/layoutBestPractices.html
Thanks,
Melissa. -
Use of identifier in ByD Studio business objects
As Wed Feb 2nd in VQ3), we introduced a new identifier data type for partner BOs.
ByD Studio contains 2 identifier:
element ID : ID; // identifier 2 (SAP "best practiceu201D)
element Identifier : Identifier; // identifier 1 (u201CCCTS compliant")
As the CCTS-complient data type u201CIdentifieru201D has various difficulties, we recommend urgently to use the data type "ID". The differences between the two data types is explained below:
1. Length
The DT Identifier has a length of 255 char.
The DT ID has a length of 60 char.
2. Upper case conversion
The DT ID supports upper case only. User entries with lower case characters are automatically converted to upper case. This is the same behavior as almost all ByD identifier data types (e.g. BusinessTransactionDocumentID, ProductID, BusinessPartnerID, etc.)
The DT Identifier supports lower case letters as well.
3. Alpha conversion
The DT ID supports alpha conversion. User entries which contain number characters only are filled with zeros from the left side (leading zeros). On the UI the leading zeros are suppressed automatically. This is the same behavior as almost all ByD identifier data types (e.g. BusinessTransactionDocumentID, ProductID, BusinessPartnerID, etc.) The DT Identifier does not support alpha conversion. This leads to an u201Cunexpectedu201D sort order on the UI.
This leads to the following sort behavior:
Sort order ID Sort order Identifier:
.1.1 .1.1
1 1
5 1.1
10 10
15 100
50 15
100 5
1.1 50
ABC abc
(no lower case) ABC
4. Structure
The ID data type is flat. There is no need for the u201C.Contentu201D suffix any longer.
The Identifier data type is structured (contains supplementary components), so the u201C.Contentu201D suffix is needed (although the supplementary components are disabled in the BO).
5. Behavior in ByD script coding:
The following coding works fine:
import ABSL;
var x = 1;
if (this.ID == "") {
// is true if ID is initial
this.ID = x.ToString();
this.ID = "1";
if (this.ID == "1") {
// is does not work, because u201C1u201D was filled with leading zeros
if (this.ID == "000000000000000000000000000000000000000000000000000000000001") {
// is true now because u201C1u201D was filled with leading zeros
raise IDMessage.Create("I", this.ID);
// leading zeros are suppressed on the UI: u201CID: 1u201D
6. Restrictions in Extensibility and Analytics:
Only the ID data type will be supported in extensibility and analytics:
Extensibility: It will be possible to add an extension field in an BO extension (planned for FP3.0).
element ID : ID;
Analytics: Analytics supports only character fields with a maximum length of 60 characters & alpha conversion.
Consequence: the u201CIdentifieru201D DT cannot be used in Extensibility and Analytics.
7. Adoption
If you have used the data type "Identifier" before and want to change the BO to "ID", the following adoption tasks are necessary:
a) Business Object: change the BO definition file (see point 1)
Note: During my tests I got a activation error. In this case I solved the problem by Clean -> Save -> Activate. In this case, test data are lost
b) Business Object: Implementation: remove the u201C.Contentu201D suffix
c) UI: After the BO change, the following runtime error occurs in the affected UI. In the error text the following text occurs: u201CMapping of proxy name of attribute failed.u201D
Solution: Open the UI Designer,
(1) Tools -> Update Meta Data
(2) Go to the data model and do u201CUnbindu201D and u201CBindu201D again for the affected field
(3) Save & Activate
d) MDAV, Forms, Web services -> not analyzed. Assumption here is that the dependent objects have to be cleaned and activated.OK, I have found your code in your previous post.
It works in 9.2.0.1.0 and 8.1.7.0.0.
SQL> CREATE OR REPLACE TYPE t_assoc_agents_address AS OBJECT
2 (V_CONTACT_NAME VARCHAR2(120),
3 V_ADDRTYPE VARCHAR2(80),
4 V_ADDRESS_LINE1 VARCHAR2(50),
5 V_ADDRESS_LINE2 VARCHAR2(50),
6 V_ADDRESS_LINE3 VARCHAR2(50),
7 V_CITY_STATE_ZIP VARCHAR2(100),
8 V_PHONE VARCHAR2(50),
9 V_ADDRESS_FAX VARCHAR2(30),
10 V_ADDRESS_EMAIL VARCHAR2(80)
11 )
12 /
 
Type created.
 
SQL> CREATE OR REPLACE TYPE nt_assoc_agents_address AS TABLE OF t_assoc_agents_address
2 /
 
Type created.
 
SQL> var c refcursor
SQL> col v_address_fax format a15
SQL> col v_address_email format a15
SQL> declare
2 lv_assoc_agents_add_out nt_assoc_agents_address
3 := nt_assoc_agents_address(
4 t_assoc_agents_address(null,null,null,null,null,null,null,
5 'New Fax', 'New Mail')
6 );
7 begin
8 open :c for select V_ADDRESS_FAX,V_ADDRESS_EMAIL from
9 table(cast(lv_assoc_agents_add_out as nt_assoc_agents_address));
10 end;
11 /
 
PL/SQL procedure successfully completed.
 
SQL> print c
 
V_ADDRESS_FAX V_ADDRESS_EMAIL
New Fax New MailWhat is your Oracle release and how are you using ref cursor (if I interpret your example right) ?
Rgds. -
Refcursor returning image (BLOB type) from database
Hi,
Process : Invoke activity takes ID as input parameter and passes it to partner link (db adapter) which executes stored proc returning a ref cursor. SQL statement in stored proc - ref cursor has a column with BLOB type.
Problem : Unable to return an image (defiined as BLOB type in database) through refcursor in BPEL.
Error : Unable to convert XSD element Column whose JDBC type is BLOB to a corresponding XML document element.
ORABPEL-11087
XSD :
<complexType name="RowSet">
<sequence>
<element name="Row" minOccurs="0" maxOccurs="unbounded" nillable="true">
<complexType>
<sequence>
<element name="Column" maxOccurs="unbounded" nillable="true">
<complexType>
<simpleContent>
<extension base="string">
<attribute name="name" type="string" use="required"/>
<attribute name="sqltype" type="string" use="required"/>
</extension>
</simpleContent>
</complexType>
</element>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
Need Solution : To get an image (of BLOB type) into BPEL using ref cursor.
Please let me know if you need any more information to get it working.
Thanks and Regards,
RakeshHi Rakesh,
There are some notes you might want to refer :
Note.423909.1 'java.lang.NumberFormatException' Signaled When Using Oracle LOB Family Column Types In ODI Datastores And Integration Interfaces:
Note.423982.1 An "ORA-17410 No More Data to Read From Socket" Error Has Been Signaled From An ODI (Sunopsis) Integration Interface:
Note.423768.1 Using Oracle Large Object (LOB) Datatype Columns In ODI Integration Interfaces:
Note.744101.1 ORA-22835 Message Signaled When Using The OdiSqlUnload Tool In ODI:
Note.424658.1 "ORA-00942" Message With Oracle Large Object (LOB) Datatype Fields In ODI Integration Interfaces:
Note.423992.1 Using Oracle LONG Datatype Columns In ODI(Sunopsis):
Note.424107.1 ODI Integration Interfaces And The Use Of Oracle Spatial Datatypes In Source And Target Datastores:
Hope this helps!
Cheers
Anirudh Pucha -
Dynamic Column Names using Refcursors
Hi,
I have a stored procedure which returns a refcursor. The refcursor contains a SQL query in which the column names and number of columns vary dynamically based on the date parameters passed.
"My objective is to return certain XYZ details of employees for a certain month range."
For ex: For the month of Aug-2011, the column names would be '1-AUG-11' to '31-AUG-11 and for Feb-2011 '1-FEB-11' to '28-FEB-11'
My issue is, when I execute the refcursor query using "EXEC", my column names/headings are preserved.
FIELD NAMES: EMPLOYEE_CODE XYZ_TYPE *1-AUG-11* *2-AUG-11* ... *31-AUG-11*
DATA: EMPCODE_Z TYPE1 VALUE_1 VALUE_1 ... VALUE_31
Whereas when I fetch the refcursor into a collection of nested table and display, my column names are lost.
DATA: EMPCODE_Z TYPE1 VALUE_1 VALUE_1 ... VALUE_31
Is there a way where I can preserve the column names from the refcursor after fetching into pl/sql collections?
Any help would be highly appreciated.
Thank you.
Edited by: 867622 on Nov 11, 2011 4:38 PM867622 wrote:
If not dynamic SQL, how can the number of columns be altered based on the input parameters?Cannot. A dynamic SQL projection means dynamic SQL (there's an exception to this, and despite interesting is not relevant to 99.99% of problems dealing with dynamic SQL projections).
You can however still use a dynamic projection and wrap that into a user defined type interface.
Here's the basic approach:
// create a user define type that will provide the wrapper for the SQL projection
create or replace type TString as table of varchar2(4000);
// build dynamic SQL projections via this type, e.g.
select
TStrings( object_id, object_name, created )
from user_objects
select
TStrings( emp_id, dept_id, salary, commission )
from employeesDespite the SQL cursors being different and the columns and number of columns being selected different, the SQL projection of both are the same. The Count method tells you the number of columns in the projection. Referencing an applicable column is simply done by using the column's sequential number in the projection.
You also do not have to use a collection or varchar2 as the wrapper type - you can create complex user objects and use the collection type for that, as the SQL projection.
Another alternative is converting the ref cursor into a DBMS_SQL cursor and using the latter's describe interface to dynamically determine the structure of the SQL projection and fetching the column values from it. But 11gr1 or later is needed for doing this. -
Output parameters always return null when ExecuteNonQuery - No RefCursor
I am trying to call a procedure through ODP that passes in one input parameter and returns two (non-RefCursor) VARCHAR2 output parameters. I am calling the procedure using ExecuteNonQuery(); however, my parameters always return null. When I run the procedure outside of ODP, such as with SQLPlus or SQL Navigator, the output parameters are populated correctly. For some reason, there appears to be a disconnect inside of ODP. Is there a way to resolve this?
Anyone have this problem?
Here is the basic code:
===========================================================
// External call of the class below
DBNonCursorParameterTest Tester = new DBNonCursorParameterTest();
===========================================================
// The class and constructor that calls the procedure and prints the results.
public class DBNonCursorParameterTest
public DBNonCursorParameterTest()
// The test procedure I used is a procedure that takes a recordID (Int32) and then returns a
// general Name (Varchar2) and a Legal Name (Varchar2) from one table with those three fields.
string strProcName = "MyTestProc;
OracleConnection conn = new OracleConnection(DBConnection.ConnectionString);
OracleCommand cmd = new OracleCommand(strProcName,conn);
cmd.CommandType = CommandType.StoredProcedure;
// Create the input parameter and the output cursor parameter to retrieve data; assign a value to the input parameter;
// then create the parameter collection and add the parameters.
OracleParameter pBPID = new OracleParameter("p_bpid", OracleDbType.Int32, ParameterDirection.Input);
OracleParameter pBPName = new OracleParameter("p_Name", OracleDbType.Varchar2, ParameterDirection.Output);
OracleParameter pBPLegalName = new OracleParameter("p_LegalName", OracleDbType.Varchar2, ParameterDirection.Output);
pBPID.Value = 1;
// Open connection and run stored procedure.
try
conn.Open();
cmd.Parameters.Add(pBPID);
cmd.Parameters.Add(pBPName);
cmd.Parameters.Add(pBPLegalName);
cmd.ExecuteNonQuery();
Console.Write("\n" + cmd.CommandText + "\n\n");
//for (int i = 0; i < cmd.Parameters.Count; i++)
// Console.WriteLine("Parameter: " + cmd.Parameters.ParameterName + " Direction = " + cmd.Parameters[i].Direction.ToString());
// Console.WriteLine("Parameter: " + cmd.Parameters[i].ParameterName + " Status = " + cmd.Parameters[i].Status.ToString());
// Console.WriteLine("Parameter: " + cmd.Parameters[i].ParameterName + " Value = " + cmd.Parameters[i].Value.ToString() + "\n");
foreach (OracleParameter orap in cmd.Parameters)
Console.WriteLine("Parameter: " + orap.ParameterName + " Direction = " + orap.Direction.ToString() + " Value = " + orap.Value.ToString());
Console.WriteLine("Parameter: " + orap.ParameterName + " Status = " + orap.Status.ToString());
Console.WriteLine("Parameter: " + orap.ParameterName + " Value = " + orap.Value.ToString() + "\n");
// End Test code.
catch (Exception ex)
throw new Exception("ExecuteQuery() failed: " + ex.Message);
finally
this.Close();
public void Close()
if (conn.State != ConnectionState.Closed)
conn.Close();
=========================================================
Other things to note:
I have no problems with returning RefCursors; they work fine. I just don't want to use RefCursors when they are not efficient, and I want to have the ability to return output parameters when I only want to return single values and/or a value from an insert/update/delete.
Thanks for any help you can provide.Hello,
Here's a short test using multiple out parameters and a stored procedure. Does this work as expected in your environment?
Database:
/* simple procedure to return multiple out parameters */
create or replace procedure out_test (p_text in varchar2,
p_upper out varchar2,
p_initcap out varchar2)
as
begin
select upper(p_text) into p_upper from dual;
select initcap(p_text) into p_initcap from dual;
end;
/C# source:
using System;
using System.Data;
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;
namespace Miscellaneous
class Program
static void Main(string[] args)
// change connection string as appropriate
const string constr = "User Id=orademo; " +
"Password=oracle; " +
"Data Source=orademo; " +
"Enlist=false; " +
"Pooling=false";
// the stored procedure to execute
const string sql = "out_test";
// simple input parameter for the stored procedure
string text = "hello!";
// create and open connection
OracleConnection con = new OracleConnection(constr);
con.Open();
// create and setup connection object
OracleCommand cmd = con.CreateCommand();
cmd.CommandText = sql;
cmd.CommandType = CommandType.StoredProcedure;
// the input paramater
OracleParameter p_text = new OracleParameter("p_text",
OracleDbType.Varchar2,
text.Length,
text,
ParameterDirection.Input);
// first output parameter
OracleParameter p_upper = new OracleParameter("p_upper",
OracleDbType.Varchar2,
text.Length,
null,
ParameterDirection.Output);
// second output parameter
OracleParameter p_initcap = new OracleParameter("p_initcap",
OracleDbType.Varchar2,
text.Length,
null,
ParameterDirection.Output);
// add parameters to collection
cmd.Parameters.Add(p_text);
cmd.Parameters.Add(p_upper);
cmd.Parameters.Add(p_initcap);
// execute the stored procedure
cmd.ExecuteNonQuery();
// write results to console
Console.WriteLine(" p_text = {0}", text);
Console.WriteLine(" p_upper = {0}", p_upper.Value.ToString());
Console.WriteLine("p_initcap = {0}", p_initcap.Value.ToString());
Console.WriteLine();
// keep console from closing when run in debug mode from IDE
Console.WriteLine("ENTER to continue...");
Console.ReadLine();
}Output:
p_text = hello!
p_upper = HELLO!
p_initcap = Hello!
ENTER to continue...- Mark -
How can i return an object isn't java object from webservice????
Hi !
I have a problem in my Project. When i call method return a java object from webservice , it 's too easy. But when i create my own object (ex:ClientRequest.class) , it doesn't work exactly T_T . When i return that object (on client, doesn't have ClientRequest.class) , i cann't access its static variables.
How can i do it ??
Please help me !
Thanks a lot !!!!!
class ClientRequest {
public static int i;
public static String s;
public ClientRequest() {
}You can use REFCURSOR type for this. In java SQL TYPES this is available too. In your PLSQL use REFCURSOR for that array and then take the same from java code. Look in the servelet programming book for this SQLTYPE and see PLSQL for handling refcursors. We have done this way and it works.
-
Hello All,
I have a procedure
PROCEDURE get_tran_detail (
i_user_id IN NUMBER := 0,
i_portfolio_id_list IN NUM_ARRAY,
i_from_dt IN transaction.trade_dt%TYPE,
i_to_dt IN transaction.trade_dt%TYPE,
i_include_suppress_txn IN NUMBER,
o_transactions OUT TXN_SUMMARY_INFO_ARRAY_test, ----output
i_debugmode IN NUMBER := 0
How do I get the o_transactions to be inserted into a GTT?
This is what I have so far
CREATE OR REPLACE PROCEDURE get_control_ref_cursor( p_ref_cursor OUT SYS_REFCURSOR )
AS
l_base_proc_ref_cursor SYS_REFCURSOR;
l_result_rec MI_GET_TXN_GTT%rowtype;
BEGIN
mi_ade_service_pkg_test.get_tran_detail (
118
,num_array(7366975,7366976,7364727) --portfolio_id
,'22-aug-2011' --transaction_date
,sysdate
,1
,o_transactions
,0);
LOOP
FETCH l_base_proc_ref_cursor INTO l_result_rec;
INSERT INTO MI_GET_TXN_GTT VALUES( l_result_rec );
OPEN p_ref_cursor
FOR SELECT *
FROM MI_GET_TXN_GTT;
END;
Error:
LINE/COL ERROR
23/4 PLS-00103: Encountered the symbol ";" when expecting one of the
following:
loop
Thanks>
How do I get the o_transactions to be inserted into a GTT?
>
Easy - DON'T DO THAT!
Why do you want to put the data into a GTT when all you do is then create a cursor on the data.
Just return the data in o_transactions directly the the caller.
Post the DDL for the objects you are using.
Here is a simple example you can try in the SCOTT schema. It uses a VARRAY and just queries it as a table.
CREATE OR REPLACE TYPE enamelist as VARRAY(20) of VARCHAR2(20)
CREATE OR REPLACE FUNCTION ename_fn
RETURN enamelist
AS
v_cursor_main enamelist := enamelist ();
BEGIN
SELECT ename
BULK COLLECT
INTO v_cursor_main
FROM emp;
RETURN v_cursor_main;
EXCEPTION
WHEN OTHERS
THEN
RETURN v_cursor_main;
END;
select * from table(ename_fn());
COLUMN_VALUE
SMITH
ALLEN
WARD
JONES
MARTIN
BLAKE
CLARK
SCOTT
KING
TURNER
ADAMS
JAMES
FORD
MILLERFor your use case you have
o_transactions OUT TXN_SUMMARY_INFO_ARRAY_testIf that 'ARRAY' is a VARRAY then you would just open the cursor on 'o_transactions'
OPEN p_ref_cursor
FOR SELECT * FROM TABLE(o_transactions);Get rid of the GTT.
CREATE OR REPLACE PROCEDURE get_control_ref_cursor( p_ref_cursor OUT SYS_REFCURSOR )
AS
l_base_proc_ref_cursor SYS_REFCURSOR;
v_cursor_main enamelist := enamelist ();
BEGIN
SELECT ename
BULK COLLECT
INTO v_cursor_main
FROM emp;
OPEN p_ref_cursor
FOR SELECT * FROM TABLE(v_cursor_main);
END;
SQL> var emp_dtls refcursor
SQL> execute get_control_ref_cursor(:emp_dtls);
PL/SQL procedure successfully completed.
SQL> print emp_dtls;
COLUMN_VALUE
SMITH
ALLEN
WARD
JONES
MARTIN
BLAKE
CLARK
SCOTT
KING
TURNER
ADAMS
COLUMN_VALUE
JAMES
FORD
MILLER
14 rows selected.
SQL> -
I have a very big function with many union alls (around 4000 line code) which returns a refcursor, I need to display summary info of this function and I am using another function to accomplish this.In second function I am declaring a refcursor and calling first one into it but how can I summarize the result(group)? the way I know is 1)loop through the cursor 2) copy the existing and add a group by clause to it.
Is there another way to group the result of a refcrusor ?
Eg:
My first function returns like this
Empno Deptno Sal
1234 10 1000
1235 10 1000
1236 10 1000
1237 20 2000
1238 20 2000
1239 20 2000I need to display
Dept count sum(sal)
10 3 3000
20 3 6000Thanks,
Hesh.See if a pipelined function will work for you.
SQL> create or replace type emp_obj as object (empno integer, deptno integer, sal integer)
2 /
Type created.
SQL> create or replace type emp_tbl as table of emp_obj
2 /
Type created.
SQL> create or replace function emp_sal_info return emp_tbl pipelined
2 as
3 rc sys_refcursor;
4 lempno integer;
5 ldeptno integer;
6 lsal integer;
7 begin
8 open rc for select empno, deptno, sal from emp;
9
10 loop
11 fetch rc into lempno, ldeptno, lsal;
12 exit when rc%notfound;
13
14 pipe row(emp_obj(lempno, ldeptno, lsal));
15 end loop;
16
17 close rc;
18
19 return;
20 end;
21 /
Function created.
SQL> select deptno, count(empno), sum(sal)
2 from table(emp_sal_info)
3 group by deptno
4 /
DEPTNO COUNT(EMPNO) SUM(SAL)
30 6 9400
20 5 10875
10 3 8750
SQL> -
Help in using record type and object type
Hi Experts,
I am new to object types and record types.
I want to return the output of this query using one OUT parameter
from the procedure using RECORD type or OBJECT type.
with out using refcursor.
SELECT empno,ename,sal FROM emp WHERE deptno=30;
Let us assume the query is returning 50 records.
I want to send those 50 records to OUT parameter using record type or object type.
Please provide the for the requirement code using RECORD TYPE and OBJECT TYPE separately.
Your earliest response is appreciated.
Thanks in advance.Hi All,
I have tried this.But it ising not work
CREATE OR REPLACE PACKAGE maultiplevalues_pkg
IS
TYPE t_record IS RECORD
(empno emp.empno%TYPE,
ename emp.ename%TYPE,
sal emp.sal%TYPE);
V_RECORD t_record;
TYPE t_type IS TABLE OF V_RECORD%TYPE;
PROCEDURE maultiplevalues_pROC(p_deptno IN emp.deptno%TYPE,
dept_result OUT t_type);
END;
CREATE OR REPLACE PACKAGE body maultiplevalues_pkg
IS
PROCEDURE maultiplevalues_pROC(p_deptno IN emp.deptno%TYPE,
dept_result OUT t_type)
is
begin
dept_result :=t_type();
for I in(
select EMPNO,ENAME,SAL from EMP WHERE deptno=p_deptno
LOOP
dept_result.extend;
dept_result(i).empno :=i.empno;
dept_result(i).ename :=i.ename;
dept_result(i).sal :=i.sal;
END LOOP;
END;
END;
Please help me OUT return multiple values through single OUT variable in a procedure.
Thanks. -
SELECT VALUES FROM OBJECT TYPES
Hi
I want to select values in a object types in a table over the database link.
like
select name from [email protected]
where name is of type varray of varchar2(100)
and db.com is database link.
It is giving me error ORA-22804.
Oracle supports this or not?SQL> var a refcursor
SQL> declare
2 bb emp%ROWTYPE;
3 begin
4 select * into bb from emp where rownum = 1;
5 open :a for select bb.ename ename, bb.empno empno from dual;
6 end;
7 /
PL/SQL procedure successfully completed.
SQL> print a
ENAME EMPNO
SMITH 7369Rgds. -
Calling a storedprocedure returning refcursor of xmltype
Hi,
I'm having issues with stored procedure, returning a refcursor of xmltypes. Most of the examples in the docs(http://docs.oracle.com/html/E10927_01/featXML.htm#i1012109) are always a direct query and I have yet to see one using a stored procedure.
Here's a repro script:
Register an xsd:
BEGIN
dbms_xmlschema.registerschema('http://www.testing.com/person.xsd',
'<?xml version = "1.0" encoding = "utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="first_name" type="xs:string"/>
<xs:element name="last_name" type="xs:string"/>
<xs:element name="gender">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="male"/>
<xs:enumeration value="female"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>',
LOCAL => FALSE, -- local
GENTYPES => FALSE, -- generate object types
GENBEAN => FALSE, -- no java beans
GENTABLES => TRUE, -- generate object tables
FORCE => FALSE,
options => dbms_xmlschema.register_binaryxml,
OWNER => USER );
END;
--create a array of int type
CREATE OR REPLACE
type int_array_type as table of number;
-- Create the table
CREATE TABLE person
ID NUMBER,
xml_document XMLTYPE
xmltype column xml_document STORE AS BINARY XML XMLSCHEMA "http://www.testing.com/person.xsd" element "person";
-- insert some data
INSERT INTO person (ID, xml_document)
VALUES (1, XMLTYPE ('<?xml version="1.0" encoding="utf-8"?>
<person xsi:noNamespaceSchemaLocation="http://www.testing.com/person.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<first_name>John</first_name>
<last_name>Doe</last_name>
<gender>male</gender>
</person>'));
INSERT INTO person (ID, xml_document)
VALUES (2, XMLTYPE ('<?xml version="1.0" encoding="utf-8"?>
<person xsi:noNamespaceSchemaLocation="http://www.testing.com/person.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<first_name>Jane</first_name>
<last_name>Doe</last_name>
<gender>female</gender>
</person>'));
Create the Package
create or replace
package test_pkg as
TYPE refcursor IS REF CURSOR;
type t_id_array is table of number index by binary_integer;
-- user procs
procedure udp_get_personlist (
p_ids IN t_id_array,
p_resultset out refcursor );
end test_pkg;
create or replace
package body test_pkg as
procedure udp_get_personlist (
p_ids IN t_id_array,
p_resultset out refcursor ) IS
v_int_array_type int_array_type := int_array_type();
begin
FOR i IN 1..p_ids.COUNT LOOP
v_int_array_type.extend(1);
v_int_array_type(i) := p_ids(i);
END LOOP;
OPEN p_resultset FOR
SELECT E.XML_DOCUMENT AS "person" FROM person E
WHERE e.ID IN ( SELECT t.COLUMN_VALUE FROM TABLE ( v_int_array_type ) t );
end udp_get_personlist;
end test_pkg;And here is my ODP.NET code
using (var con = new OracleConnection("<your oracle connection>"))
using (var cmd = con.CreateCommand())
cmd.CommandText = "test_pkg.udp_get_personlist";
cmd.CommandType = CommandType.StoredProcedure;
int[] ids = new int[] { 1, 2 };
OracleParameter param1 = cmd.Parameters.Add("p_ids", OracleDbType.Int32);
OracleParameter param2 = cmd.Parameters.Add("p_resultset", OracleDbType.RefCursor, ParameterDirection.Output);
param1.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
param1.Value = ids;
param1.Size = ids.Length;
param1.ArrayBindSize = new int[] { 4, 4 };
// Setup the ArrayBind Status for param2
param1.ArrayBindStatus = new OracleParameterStatus[1] { OracleParameterStatus.Success }; //, OracleParameterStatus.Success };
try
cmd.XmlQueryProperties.MaxRows = 1;
con.Open();
XmlReader r = cmd.ExecuteXmlReader(); // this always generates invalidoperationexception
// do something with the result
catch (Exception)
throw;
// Close and Dispose OracleConnection object
con.Close();
con.Dispose();
} Server/Tools information:
Oracle is Standard - Oracle Database 11g Release 11.2.0.1.0 running on Windows Server 2003 Std
ODP.NET (ie Oracle.DataAccess.DLL is 4.112.3.0);
Visual Studio 2010 Ultimate SP1
Any pointers in what I'm (obviously doing wrong) is greatly appreciated...
thanks
Edited by: 947266 on Sep 10, 2012 9:46 AMWas able to make it work
using (var con = new OracleConnection("<your oracle connection>"))
using (var cmd = con.CreateCommand())
cmd.CommandText = "test_pkg.udp_get_personlist";
cmd.CommandType = CommandType.StoredProcedure;
int[] ids = new int[] { 1, 2 };
OracleParameter param1 = cmd.Parameters.Add("p_ids", OracleDbType.Int32);
OracleParameter param2 = cmd.Parameters.Add("p_resultset", OracleDbType.RefCursor, ParameterDirection.Output);
param1.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
param1.Value = ids;
param1.Size = ids.Length;
param1.ArrayBindSize = new int[] { 4, 4 };
// Setup the ArrayBind Status for param2
param1.ArrayBindStatus = new OracleParameterStatus[1] { OracleParameterStatus.Success }; //, OracleParameterStatus.Success };
try
cmd.XmlQueryProperties.MaxRows = 1;
con.Open();
int i = cmd.ExecuteNonQuery();
OracleRefCursor curs = (OracleRefCursor)cmd.Parameters["p_resultset"].Value;
OracleDataReader dr = curs.GetDataReader();
while (dr.Read())
Console.WriteLine(dr[0].ToString());
catch (Exception)
throw;
// Close and Dispose OracleConnection object
con.Close();
con.Dispose();
} -
Populate collection from function using refcursor
Hello,
I have a question about table functions.
I'm looking to develop a table function that populates a collection based on a select query. The idea is that the user can pass 1+ variable to a select query in the table function and return a collection of data dependent on the variables they choose, as:
create type a1 is object (col1 varchar2(1000), col2 varchar2(1000), col3 varchar2(1000));
--varchar2(1000) used for simplicity
create type a2 is table of a1;
create or replace
function a3(p in varchar2)
return a2
is
mycollection a2:= a2();
myparam varchar2(10):= p;
begin
select a1(topic,null,info)
bulk collect into mycollection
from help
where topic = myparam;
return mycollection;
end;
This executes fine using
select * from table(a3('ACCEPT'));
but when I try to write this using a ref cursor instead (even though it might be less efficient) I can't work out how to return multiple columns in a function. I appreciate this is hopelessly wrong, and suspect I'm nowhere near populating type mycollection a2, but:
create or replace function a4(p in varchar2)
return a2
is
mycollection a2:=a2();
myparam varchar2(10):=p;
c_cursor sys_Refcursor;
begin
open c_cursor for select seq,info,topic from help where topic = myparam;
loop
fetch c_cursor into mycollection;
exit when c_cursor%notfound;
end loop;
close c_cursor;
return mycollection;
end;
This does not execute using
select * from table(a4('ACCEPT'));
and returns
ORA-06504: PL/SQL: Return types of Result Set variables or query do not match
ORA-06512: at "SYSTEM.A4", line 14
06504. 00000 - "PL/SQL: Return types of Result Set variables or query do not match"
*Cause: Number and/or types of columns in a query does not match declared
return type of a result set variable, or declared types of two Result
Set variables do not match.
*Action: Change the program statement or declaration. Verify what query the variable
actually refers to during execution.
Could anyone show me how me how to populate a collection using a refcursor instead of bulk collect? Am using 11GR2.
Thanks,
TP,I'm looking to develop a table function that populates a collection based on a select query.
That is pretty much the definition of a PIPELINED function.
-- type to match emp record
create or replace type emp_scalar_type as object
(EMPNO NUMBER(4) ,
ENAME VARCHAR2(10),
JOB VARCHAR2(9),
MGR NUMBER(4),
HIREDATE DATE,
SAL NUMBER(7, 2),
COMM NUMBER(7, 2),
DEPTNO NUMBER(2)
-- table of emp records
create or replace type emp_table_type as table of emp_scalar_type
-- pipelined function
create or replace function get_emp( p_deptno in number )
return emp_table_type
PIPELINED
as
TYPE EmpCurTyp IS REF CURSOR RETURN emp%ROWTYPE;
emp_cv EmpCurTyp;
l_rec emp%rowtype;
begin
open emp_cv for select * from emp where deptno = p_deptno;
loop
fetch emp_cv into l_rec;
exit when (emp_cv%notfound);
pipe row( emp_scalar_type( l_rec.empno, LOWER(l_rec.ename),
l_rec.job, l_rec.mgr, l_rec.hiredate, l_rec.sal, l_rec.comm, l_rec.deptno ) );
end loop;
return;
end;
select * from table(get_emp(20))
In this example the user would provide a 'DEPTNO' value and the query (at the end) would return the rows of the EMP table for that value.
You can use your own TYPEs and add other parameters as needed.
See 'Using Pipelined and Parallel Table Functions in the Data Cartridge Dev Guide
http://docs.oracle.com/cd/B28359_01/appdev.111/b28425/pipe_paral_tbl.htm
And see all of the sections dealing with Pipelined functions in the PL/SQL dev guide
http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/tuning.htm#sthref1525
Maybe you are looking for
-
How to use it with gift card?
Dear Sir, My niece bought the Apple TV to me, but I could not use it because I do not know how to install. My friend said it does not support in my country, Thailand. I have wifi and rounter to play internet. Please advise me how to install. Also,
-
Low resolution pictures in Safari macbook pro vs Google Chrome
I have both Safari (7.0.5) and Google Chrome (35.0.1916.153) on my MacBook Pro Retina running OSX 10.9.4. Viewing my galleri my pictures show in much lower resolution (but not pixelated) in Safari compared to Chrome. It's the same on my iPad. The fir
-
Help downloading Elements 11 to MAC with OSX 10.6.8
I purchased Elements 11 and have attempted to download it several times. When I get a notification the download is complete, I am asked if I would like to open PhotoshopElements_11_WWEFDJ.exe. When I click "open" all I get is a dialogue box full of
-
Moving profile to a new computer
I grabbed the files needed to save passwords and bookmarks (cert8.db, cookies.sqlite, key3.db, permissions.sqlite, places.sqlite, signons.sqlite). I went to download but could not find where they went. No folder seemed to have profiles. Where do they
-
Version 2.0 is not a compatible version error with synch manager
i've build a synch plugin and i put the dll files in the plug in directory. when im running the synch plugin and im looking through the logs i get the following error "Version 2.0 is not a compatible version." i think the problem could happen because