PL/SQL cursor-collection  related query

Hi all,
I have a function which will take a collection (table of numbers) as a input argument.
Each id in the collection corresponds to a set of columns.I need to return a cursor which will contain the resultsets for all the ids in the collection.How do i do it.
what should the query be ?
say each id has three columns a,b,c to be returned.
I am given the collection of ids and am supposed to return a cursor which will have a,b,c columns for all the ids.
For individual ids , its straight forward
select a,b,c from sometable where id=input_id.
But how do i construct the cursor given a collection of ids?
Thanks in advance.

Hi,
Please see the below example:
SQL>CREATE TABLE T ( ID NUMBER(2),a NUMBER(2),b NUMBER(2),c NUMBER(2));
Table created.
SQL>SELECT * FROM t;
        ID          A          B          C
         1         12         13         15
         2         21         31         51
2 rows selected.
SQL>
Use the below query to create your cursor :
SQL>SELECT a,b,c FROM t tb1,  TABLE( TBL_TYPE(1,2)) tb2 WHERE tb1.id = tb2.column_value;
         A          B          C
        12         13         15
        21         31         51
2 rows selected.
SQL>Regards

Similar Messages

  • XSU - Maximal number of cursor in a query -(Typelength exceeds max value)

    Hi,
    Is there a way to increase the maximal number of cursors in a OracleXMLQuery object in XSU?
    I have an object splitted in more than 50 tables and I need more than 50 cursors in order to get the whole object as XML.
    XSU is giving me an error each time I try to get more than 50 cursors in a query:
    <ERROR>oracle.xml.sql.OracleXMLSQLException: Typlaenge groesser als Hoechstwert</ERROR>
    (sorry it is german, it means something like Typelength exceeds the maximal value)
    It would be great if someone knows, I tried everything.
    Cheers,
    Diego

    Hi,
    Go to context related method of Search view
        - redifine method DO_INIT_CONTEXT, before redifine copy the existing code.
        - Add the same code to your redfined method and specify the no of max hits required.
        - if this is a custom application you can find the code in Standard Search applications like Quotation/Sale Order etc
    Sample code :
    method DO_INIT_CONTEXT.
      data:
       lv_cnode type ref to cl_bsp_wd_context_node_asp,
       lr_qs    type ref to cl_crm_bol_dquery_service.
      field-symbols: <qs_name> type crmt_ext_obj_name.
    set flag for later intialization in DO_PREPARE_OUTPUT
      me->set_init_qs( abap_true ).
    check if QS already exist
      lv_cnode = get_dquery_cnode( ).
      lr_qs ?= lv_cnode->collection_wrapper->get_first( ).
      if lr_qs is not bound.
      add empty QS in order to allow application to prefill values
        assign lv_cnode->('BASE_ENTITY_NAME') to <qs_name>.
        lr_qs = cl_crm_bol_dquery_service=>get_instance( <qs_name> ).
        lv_cnode->collection_wrapper->add( lr_qs ).
      endif.
    Initialize maximum hits parameter if not yet set
      data: data_ref type ref to data.
      field-symbols: <max_hits> type i.
      data_ref = lr_qs->get_property( iv_attr_name = 'MAX_HITS' )."#EC NOTEXT
      assign data_ref->* to <max_hits>.
      if data_ref is not bound or <max_hits> = 0.
        data: max_hits_default type i.
        max_hits_default = 20000. "cl_crm_ui_parameter_util=>get_search_max_hits( ).
        lr_qs->set_property( iv_attr_name = 'MAX_HITS'
                                iv_value = max_hits_default ).  "#EC NOTEXT
      endif.
    Comment out this code as you might get error for this.
    register for change of dquery service
    set handler on_dquery_changed for lv_cnode->collection_wrapper.
    set handler on_config_data_changed.
    endmethod.
    Thanks,
    Aniket
    Edited by: Aaniket Korde on Dec 14, 2009 11:54 PM

  • Returning SQL cursor from Stored Procedure

    Hi,
    I have a query regarding returning sql cursor from stored procedure to java in oracle 11g.
    I want to query some data ex: my query returns A, B, C. Also, now I want to query some other data ex: D, E, F. Now I want to return this data as an sql cursor as a single row . Example: A,B,C,D,E,F. Is it possible to return/create a cursor in stored procedure?
    assume both query returns equal number of rows.. however both are not related to each other..

    RP wrote:
    Hi,
    I have a query regarding returning sql cursor from stored procedure to java in oracle 11g.
    I want to query some data ex: my query returns A, B, C. Also, now I want to query some other data ex: D, E, F. Now I want to return this data as an sql cursor as a single row . Example: A,B,C,D,E,F. Is it possible to return/create a cursor in stored procedure?
    assume both query returns equal number of rows.. however both are not related to each other..It sounds like what you need is a ref cursor.
    First thing to remember though is that cursors do not hold any data (see: {thread:id=886365})
    In it's simplest form you would be creating a procedure along these lines...
    SQL> create or replace procedure get_data(p_sql in varchar2, p_rc out sys_refcursor) is
      2  begin
      3    open p_rc for p_sql;
      4  end;
      5  /
    Procedure created.
    SQL> var rc refcursor;
    SQL> exec get_data('select empno, ename, deptno from emp', :rc);
    PL/SQL procedure successfully completed.
    SQL> print rc;
         EMPNO ENAME          DEPTNO
          7369 SMITH              20
          7499 ALLEN              30
          7521 WARD               30
          7566 JONES              20
          7654 MARTIN             30
          7698 BLAKE              30
          7782 CLARK              10
          7788 SCOTT              20
          7839 KING               10
          7844 TURNER             30
          7876 ADAMS              20
          7900 JAMES              30
          7902 FORD               20
          7934 MILLER             10
    14 rows selected.
    SQL> exec get_data('select deptno, dname from dept', :rc);
    PL/SQL procedure successfully completed.
    SQL> print rc
        DEPTNO DNAME
            10 ACCOUNTING
            20 RESEARCH
            30 SALES
            40 OPERATIONS
            50 IT SUPPORTWhich takes an SQL statement (as you said that both your queries were unrelated), and returns a ref cursor, and then your Java code would fetch the data using that cursor.
    Now, as for getting your rows to columns and combining two queries that do that... something along these lines...
    SQL> select * from x;
    C
    A
    B
    C
    SQL> select * from y;
    C
    D
    E
    F
    SQL> ed
    Wrote file afiedt.buf
      1  select x.col1, x.col2, x.col3
      2        ,y.col1 as col4
      3        ,y.col2 as col5
      4        ,y.col3 as col6
      5  from (
      6        select max(decode(rn,1,col1)) as col1
      7              ,max(decode(rn,2,col1)) as col2
      8              ,max(decode(rn,3,col1)) as col3
      9        from (select col1, rownum rn from (select * from x order by col1))
    10       ) x
    11  cross join
    12       (
    13        select max(decode(rn,1,col1)) as col1
    14              ,max(decode(rn,2,col1)) as col2
    15              ,max(decode(rn,3,col1)) as col3
    16        from (select col1, rownum rn from (select * from y order by col1))
    17*      ) y
    SQL> /
    C C C C C C
    A B C D E F... will do what you ask. For further information about turning rows to columns read the FAQ: {message:id=9360005}

  • Sending email using PL/SQL based on a query result

    Hello all,
    I want to create a procedure using PL/SQL, based on a query result.Here is the scenario:
    I have multiple tables in Target and Source databases that I want to compare(not the whole table but queries on these tables) and if they differ, I want to shoot an email. I have some ideas how to implement this but not sure whether it is the best approach.
    select Acct_id, total from SourceTableA
    minus
    select Acct_id, total from TargetTableA
    select Acct_id, sum from SourceTableB
    minus
    select Acct_id, sum from TargetTableB
    If the result of any of above queries > 0 then I want to shoot an email and want to repeat this procedure in the morning every day.
    I know how to implement send_mail procedure using UTL_SMTP package and how to schedule tha job by dbms_job package. But I am not sure how to implement the result of minus query. In case if minus > 0 then I also want to send the name of tables in the email message where source and target tables are not same. Should i use cursor, variable or insert the result in a new table? any help would be highly appreciated. Thanks in advance.
    Khan

    Actually these queries are the part of our daily testing that we run everyday manually(after the scheduled ETL load) to see if there are any discrepencies between our datawarehouse tables and source tables. So instead of running these queries manually everyday we want to schedula a procedure that will shoot an email in case of any discrepency and indicate which tables have problems.

  • Need help on Dynamic SQL Cursor in Forms

    Hi All,
    I am trying to execute Dynamic SQL Cursor in forms using EXEC_SQL built in.
    I have a cursor for example:
    'select * from supplier where supplier = '||p_supplier||' and processing_order = '||p_order
    My code is
    cur_num := Exec_SQL.Open_cursor;
    sql_order := 'select * from supplier where supplier = '||p_supplier||' and processing_order = '||p_order;
    EXEC_SQL.PARSE(cursor_number, sql_order);
      EXEC_SQL.DEFINE_COLUMN(cur_num ,1,ln_Supp_Id);
      EXEC_SQL.DEFINE_COLUMN(cur_num ,2,ls_Suppl_Name,30);
    EXEC_SQL.DEFINE_COLUMN(cur_num ,24,ls_exchange,20);
      sql_count := EXEC_SQL.EXECUTE(cur_num );
      While EXEC_SQL.FETCH_ROWS(cur_num ) > 0 Loop
            EXEC_SQL.COLUMN_VALUE(cur_num ,1,ln_Supp_Id);
            EXEC_SQL.COLUMN_VALUE(cur_num ,2,ls_Suppl_Name);
            EXEC_SQL.COLUMN_VALUE(cur_num ,24,ls_exchange);
    End Loop;
    EXEC_SQL.CLOSE_CURSOR(cur_num );
    In this case I have to write 24 Define Columns and 24 Column value. Is there any way to assign them to %rowtype at one time as I need all coulmn of the table.
    I had similar case on multiple tables.
    Please help me
    Thanks,
    Maddy

    I need this dynamic sql because p_supplier and p_order values changes at run time
    I do not understand. Is this a simplified sample or the real thing? You do know that you can pass variables to cursors:
    cursor test is
    select * from supplier where supplier = p_supplier and processing_order = p_order;
    or does e.g. p_supplier hold other parts of the query?
    cheers

  • SQL Query ( PL/SQL function body returning query ) page

    Hello Friends,
    I have a page with type SQL Query ( PL/SQL function body returning query ).
    I have written a pl/sql block that returns a sql query - select statment.
    Some times i am getting no data found error - does it got to do with the variable that stores the query .
    =======================
    ORA-06502: PL/SQL: numeric or value error: character string buffer too small
    Error ERR-1101 Unable to process function body returning query.
    OK
    =====================
    When the query is returned with records where exactly the records are stored is it in the variable declared in pl/sql block or with the Oracle Apex implicit cursor.
    Here's the pl/sql block ..
    The query is generated while the user is navigating through pages ..
    ====================
    declare
    l_return_stmt varchar2(32767);
    l_select varchar2(32000);
    l_from varchar2(32000);
    l_where varchar2(32000);
    l_order_by varchar2(32000);
    l_stmt_recordcount varchar2(32000);
    l_recordcount number ;
    begin
    l_select := 'select '||:P10_VARLIST1||:P10_VARLIST2||:P10_VARLIST3
    ||:P10_VARLIST4||:P10_VARLIST5;
    l_from := ' from '||:P10_RELATION;
    if length(:P10_WHERE) > 0 then
    l_where := ' where '||:P10_WHERE;
    else
    l_where := '';
    end if;
    if length(:P10_ORDER_BY) > 0 then
    l_order_by := ' order by '||:P10_ORDER_BY;
    else
    l_order_by := '';
    end if;
    l_return_stmt := l_select||l_from||l_where||l_order_by;
    :P10_STMT := l_return_stmt;
    return l_return_stmt;
    end;
    =============================
    Appreciate your help in this regard.
    thanks/kumar
    Edited by: kumar73 on Apr 22, 2010 6:38 AM

    It looks like the query string you are trying to pass back exceeds the 32K limit for a varchar. Where this is happening is kind of difficult to tell as it could be any number of points, and also depends on what you are passing into the process via page items.
    I would first try to establish what combination of page items causes this error to occur. Then, starting from the bottom and working your way backwards, I would start 'switching off' some of the items you use to build your query until it breaks again, thus establishing which part is leading to the error.
    Also, I'm not sure what :P10_STMT is doing (are you maybe using this for visiblity of the query created)?
    It looks like the query string you are trying to pass back exceeds the 32K limit for a varchar. Where this is happening is kind of difficult to tell as it could be any number of points, and also depends on what you are passing into the process via page items.
    I would first try to establish what combination of page items causes this error to occur. then, starting from the bottom and working your way backwards, I would start 'switching off' some of the items you use to build your query until it breaks again, thus establishing which part is leading to the error.
    Also, I'm not sure what :P10_STMT is doing (are you maybe using this for visiblity of the query created)?

  • Size of PL\SQL Cursor block

    I want to know the internal working of the PL\SQL Cursor. Lets start with a scenario.
         1) I have 3 table with 20 million records each.
         2) I am making a join out of them on a certain condition which gives me 60 million records, now I am putting them in a cursor.
    Questions :
         i) Can the Oracle PL\SQL Cursor is capable of holding that much records or there is any limit for it ?
         ii) If there is a limit for such block, then where can I find it and how can I set it ?
         3) If there is no such limit, then running such a query and holding all the data in the Cursor Block would degrade the performance. How Oracle handles such situations, It might be possible that Oracle only have the indexes of those records in the Cursor, but still it would be to time consuming to index 3 different table
    Kindly Inform me about this issue ....
    Thanks & regards
    - Nabil Shams

    1. Oracle PL/SQL cursor is just a handle to shared SQL area in Oracle SGA and as such does not consume an awful lot of memory (I would dare to say it consumes peanuts). What is more important it does not depend on number of rows you are going to fetch via cursor
    2. Therefore the answer to question 2 is NO
    3. Running the query could and would affect you in most unpleasnat ways if you tried to store results of the query in your process memory (PGA/UGA), or more specifically if you created PL/SQL indexed by table and tried to pack all 60000000 rows into it.
    If you fetch rows one by one, process the row, throw it away - then no problem... but what do you need to do it for?

  • Need a column based off a PL/SQL cursor, how to do this?

    Oracle9i Enterprise Edition Release 9.2.0.8.0 - 64bit Production
    With the Real Application Testing option
    JServer Release 9.2.0.8.0 - Production
    Report Builder 10.1.2.2.0
    ORACLE Server Release 10.1.0.5.0
    Oracle Procedure Builder 10.1.2.2.0
    Oracle ORACLE PL/SQL V10.1.0.5.0 - Production
    Oracle CORE     10.1.0.5.0     Production
    Hi,
    I am trying to create a fairly basic report but in the initial data model query, I have one column that is built based off of a PL/SQL cursor. How do I add this into my report? I have tried to create a function under Program Units and reference the function in my select statement for the data model however it keeps saying it is an invalid identifier, and I assume its looking in our database and not the function I created inside the report.
    This is what it looks like:
    SELECT   a.id,
             b.name,
             F_GET_GENERIC_NAME(b.code) "Generic Name",
             c.strength...and the function i want it to use in my report:
    FUNCTION F_GET_GENERIC_NAME (in_code varchar2) RETURN VARCHAR2 IS
    BEGIN
    DECLARE
    generic_name table.column%TYPE;
    CURSOR cs_get_generic_name IS
    SELECT /*+ USE_HASH (AR) */ desc
    FROM  a_ref AR, ai_ic AC    
    WHERE AC.code = in_code
    AND   AC.code = AR.code
    ORDER BY sort_nbr;
    BEGIN
           generic_name := '';
              FOR v_get_generic_name IN cs_get_generic_name
              LOOP
                 generic_name := generic_name || RTRIM(v_get_generic_name.desc)
                                     || '/' || ' ';
              END LOOP;
              generic_name := SUBSTR(generic_name, 1,(NVL(LENGTH(generic_name), 0) - 2));
    RETURN generic_name;
    END;
    END;
        Any suggestions? Should I just create the function in the database?

    I am trying to do it through a formula column but am encountering the following problem.
    I've created a formula column in my data model where I want the column to be (inside the group).
    Inside the PL/SQL for the column I reference the function that I had previously created with the following:
    function CF_Generic_nameFormula return Char is
    begin
         F_GET_GENERIC_NAME(:code);
    end;However it won't let me compile, giving the error that "F_GET_GENERIC_NAME is not a procedure or is undefined." Is there something else that I am missing?
    EDIT: Nevermind, i missed something simple like putting a return in front of the function call.
    Edited by: a small rabbit on Nov 3, 2009 10:43 AM
    Edited by: a small rabbit on Nov 3, 2009 10:44 AM

  • At what point is PL/SQL cursor data retrieved?

    Hi
    This may sound like a silly question but since I am not entirely sure, I thought I'd ask.
    In Oracle PL/SQL, do you know at what stage the query in a cursor is actually executed?
    Is it at the DECLARE stage or when you first OPEN / LOOP on it?
    I suspect upon the OPEN or the LOOP.
    I.e. if I had a cursor declared but did not loop (using FOR .. LOOP) through it for some hours, would the query results be as at the time of declare or as at the time of the OPEN / FOR...LOOP?
    E.g.
    CURSOR invoices
      IS
        SELECT invoice_number
        FROM unpaid_invoices
        WHERE due_date < TRUNC (SYSDATE)
    BEGIN
    -- Some time consuming processing that will take an hour
    -- Start Loop through cursor of invoices.
      <<overdue_invoices>>
      FOR inv IN invoices LOOP
    -- Some processing on the invoice
      END LOOP overdue_invoices;
    END;Would the cursor details for invoices be as at the CURSOR declaration or when the FOR inv... is reached?
    Thanks
    Martin

    When you use a for loop like that it implicitly opens the cursor at the start and closes it at the end of the loop.
    But the SQL query in that cursor is actually "run" when the first implicit or explicit fetch is issued, and retrieves new rows for every subsequent fetch.
    Of course, before rows can be retrieved there needs to be several other tasks.
    There's a good description of the steps of SQL processing in this part of the documentation.
    http://download.oracle.com/docs/cd/E11882_01/appdev.112/e10471/adfns_sqlproc.htm
    PL/SQL implicitly declares a cursor for all SQL data manipulation statements, including queries that return only one row. For queries that return multiple rows, you can explicitly declare a cursor to process the rows individually.
    A cursor is a handle to a specific private SQL area. In other words, a cursor can be thought of as a name for a specific private SQL area. A PL/SQL cursor variable enables the retrieval of multiple rows from a stored subprogram.Edited by: fsitja on Dec 15, 2009 1:03 AM

  • SQL Cursors HELP  ASAP

    I need somebody to help me with sql cursors, in JSP.
    This is my peace of code what is wrong with it?
              Statement stmt = myConn.createStatement();
              stmt.executeQuery("BEGIN WORK");
              stmt.executeQuery("DECLARE item_cursor CURSOR FOR SELECT user_name FROM admin_info");
              stmt.executeQuery("FETCH 10 FROM item_cursor");
              ResultSet rs = stmt.getResultSet();
              while(rs.next()){
                   if(rs.getString(1) != null){
                        user_name = rs.getString(1).trim();
    %><P><%= user_name %></P><%
              stmt.executeQuery("CLOSE item_cursor");
              stmt.executeQuery("COMMIT WORK");
    and this is the error that a get: No results where returned by the query
    Please help anybody
    thanx guys

    If you are using ORACLE drivers and classes.
    This sample program shows Oracle JDBC REF CURSOR functionality, creating a PL/SQL package that includes a stored function that returns a REF CURSOR type. The sample retrieves the REF CURSOR into a result set object.
    * This sample shows how to call a PL/SQL function that opens
    * a cursor and get the cursor back as a Java ResultSet.
    import java.sql.*;
    import java.io.*;
    import oracle.jdbc.driver.*;
    class RefCursorExample
    public static void main (String args [])
    throws SQLException
    // Load the driver
    DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
    // Connect to the database
    // You can put a database name after the @ sign in the connection URL.
    Connection conn =
    DriverManager.getConnection ("jdbc:oracle:oci8:@", "scott", "tiger");
    // Create the stored procedure
    init (conn);
    // Prepare a PL/SQL call
    CallableStatement call =
    conn.prepareCall ("{ ? = call java_refcursor.job_listing (?)}");
    // Find out all the SALES person
    call.registerOutParameter (1, OracleTypes.CURSOR);
    call.setString (2, "SALESMAN");
    call.execute ();
    ResultSet rset = (ResultSet)call.getObject (1);
    // Dump the cursor
    while (rset.next ())
    System.out.println (rset.getString ("ENAME"));
    // Close all the resources
    rset.close();
    call.close();
    conn.close();
    // Utility function to create the stored procedure
    static void init (Connection conn)
    throws SQLException
    Statement stmt = conn.createStatement ();
    stmt.execute ("create or replace package java_refcursor as " +
    " type myrctype is ref cursor return EMP%ROWTYPE; " +
    " function job_listing (j varchar2) return myrctype; " +
    "end java_refcursor;");
    stmt.execute ("create or replace package body java_refcursor as " +
    " function job_listing (j varchar2) return myrctype is " +
    " rc myrctype; " +
    " begin " +
    " open rc for select * from emp where job = j; " +
    " return rc; " +
    " end; " +
    "end java_refcursor;");
    stmt.close();

  • Understanding SQL cursor attributes

    I was trying to understand the use of SQL cursor attributes.So i chose sql%notfound attribute to be used with an exception in the below example.
    create or replace procedure checkExcp
    is
    v_empName varchar2(30);
    exp_no_row_found exception;
    errorMessage varchar2(500);
    begin
    select ename into v_empName from emp where empno = '8000';
    if sql%notfound then
         raise exp_no_row_found ;
    end if;
    exception
    when exp_no_row_found
    then
      errorMessage := 'Error occured while executing updateInventoryTotalsInDB function: ';
    end;When i debugged this proc i realized that the
    if sql%notfound then
         raise exp_no_row_found ;bit of the code(and the custom exception exp_no_row_found) is useless. Because when no rows are returned by the query
    select ename into v_empName from emp where empno = '8000';it straightaway goes to the exception block bypassing the 'if sql%notfound....' bit. So when is a SQL cursor attribute like sql%notfound useful?

    But i want to add specific error messages to each
    SELECT...INTO statements. So a single,common
    NO_DATA_FOUND exception would mask these specific
    errors.Then don't make it a single, common exception block. Have specific execution blocks with their own exception block for each different way you want to handle the exception e.g.
    BEGIN
      BEGIN
        SELECT mydata INTO myvar FROM mytable;
      EXCEPTION
        WHEN NO_DATA_FOUND THEN
          myvar := 'No data for myvar';
      END;
      BEGIN
        SELECT myotherdata INTO myvar2 FROM mytable;
      EXCEPTION
        WHEN NO_DATA_FOUND THEN
          myvar2 := 'No data for myvar2';
      END;
    END;Nested execution blocks are your friend when you want to handle exceptions for specific areas.

  • Building report from PL/SQL cursor

    Hello,
    is there any way to build APEX report using just PL/SQL cursor?
    I don't have grant to SELECT from views or tables, but I can use some functions returning row types and cursors. I know I can use them to build table from scratch with htp.p etc., but it’s not very nice. I want to do it using APEX reporting with filtering and pagination functionality.
    Is it possible?
    Regards,
    Przemek

    Apologies for the delay, I was out of the office.
    Below is a package serving as the basis for creating a view based on a pipelined function. The package is just a skeleton and will not compile in its current form, you will need to go through it filling in the blanks as described by the comments.
    If you want some control over what rows are returned by the view from a larger result set, use the set_parameters function in the WHERE clause, E.G.:
    select * from really_big_complicated_slow_view where 1 = view_pkg.set_parameters(something_that_reduces_the_view_result_set_size);
    Or, a more concrete example:
    select result_text from view_to_convert_to_csv where 1 = view_pkg.set_parameters(pi_table => 'my_table', pi_where = 'whatever');
    In the spirit of full disclosure, I got the idea for using the "set_parameters" function in the view WHERE clause from a post or blog somewhere a couple of years ago but have lost track of who actually deserves the credit for the good idea.
    -Tom
    create or replace package demo_vw as
    -- Package to serve as the basis for a view based on a function
    -- Customize this record so that it represents a row from this view...
    type row_type is record (
    -- record fields here
    type table_type is table of row_type;
    -- This function is used in the DDL to define the view, for example:
    -- create or replace view my_view (col1, col2, ..., colN) as
    -- select * from table(my_view_vw.get_view);
    function get_view
    return table_type
    pipelined;
    -- Customize this function header to accept the parameters for this view, if
    -- any. If this view does not require any parameters, the set_parameters
    -- function may be deleted.
    -- This function should always return 1 and is called as follows
    -- select <whatever>
    -- from my_view
    -- where 1 = my_view_vw.set_parameters(p1, p2, p3, ..., pN);
    function set_parameters (pi_whatever1 in whatever,
    pi_whateverN in whatever)
    return number;
    end demo_vw;
    show error package demo_vw
    create or replace package body demo_vw as
    -- Customize this list of private global variables to match the parameters
    -- required by the view. These variables are set, reset, and validated by
    -- set_parameters, reset_parameters, and valid_parameters respectively...
    g_var1 whatever;
    g_varN whatever;
    function set_parameters (pi_whatever1 in whatever,
    pi_whateverN in whatever)
    return number
    is
    -- Customize this function header to accept the parameters for this view, if
    -- any. If this view does not require any parameters, the set_parameters
    -- function may be deleted.
    -- This function should always return 1 and is called as follows
    -- select col1, col2, ..., colN
    -- from my_view
    -- where 1 = my_view_vw.set_parameters(p1, p2, p3, ..., pN);
    begin
    g_var1 := pi_whatever1;
    g_varN := pi_whateverN;
    return 1;
    end set_parameters;
    function valid_parameters
    return boolean
    is
    -- Customize...
    -- Assumes that set_parameters has been called to set the value of the view
    -- parameters.
    l_valid boolean := true;
    begin
    return l_valid;
    end valid_parameters;
    procedure reset_parameters
    is
    -- Customize...
    -- This is called at the end of the get_view function to reset the view
    -- parameters for the next caller.
    begin
    g_var1 := null;
    g_varN := null;
    end reset_parameters;
    function get_view
    return table_type
    pipelined
    is
    -- build and return each row for the view...
    l_row row_type;
    begin
    if valid_parameters then
    -- do your process to populate the l_row variable here...
    pipe row (l_row);
    end if;
    reset_parameters;
    exception
    when others then
    reset_parameters;
    raise;
    end get_view;
    end demo_vw;
    show error package body demo_vw
    create or replace view demo
    as
    select * from table(demo_vw.get_view);

  • Implicit PL/SQL cursors remain open, causing ORA-01000 (Client 9.2.0.1)

    Hello,
    since migrating our system from Oracle Client 9.0.X to 9.2.0.1 (Windows XP), i am encountering troubles when calling a stored procedure from a Cobol-Program:
    after a while i run into a 'Maximum open cursors exceeded'-message (ORA-01000)
    The stored procedure returns a cursor (ref_cursor)
    When Executing the stored procedure, there are actually 2 cursors involved, in fact the stored PL/SQL procedure implicitely opens a child-cursor when doing a select within the PL/SQL.
    After fetching the result and closing the cursor in my cobol-program, it correctly closes the cursor associated with the stored-procedure, but it does not close the cursor that was implicitely opened by oracle.
    After a while i am running into a Maximum open cursors message, because those cursors have not properly been closed.
    Here's a simple PL/SQL package that illustrates the problem:
    create or replace package scott.SCOTTS_PACKAGE is
    type ref_cursor IS REF CURSOR;
    function GET_EMP(EMP_IN CHAR) return ref_cursor;
    end SCOTTS_PACKAGE;
    create or replace package body scott.SCOTTS_PACKAGE is
    -- Function and procedure implementations
    function GET_EMP(EMP_IN CHAR) return ref_cursor is
    MyCurs ref_cursor;
    begin
    OPEN MyCurs FOR
    SELECT EMPNO ,
    ENAME ,
    JOB
    FROM SCOTT.EMP
    WHERE ENAME = EMP_IN;
    return(MyCurs);
    end;
    end SCOTTS_PACKAGE;
    Here are some exerpts from my cobol program:
    (The program iterates 100x through the section that executes the PL/SQL. After each iteration an additional open cursor remains in the database)
    003800 EXEC SQL BEGIN DECLARE SECTION END-EXEC.
    003900*
    004000 01 SQL-USERNAME PIC X(16) VARYING.
    004100 01 SQL-PASSWD PIC X(16) VARYING.
    004200 01 SQL-DBNAME PIC X(64) VARYING.
    004300 01 ORACLE.
    004700 02 ORA-CUR-EMP SQL-CURSOR.
    01 EMPREC.
    02 EMPREC-EMPNO PIC X(4).
    02 EMPREC-ENAME PIC X(10).
    02 EMPREC-JOB PIC X(9).
    005400 EXEC SQL END DECLARE SECTION END-EXEC.
    018400 PROCEDURE DIVISION.
    CONTINUE.
    018700 EXEC SQL
    018800 WHENEVER SQLERROR DO PERFORM SQL-ERROR
    018900 END-EXEC.
    019000*
    CONTINUE.
    019100 EXEC SQL
    019200 WHENEVER NOT FOUND DO PERFORM SQL-NOT-FOUND
    019300 END-EXEC.
    022400 EXEC SQL
    022500 ALLOCATE :ORA-CUR-EMP
    022600 END-EXEC
    PERFORM VARYING I FROM 1 BY 1 UNTIL I > 100
    ACCEPT DUMMY FROM TER
    IF DUMMY = "E"
    MOVE 100 TO I
    END-IF
    PERFORM GET-EMP
    ADD 1 TO I
    END-PERFORM
    119300 GET-EMP SECTION.
    119400************************
    119500 GAM0.
    MOVE SPACES TO EMPREC-EMPNO EMPREC-JOB
    MOVE "SMITH" TO EMPREC-ENAME
    120200 EXEC SQL AT SSSI EXECUTE
    120300 BEGIN
    120400 :ORA-CUR-EMP:=
    120500 SCOTT.SCOTTS_PACKAGE.GET_EMP(:EMPREC-ENAME );
    120900
    END;
    121000 END-EXEC
    121200 IF DB-ERR-CODE NOT = HIGH-VALUE
    121300 DISPLAY "CCSIFSO:GET-AUTRE-MATR:APPEL PERS... OK"
    121400 EXEC SQL
    121500 FETCH :ORA-CUR-EMP
    121600 INTO
    121700 :EMPREC-EMPNO,
    121800 :EMPREC-ENAME,
    121900 :EMPREC-JOB
    122400 END-EXEC
    122500 END-IF
    122600*
    122700 IF DB-ERR-CODE NOT = HIGH-VALUE
    122800 DISPLAY "CCSIFSO:GET-AUTRE-MATR:APPEL FETCH.. OK"
    123000 ELSE
    123100 MOVE LOW-VALUE TO DB-ERR-CODE
    123200 END-IF
    123300 EXEC SQL
    123400 CLOSE :ORA-CUR-EMP
    123500 END-EXEC
    123600 GA-EX.
    123700 EXIT.
    124000 SQL-NOT-FOUND SECTION.
    124100*----------------------
    124200 NF0.
    124300 DISPLAY "CCSIFSO:SQL-NOT-FOUND SECTION."
    124400 MOVE HIGH-VALUE TO DB-ERR-CODE.
    124500 NF-EX.
    124600 EXIT.
    124700*
    124800 SQL-ERROR SECTION.
    124900*-----------------
    125000 ER0.
    125200 EXEC SQL
    125300 WHENEVER SQLERROR CONTINUE
    125400 END-EXEC
    125700 MOVE HIGH-VALUE TO DB-ERR-CODE
    125800*
    126100 DISPLAY "ORACLE ERROR DETECTED: " SQLCODE UPON TER
    126200 DISPLAY SQLERRMC UPON TER
    126300*
    126400 EXEC SQL AT SSSI
    126500 ROLLBACK WORK
    126600 RELEASE
    126700 END-EXEC
    126800 DISPLAY "----------------------------" UPON TER
    126900 DISPLAY " ! ROLLBACK ET DISCONNECT ! " UPON TER
    127000 DISPLAY "----------------------------" UPON TER
    127200 CALL "PPTERMJ".
    127400 ER-EX.
    127500 EXIT.
    Finally here's an exerpt from V$OPEN_CURSOR, after a few iterations:
    1 begin :b1 := SCOTT . SCOTTS_PACKAGE . GET_EMP (:b2 ) ; END ;
    2 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
    3 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
    4 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
    5 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
    6 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
    7 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
    8 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
    9 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
    10 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
    11 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
    As you see, there is only 1 cursor starting with 'begin ... '
    but there are 10 implicit cursors 'SELECT EMPNO, ... ' that have not been properly closed, nor reused by ORACLE.
    In our old configuration (ORACLE CLient 9.0.X), you would only see:
    1 begin :b1 := SCOTT . SCOTTS_PACKAGE . GET_EMP (:b2 ) ; END ;
    2 SELECT EMPNO , ENAME , JOB FROM EMP WHERE ENAME = :B1
    meaning all the other cursors have properly been closed.
    As a conclusion: the program correctly closes the implicit cursors when using a 9.0 Client, wheras the implicit cursors remain open on Client 9.2.0.1 (Windows XP)
    The underlying database can be either 8.i or 9, the problem remains the same.
    Finally here's a small Delphi code, using ODAC-components, that somewhat illustrates the same problem:
    procedure TForm1.ExecProcClick(Sender: TObject);
    var I: INTEGER ;
    begin
    FOR I := 1 TO 5 DO
    BEGIN
    SP1.StoredProcName:='SCOTT.SCOTTS_PACKAGE.GET_EMP';
    SP1.Prepare;
    SP1.ParamByName('EMP_IN').AsString := 'SMITH';
    SP1.ExecProc;
    SP1.Next;
    SP1.Close;
    SP1.UnPrepare;
    END;
    end;
    After each call to 'PREPARE', an additional implicit cursor remains open on the database. (using Oracle Client 9.2.0.1)
    On our old system (Oracle Client 9.0 or 8.X), the same program would not generate accumulating open cursors on the database
    Any suggestions would be welcome,
    Claude

    Cobol.. been many years since I last even saw some Cobol source code. Invokes all kinds of memories. :-)
    Since you found the patch, the advice is superfluous, but works. Close the cursor at the PL/SQL side, e.g.
    create or replace procedure CloseRefCursor( cRefCursor TYPELIB.TRefCursor ) is
    begin
      close cRefCursor;
    exception when OTHERS then
      -- if the cursor is already gone, not a problem
      NULL;
    end;In Delphi for example, one can subclass the class used for ref cursor calls and add a call to the above PL/SQL proc in the destructor. Or add create a standard Cobol close ref cursor section that does similar.

  • Error while executing Procedure - ORA-06511: PL/SQL: cursor already open

    I have successfully compiled the following procedure but when I execute it, following error occurs, please adv.
    Thanks and Regards,
    Luqman
    create or replace
    procedure TESTKIBOR
    (contno in varchar)
    AS
    BEGIN
    DECLARE cursor c1 is
    SELECT * FROM KIBOR_SCHEDULE
    WHERE CN=contno;
    begin
    OPEN C1;
    FOR line IN c1 LOOP
    update kibor_schedule
    set lincome=line.Lincome,
    expo=line.eXPO,
    pport=line.pPORT
    where cn=line.cn
    and rno=line.rno;
    END LOOP;
    COMMIT;
    close c1;
    END;
    END TESTKIBOR;
    ERROR at line 1:
    ORA-06511: PL/SQL: cursor already open
    ORA-06512: at "MKTG.TESTKIBOR", line 6
    ORA-06512: at "MKTG.TESTKIBOR", line 10
    ORA-06512: at line 1

    Hi,
    CREATE OR REPLACE PROCEDURE Testkibor
         (contno  IN VARCHAR)
    AS
    BEGIN
      DECLARE
        CURSOR c1 IS
          SELECT *
          FROM   kibor_schedule
          WHERE  cn = contno;
      BEGIN
    --//    OPEN c1; --no need to open if using for loop
        FOR line IN c1 LOOP
          UPDATE kibor_schedule
          SET    lincome = line.lincome,
                 expo = line.expo,
                 pport = line.pport
          WHERE  cn = line.cn
                 AND rno = line.rno;
        END LOOP;
        COMMIT;
    --//     CLOSE c1; -- no need for loop  does it for you
      END;
    END testkibor;SS

  • PL/SQL function in datamodel query

    Hi All,
    I have the following problem:
    I have a query Q1 returning a few rows. In the group G1 using this query Q1 i have a computed field returning a number NUM_1.
    select col_1, col_2 from table_1;
    So the output looks like:
    row 1 col_1 col_2 NUM_1_1
    row n col_1n col_2n NUM_1_n
    I want to order these rows by the calculated column NUM_1 the highest first.
    I know i can't order by a calculated column but can i do it by using a pl/sql function in the query to calculate the NUM_1?
    Like:
    select col_1, col_2, function(x) NUM_1 from table_1;
    And where should i create this function? Can it be done in the program unit section or do i have to create a library?
    Best regards,
    Snoesky

    Oke, i have created a break group on the calculated field.
    Ordering works fine now.
    I have an additional question:
    Is it possible to dynamically order this break (column) group? Meaning thru a parameter to tell the ordering to be descending or ascending.
    Regards,
    Snoesky

Maybe you are looking for