|
-
Aug 3rd, 2010, 01:32 PM
#1
Have you worked with Oracle Pipelined functions?
I am facing an issue trying to use variable binding with a pipeline function in Oracle. I am using ODP .NET for connecting to the database.
If you want to be familiar with PIPELINED functions, you can read this blog.
I have very similar code with a difference. My function takes in two parameters that I need to pass to get the table. This is working in SQLPLUS without any issues.
In my C# code, however things change. My function no longer returns a recordset (data reader), if I use the standard method of assigning the parameters.
The code will work if I concat the variables in a string.
Here is the example that doesn't work.
c# Code:
static OracleDataReader fetchData(OracleConnection oc, string strPONumber)
{
try
{
OracleCommand od = oc.CreateCommand();
od.CommandType = System.Data.CommandType.Text;
od.CommandText = "select * from table(pkg_fetchPOInfo.getPORowsTable(:1,:2))";
OracleParameter op1 = new OracleParameter();
op1.ParameterName = "1";
op1.OracleDbType = OracleDbType.Varchar2;
op1.Direction = System.Data.ParameterDirection.Input;
op1.Size = 7;
op1.Value = strPONumber;
od.Parameters.Add(op1);
OracleParameter op2 = new OracleParameter();
op2.ParameterName = "2";
op2.OracleDbType = OracleDbType.Varchar2;
op2.Direction = System.Data.ParameterDirection.Input;
op2.Size = 3;
op2.Value = "US";
od.Parameters.Add(op2);
OracleDataReader or = od.ExecuteReader();
return or;
}
catch (Exception e)
{
Console.WriteLine("Error " + e.ToString());
return null;
}
}
Here is the example that does.
c# Code:
static OracleDataReader fetchData(OracleConnection oc, string strPONumber)
{
try
{
OracleCommand od = oc.CreateCommand();
string formSQL = "Select * from table(pkg_fetchPOInfo.getPORowsTable('"+strPONumber+"','US'))";
od.CommandType = System.Data.CommandType.Text;
od.CommandText = formSQL;
OracleDataReader or = od.ExecuteReader();
return or;
}
catch (Exception e)
{
Console.WriteLine("Error " + e.ToString());
return null;
}
}
Everything that has a computer in will fail. Everything in your life, from a watch to a car to, you know, a radio, to an iPhone, it will fail if it has a computer in it. They should kill the people who made those things.- 'Woz'
save a blobFileStreamDataTable To Text Filemy blog
-
Aug 4th, 2010, 07:35 AM
#2
Re: Have you worked with Oracle Pipelined functions?
No error message written to console?
-
Aug 4th, 2010, 12:27 PM
#3
Re: Have you worked with Oracle Pipelined functions?
 Originally Posted by leinad31
No error message written to console?
Yes, there is an error code being returned.
The error being returned is ORA-22905: cannot access rows from a non-nested table item.
Everything that has a computer in will fail. Everything in your life, from a watch to a car to, you know, a radio, to an iPhone, it will fail if it has a computer in it. They should kill the people who made those things.- 'Woz'
save a blobFileStreamDataTable To Text Filemy blog
-
Aug 4th, 2010, 07:07 PM
#4
Re: Have you worked with Oracle Pipelined functions?
Might as well post code of pipeline function
-
Aug 4th, 2010, 08:54 PM
#5
Re: Have you worked with Oracle Pipelined functions?
The function is part of a package. The function looks something like this.
sql Code:
create or replace package pkg_fetchPOInfo is
TYPE PO_HEADER_ROW IS RECORD
( PO_ID INT, --Reference field
PO_NUMBER VARCHAR2(22), --Reference field
BRANCH_ID VARCHAR2(3), -- Contains the Operating Unit Id.
PARTY_NAME VARCHAR2(200), --Could contain VENDOR or MANUFACTURER
DATE_ORDERED DATE,
UNIT_NUMBER VARCHAR2(6), --reference to unit number.
UNIT_HEIGHT NUMBER(15),
UNIT_WIDTH NUMBER(15),
UNIT_LENGTH NUMBER(15),
AMOUNT NUMBER(22,2)
);
TYPE PO_ROWS_TAB IS TABLE OF PO_HEADER_ROW;
function getPORowsTable(iPO_NUMBER IN VARCHAR2, iCountryCode IN VARCHAR2) return PO_ROWS_TAB pipelined;
end pkg_fetchPOInfo;
/
CREATE OR REPLACE PACKAGE BODY pkg_fetchPOInfo
IS
function getPORowsTable(iPO_NUMBER IN VARCHAR2, iCountryCode IN VARCHAR2) return PO_ROWS_TAB
pipelined
is
v_row PO_HEADER_ROW;
cursor curGetPOInfo is
SELECT * FROM get_POMANU_VW_US WHERE po_number = iPO_NUMBER;
begin
if iCountryCode = 'US' then
begin
for x_rec in curGetPOInfo
loop
v_row.PO_ID := x_rec.po_id;
v_row.PO_NUMBER := x_rec.po_number;
v_row.PARTY_NAME := x_rec.MFG_NAME;
v_row.DATE_ORDERED := x_rec.ordered_date;
v_row.BRANCH_ID := x_rec.gl_branch; --Fin Org Unit code.
v_row.UNIT_NUMBER := x_rec.unit_number;
v_row.UNIT_HEIGHT := x_rec.unit_length;
v_row.UNIT_LENGTH := x_rec.unit_length;
v_row.UNIT_WIDTH := x_rec.unit_WIDTH;
v_row.AMOUNT := x_rec.po_amount;
pipe row ( v_row );
end loop;
return;
end;
else
begin
--Stub for other countries.
null;
end;
end if;
end getPORowsTable;
end; /*Always mark the package end*/
/
Everything that has a computer in will fail. Everything in your life, from a watch to a car to, you know, a radio, to an iPhone, it will fail if it has a computer in it. They should kill the people who made those things.- 'Woz'
save a blobFileStreamDataTable To Text Filemy blog
-
Aug 6th, 2010, 01:53 AM
#6
Re: Have you worked with Oracle Pipelined functions?
What's strange is that it works in some scenarios, it shouldn't work at all... you didn't use sys_refcursor, nor database scope types (you declared within package, type not in all_types view).
It may be client-side SQL parsing related since it runs in sqlplus... check version of libraries you are using to connect to oracle database. Make sure it is the latest version.
-
Aug 6th, 2010, 08:44 AM
#7
Re: Have you worked with Oracle Pipelined functions?
A variation works for me. The variation is to wrap the function in a stored proc that returns a REFCURSOR. The I use the SYSREFCURSOR datatype to fetch the output.
I suppose, the only option for me is to use wrap this function with a stored procedure.
Everything that has a computer in will fail. Everything in your life, from a watch to a car to, you know, a radio, to an iPhone, it will fail if it has a computer in it. They should kill the people who made those things.- 'Woz'
save a blobFileStreamDataTable To Text Filemy blog
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|