Return a Recordset in a PL/SQL
Hello All,
I'm attempting to write a PL/SQL statement over some very large tables. The processing of the statement takes over 45 minutes to complete.
I've been able to speed up processing by creating a temp table over the largest of the tables, and it truly has speed up processing. The problem is that this statement will be used in a report run from SQL Reporting Services, using PL/SQL. This will be used in various reports and would like to make this an adhoc type of job - launched by executing the report.
I've tried writing a procedure that returns a recordset, but I'm having no luck. I'm new to writing Stored Procedures, Functions and Packages, and am trying to get my head around the best way to approach this.
Here is what I have so far - and it's not even close to working, but you can see the logic I'm trying to follow as far was what I need to return.
CREATE OR REPLACE PACKAGE PKG_BillSegs_ZeroUsage AS
TYPE cursor_type IS REF CURSOR;
Procedure GETBILLSEG_ZEROUSAGE (
p_RevMth IN bi_bill_segment.rev_month%TYPE,
p_recordset OUT PKG_BillSegs_ZeroUsage.cursor_type);
END PKG_BillSegs_ZeroUsage;
CREATE OR REPLACE PROCEDURE GetBillSeg_ZeroUsage (p_RevMth IN bi_bill_segment.rev_month%TYPE,
p_recordset OUT PKG_BillSegs_ZeroUsage.cursor_type) AS
BEGIN
OPEN p_recordset FOR
select * from bi_bill_segment where usage_qty = 0 and rev_month = p_RevMth;
END GetBillSeg_ZeroUsage;
Any help is greatly appreciated!
Here's the output from explain plan - sorry for the output, but couldn't get it to be any prettier :
OPERATION OPTIONS OBJECT_NAME OBJECT_TYPE OPTIMIZER SEARCH_COLUMNS ID PARENT_ID POSITION COST CARDINALITY BYTES
SELECT STATEMENT REMOTE CHOOSE 0 91911 91911 2 4902
TABLE ACCESS BY INDEX ROWID BI_BILL_SEGMENT_T ANALYZED 1 0 1 91911 2 4902
INDEX RANGE SCAN BI_BILL_SEGMENT_IE7 NON-UNIQUE ANALYZED 1 2 1 1 659 178774
Similar Messages
-
How to test a procedure which returns a recordset from pl/sql
hello,
Is it possible to test a procedure which returns a recordset from pl/sql?
Everything I try results in errors like PLS-00382: expression is of wrong type, when I try to open the result cursor
or PLS-00221: tc is not a procedure or is undefined.
I created the following procedure:
CREATE OR REPLACE PACKAGE test AS
TYPE cursorType is REF CURSOR;
PROCEDURE test_cursor( tc IN OUT cursorType,
v_err OUT varchar2,
v_msg OUT varchar2);
END;
CREATE OR REPLACE
PACKAGE BODY test AS
PROCEDURE test_cursor
(tc IN OUT cursorType,
v_err OUT varchar2,
v_msg OUT varchar2)
AS
BEGIN
open tc for
SELECT '1' "number" FROM dual
union
select '2' "number" from dual;
v_msg := 'no errors';
v_err := 0;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
v_msg := 'no data found';
v_err := SQLCODE;
WHEN OTHERS
THEN
v_msg := SQLERRM;
v_err := SQLCODE;
END;
END;
I try to get the output from pl/sql with something like this:
DECLARE
TC PROVGRON.TEST.cursorType;
V_ERR VARCHAR2(200);
V_MSG VARCHAR2(200);
BEGIN
V_ERR := NULL;
V_MSG := NULL;
PROVGRON.TEST.TEST_CURSOR ( TC, V_ERR, V_MSG );
DBMS_OUTPUT.Put_Line('V_ERR = ' || V_ERR);
DBMS_OUTPUT.Put_Line('V_MSG = ' || V_MSG);
-- in tc I was hoping to hava a cursor??
FOR i IN tc
LOOP
DBMS_OUTPUT.PUT_LINE (i.number);
END LOOP;
END;
Without the for loop (or open tc) the pl/sql will output:
V_ERR = 0
V_MSG = no errors
PL/SQL procedure successfully completed.
With anything I try with the cursor I get errors?
What am I doing wrong?http://download.oracle.com/docs/cd/B19306_01/server.102/b14357/ch5.htm#sthref1122
-
Procedure to return a recordset in ASP.
I'll admint that my background is with MS SQL and Oracle is a bit different!
In SQL I can create a stored procedure that will return a recordset, filtered by the parameter that I pass to the procedure. Such as:
CREATE PROCEDURE sp_DriverList @BusCoID int
AS
SELECT DISTINCT ListName, DriverID
FROM T_Drivers
WHERE BusCoID = @BusCoID
ORDER BY ListName
In ASP I get back a list of all the Drivers for a given company, using the @BusCoID parameter.
When I try to implement this same method in Oracle 9i, I get an error. Can someone provide an example, comparable to the SQL version above, that would return a recordset?
Thanks!!!Your post will likely get a better response on the ODP.NET forum, but here's how I would do it.
CREATE OR REPLACE PACKAGE my_package
IS
TYPE refc IS REF CURSOR
RETURN t_drivers%ROWTYPE refc;
Function fetch_drivers(p_busid_in IN number);
END my package;
CREATE OR REPLACE PACKAGE BODY my_package
IS
Function fetch_drivers (p_busid_in IN number)
IS
l_curser refc;
BEGIN
OPEN l_cursor FOR
SELECT DISTINCT ListName, DriverID
FROM T_Drivers
WHERE BusCoID = p_busid_in
ORDER BY ListName;
RETURN l_cursor;
END fetch_drivers; -
Error: Current provider does not support returning multiple recordsets from a single execution
Hello,
The following piece of code which has been working for the
past five years suddenly started giving me the following error:
Current provider does not support returning multiple recordsets
from a single execution
We have recenlty moved this site to a new server. Could this
error be related to their CFAdmin settings? Eveything else on the
site seems to be working fine. Or am I using an outdated tag or
something?
Any light in this direction is appreciated, thanks.
Here's the code:There doesn't seem to be anything that seems wrong with the
code. It might have something to do with the Max Pooled Statements
or Number of Connections settings in the CF Administrator, but it
could just as easily have something to do with a setting on the
database. I would check with your provider. -
How to return a recordset (SQL)
I would like to know if it is possible to return a record set from a procedure and if so how?
Thanks in advance for any help.If you find out how to... could you please let me know it...
Thanks... I'm looking for the same thing.
my email: [email protected] -
Error executing Stored Procedure that returns a recordset in Visual Basic 6
Hello, i tried to use the example in the link posted as a response to my question in a previous thread, and in Visual Basic 6, when i execute the Stored procedure it gives me the following error:
This is the package created as indicated in the example FAQ you posted.
package types
as
type cursorType is ref cursor;
end;
This is the procedure created as indicated in the example FAQ you posted.
PROCEDURE SP_TITUVALO(T_BR IN VARCHAR2,
P_Cursor OUT TYPES.cursorType )
AS
BEGIN
OPEN P_Cursor FOR
SELECT * FROM TASAS WHERE BR=T_BR AND TASA > 0;
END;
This is the code used to execute the Stored Procedure in VB6:
Dim objConn As New ADODB.Connection
Dim connString
Dim cmdStoredProc As New ADODB.Command
Dim param1 As New ADODB.Parameter
Dim RS As ADODB.Recordset
Set param1 = cmdStoredProc.CreateParameter("T_BR", adVarChar, adParamInput, 255, "97")
cmdStoredProc.Parameters.Append param1
objConn.Open strconex
Set cmdStoredProc.ActiveConnection = objConn
cmdStoredProc.CommandText = "SP_TITUVALO"
cmdStoredProc.CommandType = adCmdStoredProc
Set RS = cmdStoredProc.Execute
This is the error returned:
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'SP_TITUVALO'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
****************************************************************Juan,
Not sure about FAQ you are referring to, but it seems that you need to set PLSQLRSet property of ADODB.Command to TRUE. Because if you fail to do so - errors with refcursors are likely to happen.
Consider:
Set objConn = CreateObject("ADODB.Connection")
objConn.ConnectionString = "Provider=OraOLEDB.Oracle;Persist Security Info=False;Data Source=test9ora;User ID=max;Password=blabla"
objConn.Open
'Dim cmdStoredProc
Set cmdStoredProc = CreateObject("ADODB.Command")
Dim param1
Set param1 = cmdStoredProc.CreateParameter("T_BR", adVarChar, adParamInput, 255, "97")
param1.Value = "X"
cmdStoredProc.Parameters.Append param1
'Dim RS
Set cmdStoredProc.ActiveConnection = objConn
'The following line was missed out
cmdStoredProc.Properties("PLSQLRSet") = True
cmdStoredProc.CommandText = "SP_TITUVALO"
cmdStoredProc.CommandType = adCmdStoredProc
Set RS = cmdStoredProc.ExecuteThis works fine, at least for me.
Cheers. -
Can a Fn return a recordset?
How do I have oracle store a SQL statement that can have params passed in, and have a recordset returned to user when executed? Is this done w/ a function?
For example, I want to store the following code:
create procedure/function/?? empname
IDNum as number
As
select empid, name
from emp
where empid = IDNum;
In the simple query above, I want to pass in a parameter when executing the above stored sql statement. When executed from the command line the syntax and result should be:
SQL> execute empname '4'
empid name
4 Bill Wojahowitz
Please help, and if possible can you show an example of syntax. Thanks in advance.
ChrisB
nullYou can create a procedure like this :
create or replace procedure empname(no in number) is
name varchar2(100);
begin
select ename into name from employee where empno=no;
dbms_output.put_line(no | | ' ' | |name);
end empname;
when u say execute empname(4) it will output the number and name.
set serveroutput on to show the result.
Hope this helps.
Take Care
Chandar -
Null consistently returned by RecordSet.getTimeStamp()
Hi
I'm continually getting 'null' being returned by the getTimeStamp(int) method from a ResultSet.
If I run the stored proc with the required parameters in SQL server, it returns values for the field. Its a DateTime field - so should return this when my code calls it, right?
Here is a snippet of the code:
try { conn = datasrc.getConnection(); cs = conn.prepareCall("{call rsp_employee_get(?,?)}"); cs.setInt(1, id); cs.setString(2, name); rs = cs.executeQuery(); if(rs.next()) { employee = new Employee(); employee.setManagerId(rs.getInt(1)); employee.setOccupationId(rs.getInt(2)); employee.setJobTitle(rs.getString(3)); employee.setPreferredName(rs.getString(4)); employee.setWorkedFromDate(rs.getTimestamp(5)); employee.setWorkedToDate(rs.getTimestamp(6)); //this is where my error occurs
All objects etc have been created correctly, and obviously above is only a snippet.
The proc returns values as expected, and rs.getTimestamp(5) works fine - however these dates all have the time 00:00:00.000 whereas the field getTimestamp(6) refers to have times of 23:59:59.000... (could this be it??)
The proc returns a list of employees off the database, past and present - so some do have null values for this field (ie they're current employees) - however, I've checked and its recording them all as null even though they're not null when I run the proc manually.
I'm getting a bit fed up with it to be honest, hoping someone here has seen it before and can see if I've done something wrong?On my production system the same query processes just fine...EXCEPT that the Recordset is "n/a".
Can you clarify what you mean by "n/a"?
I can't see how it would make a difference, but you should not hard-code dynamic values into you SQL statement, you should pass them as a parameter.
So it would seem that it's a CF problem... agree?
Nope. CF doesn't know or care about your SQL. All it does is pass it to the DB driver, and wait for the DB driver to return something to it.
That said, it might not be a problem with the call, it might be a problem with how it handles what it gets back, I suppose.
Running with that theory... I wonder if the change to the ORDER BY statement is coincidental, perhaps it's just that it bubbles to the top of the recordset something that CF doesn't like. Can you remove columns from you SELECT statement one by one, and see if at some point if starts returning data correctly?
Can you do a trace on the query and verify what the DB is receiving from the driver, and what it's sending back? I have no idea how to do that in SQLite, sorry.
Adam -
ADO Recordset Cache Size Breaking SQL Reads
I've got a C++ application that uses ADO/ODBC to talk to various databases using SQL.
In an attempt to optimize performance, we modified the Cache Size parameter on the Recordset object from the default Cache Size of 1 to a slightly larger value. This has worked well for SQL Server and Access databases to increase the performance of our SQL reads.
However, talking to our Oracle 8i (8.1.6 version) database, adjusting the Cache Size causes lost records or lost fields.
We've tried the same operation using a VB application and get similar results, so it's not a C++ only problem.
For the VB app, changing the cursor-type from ForwardOnly to Dynamic does affect the problem, but neither work correctly. With a ForwardOnly cursor the string fields start coming back NULL after N+1 reads, where N is the Cache Size parameter. With a Dynamic cursor, whole records get dropped instead of just string fields: for example with a Cache Size of 5, the 2nd, 3rd, 4th and 5th records are not returned.
In our C++ application, the symptom is always lost string fields, regardless of these two cursor types.
I've tried updating the driver from 8.01.06.00 to the latest 8.01.66.00 (8.1.6.6) but this didn't help.
Is anybody familiar with this problem? know any workarounds?
Thanks
[email protected]I am displaying you mine test db's buffer cache size : (11.2.0.1 on Windows box)
SQL> show parameter db_cache_size;
NAME TYPE VALUE
db_cache_size big integer 0
SQL> select name, current_size, buffers, prev_size, prev_buffers from v$buffer_pool;
NAME CURRENT_SIZE BUFFERS PREV_SIZE PREV_BUFFERS
DEFAULT 640 78800 0 0
SQL> select name,bytes from v$sgainfo where name='Buffer Cache Size';
NAME BYTES
Buffer Cache Size *671088640*
SQL> show sga;
Total System Global Area 1603411968 bytes
Fixed Size 2176168 bytes
Variable Size 922749784 bytes
*Database Buffers 671088640 bytes*
Redo Buffers 7397376 bytes
SQL> select * from v$sga;
NAME VALUE
Fixed Size 2176168
Variable Size 922749784
*Database Buffers 671088640*
Redo Buffers 7397376
SQL> show parameter sga_target;
NAME TYPE VALUE
sga_target big integer 0
SQL>Regards
Girish Sharma
Edited by: Girish Sharma on Oct 18, 2012 2:51 PM
Oracle and OS Info added. -
How to count the no of fields returned by recordset?
hi friends,
how can i know how many columns have been returned by the recordset
ex. rs.executeQuery("select * from table");
now how many columns r there in the table, can this be known?
thanx in advance,
VishalResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();ResultSetMetaData will provide you with a great deal of information about the ResultSet - check out the API here: http://java.sun.com/j2se/1.4.1/docs/api/java/sql/ResultSetMetaData.html
Hope this helps! -
SSRS - Oracle Stored procedure returns no data but does in SQL Developer Sudio
HI there,
Stored procedure returns no data when executed on the report but when i execute the stored procedure in Sql Developer it returns required rows.
Thanks for your help!Hi Simon,
When i test with simple query, i get the data.
For your convenience, my stored proc looks lyk :
PROCEDURE pr_REPORT_data(P_STARTDATE IN DATE, P_ENDDATE IN DATE, data_rows OUT T_CURSOR) AS
OPEN completed_Reinstatement FOR
SELECT
value1,.......value5
FROM table1
WHERE
To_Date(createdDate, 'YYYY/MM/DD') BETWEEN To_Date(P_STARTDATE, 'YYY/MM/DD') AND To_Date(P_ENDDATE, 'YYYY/MM/DD');
END pr_REPORT_data;
T_CURSOR is of type cursor which is declared on the package.
I'm assuming the problem is with date parameters, however i converted the date before passing to
WHERE clause. -
Returning collection-associative array from pl-sql procedure
CREATE OR REPLACE procedure test_ganesh( p_deptno IN number,gana out PARTIES_RESULT)
is
query varchar2(200);
PARTY_ID varchar2(200);
PARTY_CODE varchar2(200);
PARTY_NAME varchar2(200);
PARTY_SEQ VARCHAR2(200);
counter number;
TYPE PARTIES IS TABLE OF varchar2(2000) index by binary_integer;
txn_parties PARTIES;
type PARTIES_RESULT IS TABLE OF PARTIES index by binary_integer;
total_result PARTIES_RESULT;
TYPE EmpTyp IS REF CURSOR;
p_du EmpTyp;
p_cursor EmpTyp;
global_counter number;
begin
global_counter:=1;
counter:=1;
open p_cursor FOR
select A.ref_no
from ot_lc_txn_details A
where rownum <12;
LOOP
FETCH p_cursor INTO query;
EXIT WHEN p_cursor%NOTFOUND;
counter:=1;
open p_du FOR
select party_id,party_code,seq_no,party_name from ot_txn_party where ref_no=query;
LOOP
FETCH p_du INTO PARTY_ID,PARTY_CODE,PARTY_SEQ,PARTY_NAME;
EXIT WHEN p_du%NOTFOUND;
txn_parties(counter):=PARTY_ID || '&&&' || PARTY_CODE || '&&&'||PARTY_SEQ || '&&&' || PARTY_NAME;
counter:=counter+1;
END LOOP;
CLOSE p_du;
total_result(global_counter):=txn_parties;
global_counter:=global_counter+1;
END LOOP;
CLOSE p_cursor;
--open gana FOR SELECT * FROM table(cast(total_result as PARTIES_RESULT)) ;
end;
The error comes at line one, PLS-00905- object PARTIES_RESULT is invalid.
i have used the create type thing to create this type.
if i remove the out parameter it works, no compilation error.
Questions i) How to return the associative array as out parameter?
ii)Am i doing aynthing qrong here?
iii) Can i open a ref cursor to this associative array and then return that ref_cursor?
Please anyone reply back, Thanks in advance
Message was edited by:
user649602As an example:
SQL> create type PARTIES is table of varchar2(2000);
2 /
Type created.
SQL> create or replace procedure proc1(p_deptno number,gana out parties) as
2 begin
3 select ename
4 bulk collect into gana
5 from emp
6 where deptno = p_deptno;
7 end;
8 /
Procedure created. -
Obtaining a collection as a return from an execute immediate pl/sql block
version 10.2
I need to obtain the collection back from the execute immediate of a pl/sql block:
procedure block(owner varchar2) is
stmt long;
objecttab_coll dbms_stats.objecttab;
begin
stmt := '
begin
dbms_stats.gather_schema_stats(''' || owner || '''
,options => ''LIST AUTO''
,objlist => :objecttab_coll
end;';
execute immediate stmt returning into objecttab_coll;
-- do more stuff here
end block;I have tried this + a few variations but with no luck. In looking through the docs I do not see an example. can this be done?
Thanks
OxI dont find any need for an execute immediate here. This must be just enough.
procedure block(owner varchar2)
is
objecttab_coll dbms_stats.objecttab;
begin
dbms_stats.gather_schema_stats(ownname => owner, options => 'LIST AUTO', objlist => objecttab_coll);
-- do more stuff here
end block;Thanks,
Karthick. -
SSIS query returns no results - same query in SQL management studio works
Hello,
I'm running a very simple join to get a result set:
SELECT dbo.sap_contracts.svc_id, dbo.sap_contracts.svc_code, dbo.sap_contracts.quantity, dbo.sap_contracts.start_date, dbo.sap_contracts.end_date
FROM dbo.sap_contracts
INNER JOIN dbo.contracts
ON dbo.contracts.contract_id=dbo.sap_contracts.contract_id
where customer_name='XXXXXXXXX'
When I run this in SQL management studio it works fine and returns the list of existing "SAP contracts" in the DB (to compare to the customer's contracts actually in SAP).
In SSIS (SQL 2012) I'm using an Execute SQL task to run this query and putting the full results set into a variable of type "object". I've done very similar things before and it worked fine. With this query in SSIS I get no results at all. Changing
the variable type to "string" throws an error showing that the type being written to the variable is "DBNull" - so it seems that the query in SSIS returns no records, when in SQL management studio I get the 15 records that should be returned.
Does anyone have any ideas of what could be wrong?
Cheers
MarkThere are several connections to the DB in tasks before this one, and the task after this is a whole load of C# in a script task doing SOAP communications to the SAP ERP system to compare the result set from this SQL with the contracts in SAP ERP for the
specific customer.
Input variables are all correct (I've checked them about 15 times now with breakpoints on just about every task in the whole package) and I'm at the point of having to test everything in an attempt to see exactly what query is being sent to the SQL server
and anything else I can do to see why nothing comes back. There is a almost complete lack of debugging tools in SSIS which doesn't make life any easier (something I've heard quite a few times in various forums).
I'm tearing my hair out on this for half a day now and it's not funny any more, so apologies if I come across as a little frustrated.
Cheers
Mark -
Returning composite datatype(record) to an SQL Query
I have a function called get_customer_address() that takes customer id and returns the customer address as a record type.
TYPE cust_address_type IS RECORD
(address1 VARCHAR2(25),
address2 VARCHAR2(25),
city VARCHAR2(25),
zipcode VARCHAR(10),
STATE VARCHAR(10));
cust_address cust_address_type;
My function is returning cust_address.
I want to modify below exising query and call this function from the query to get address.
select cust_id, address1, address2, city, zipcode from customer_table;
Instead of using address1, address2, city, zipcode if I want to the record type variable cust_id returned from the function, can I use it in my query? How do I modify the above query to call the function get_customer_address and get the same values as in the above query?To add to Elic's comment - PL/SQL record structures can be defined as SQL objects, as long as SQL data types are used and not non-supported PL/SQL types like boolean.
E.g. create or replace type TCustAddress is object
( address1 VARCHAR2(25),
address2 VARCHAR2(25),
city VARCHAR2(25),
zipcode VARCHAR2(10),
state VARCHAR2(10)
);This provides a lot more flexibility than using PL/SQL record types. This is essentially an object class definition - and you can add constructors and methods to it.
It works seamlessly across both SQL and PL/SQL.
Maybe you are looking for
-
Since I installed FireFox 5.0 recently, when I open a new tab, it is just blank. My prior version of FireFox showed about 9 or so of the sites I visited most often. I never set this in the old version. It just worked that way. I loved it. I have no i
-
Adding a "static" image to selected gallery
Hi there, I've been working with the gallery with great success so far, but I'm stumped on trying to add another feature. As you can see in this example: http://www.thirstymango.com/troupehipnotica/mardi_screenshot.gif where the big red asterisk is,
-
Using WIA and its moronic default settings is like going back to being a caveman.
-
How to calculate term of aloan
Hi, Thank you in advance if you could help me. I need to write a trigger that will work out the terms of a loan. To do that I need a function that takes interest rate, number of payments and principal amount and return the term amount. Does such a fu
-
Issue with lost messages after updating....
I was wondering if anyone could shed some light on the following.... I recently (...regretfully) completed the software update to v 20.0.019 via PC suite...before the update I made a back up of ALL files onto my SD card, which according to my backup