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
    null

    You 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,
    Vishal

    ResultSetMetaData 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:
    user649602

    As 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
    Ox

    I 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
    Mark

    There 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