Sys_refcursor revisited

So, we're looking into using SYS_REFCURSOR in order to send the results of PL/SQL function into our reporting tool. Our initial tests worked great with an oversimplified example, and we started looking into planning a standardized approach.
Then, we were presented with a function which didn't fit into the examples I've seen to-date which involve a SYS_REFCURSOR. In our situation, cursors are used to gather the data, if/then statements transform the data, and then multiple rows are supposed to be sent back to the calling program. Since a SQL statement isn't used as the final step which gathers the data for the calling program, what do we use to return that data?
We could deposit the data in a GLOBAL TEMPORARY TABLE and use a SQL statement as the last step which draws everything from that table and returns it via a SYS_REFCURSOR. Or is there an alternative to pipe the data back directly?
--=Chuck

There is a basic flaw in this argument Charles - SQL is the language used to access the data in the database. Does not matter what you do in PL/SQL (or Java etc), it still needs to use the SQL language to get the data from the database.
And that is the point I often harp on. Using SQL as best possible.
Thus it is not a purist viewpoint - simply one that says use the best tool for the job. As SQL is the "data access language", it needs to do most of the work in getting the data out of the database and into the client (PL/SQL in this case).
Using PL./SQL does not mean now suddenly being able to process less data. Or being able to process the data faster or better.
It is like a balance scale. SQL for getting the absolute minimum data needed as efficiently as possible from the data. PL to crunch that data with minimal moving parts.
There are valid reasons for that performance gains you've stated. Simply saying that PL/SQL is the cause... I find that hard to believe. The major impact on performance is I/O. This is also the basic unit of cost that the CBO bases its decisions on.
Any significant performance increases are typically due to decreasing I/O.
The 2nd biggest factor is CPU. It could be that those unioned SQLs had some serious number crunching requirements (like calling a user defined PL/SQL function). It could be that function is now called from PL/SQL instead. A native call is a lot cheaper than a call that requires the SQL engine to perform context switching to the PL/SQL engine.
There are numerous factors here that could cause the problem.
In either case, it would seem that SQL was in the first place not correctly used. And that was the reason for the slow SQL performance.
Bottom line - we need to deal with facts here. Merely observing that the PL/SQL based solution now is faster than the SQL based solution, by no means imply that PL/SQL is necessarily better in this case than SQL. One need to identify what the problem was with the SQL based solution and how the PL./SQL based solution solved it - before making any conclusions as to how much more effective and better PL/SQL is in this case.

Similar Messages

  • Is there any provision to view the selected record using SYS_REFCURSOR?

    hi friends ,
    I was using SQL Server . now i am shifting to Oracle . so we are changing the Stored Procedures in SQLServer to Oracle SP's. I have given the structure of procedure given below . If possible , i want to see the output of select statement in the TOAD editor . If any body knows please help me
    CREATE OR REPLACE PROCEDURE PS_AON
    P_STATUS OUT VARCHAR2,
    P_CUR OUT SYS_REFCURSOR
    AS
    BEGIN
    OPEN P_CUR FOR
              select colum1,column2,column3 from Table 1;
    EXCEPTION
                   WHEN OTHERS THEN
                   P_STATUS:=SQLERRM;
    END;
    This is one of the model of stored procedures i am using . And the editor i am using is TOAD 7.3.0 and oracle 9i. Is there any provision to view the selected records by running this procedure in TOAD editor
    thanks & regards

    (assuming you have relatively recent version of TOAD).
    Write a small block to call the procedure (or use Toad's 'execute procedure' option) as in the example below. Note the ':' in front of 'v_cur_out'. When you run the block, TOAD will prompt you for a value / datatype for 'v_cur_out'. Ignore the value, set the datatype to 'Cursor' and click OK. The resultset (if any) will be displayed in the Data Grid window below.
    DECLARE
       v_status VARCHAR2 (32767);
    BEGIN
       ps_aon (v_status, :v_cur_out);
       DBMS_OUTPUT.PUT_LINE ('v_status => ' || v_status);
    END;
    /

  • CURSOR_ALREADY_OPEN and SYS_REFCURSOR

    Hi,
    I have noticed that you can open a sys_refcursor without closing it. A co-worker did it in a function and I complained it was not good practice and it would raise an error, but he told me I was wrong. I have tested it and it has worked, so I have lost the argument.
    And then I found nothing on Oracle literature about it. Did I miss something? Is it common knowledge?
    Thanks, Roger

    And then I found nothing on Oracle literature about it. Did I miss something? Is it common knowledge? It is documented behaviour: Opening a Cursor Variable:
    You need not close a cursor variable before reopening it. Note that consecutive OPENs of a static cursor raise the predefined exception CURSOR_ALREADY_OPEN. When you reopen a cursor variable for a different query, the previous query is lost.
    «

  • Calling a stored procedure with RAW and SYS_REFCURSOR

    How do you call a stored procedure with the following input and output parameters?
    create or replace PROCEDURE test
    v_col1 IN NUMBER DEFAULT NULL ,
    v_col2 IN VARCHAR2 DEFAULT NULL ,
    v_col3 IN RAW DEFAULT NULL ,
    v_vol4 IN DATE DEFAULT NULL,
    cv_1 IN OUT SYS_REFCURSOR
    OPEN cv_1 FOR
    SELECT
    lv_tmp1 aaaa ,
    lv_tmp2 bbbb,
    lv_tmp3 cccc
    FROM DUAL ;
    END;
    Edited by: 925963 on Apr 6, 2012 10:50 AM

    Did you try just declaring the vars?
    untested
    declare
      myCur SYS_REFCURSOR;
      myRaw RAW(4);
      BEGIN
        test (0, 0, myRaw, sysdate, myCur);
      END;

  • How to use  SYS_REFCURSOR as a table  in calling sp

    hi gurus,
    here i have 2 sp in which i m calling GET_OPREF inside GET_REFCALL. and in GET_REFCAL i want to use output cursou as a table .
    plz help me ....
    CREATE OR REPLACE PROCEDURE GET_OPREF
    (p_cursor OUT  SYS_REFCURSOR )
    is
    begin
    open p_cursor FOR
        select 10 amt from dual union all
        select  20 amt from dual union all
        select 30 amt from dual ;
    end GET_OPREF ;
    CREATE OR REPLACE PROCEDURE GET_REFCALL
    is
      c_cursor   SYS_REFCURSOR ;
      r_emp      get_2%rowtype ;
       v_tot int ;
    begin 
      GET_OPREF(c_Cursor);
    select sum (amt) into v_tot from c_Cursor;  -- *here i want to user cursor as a table*
        dbms_output.put_line(v_tot ); 
    end get_refcall ;Edited by: user12108669 on Dec 1, 2009 5:03 AM
    Edited by: user12108669 on Dec 1, 2009 5:09 AM

    After you run the procedure your cursor is open. You can fetch it right away and use it like you would use a regular cursor.
    SQL> set serveroutput on
    SQL> CREATE OR REPLACE PACKAGE type_pack AS
      2  type t_cur is ref cursor;
      3  type t_tab is table of number;
      4  END type_pack;
      5  /
    Package created.
    SQL> CREATE OR REPLACE procedure test_ref(cur_output out sys_refcursor) i
      2  begin
      3    open cur_output for
      4    with test as
      5      (select 1 num from dual
      6       union select 2 num from dual
      7       union select 3 num from dual)
      8      select num
      9        from test;
    10  end;
    11  /
    Procedure created.
    SQL> CREATE OR REPLACE procedure run_test is
      2    cur_test sys_refcursor;
      3    tab_cur type_pack.t_tab;
      4  begin
      5    dbms_output.put_line('running...');
      6    test_ref(cur_test);
      7    fetch cur_test bulk collect
      8      into tab_cur;
      9    for i in 1 .. tab_cur.count
    10    loop
    11    dbms_output.put_line(tab_cur(i));
    12    end loop;
    13  end;
    14  /
    Procedure created.
    SQL> exec run_test;
    running...
    1
    2
    3
    PL/SQL procedure successfully completed.
    SQL>

  • SYS_REFCURSOR takes more time than direct query execution

    I have a stored proc which has 4 inputs and 10 output and all outputs are sys_refcursor type.
    Among 10 ouputs, 1 cursor returns 4k+ records and all other cursors has 3 or 4 records and average 5 columns in each cursors. For this, it takes 8 sec to complete the execution. If we directly query, it gives output in .025 sec.
    I verified code located the issue with cursor which returns 4k+ only.
    The cursor opening from a temporary table (which has 4k+ records ) without any filter. The query which inserted into temporary is direct inserts only and i found nothing to modify there.
    Can anyone suggest, how we can bring the results in less than 3 sec? This is really a challenge since the code needs to go live next week.
    Any help appreciated.
    Thanks
    Renjish

    I've just repeated the test in SQL*Plus on my test database.
    Both the ref cursor and direct SQL took 4.75 seconds.
    However, that time is not the time to execute the SQL statement, but the time it took SQL*Plus in my command window to print out the 3999 rows of results.
    SQL> create or replace PROCEDURE TEST_PROC (O_OUTPUT OUT SYS_REFCURSOR) is
      2  BEGIN
      3    OPEN  O_OUTPUT FOR
      4      select 11 plan_num, 22  loc_num, 'aaa' loc_nm from dual connect by level < 4000;
      5  end;
      6  /
    Procedure created.
    SQL> set timing on
    SQL> set linesize 1000
    SQL> set serverout on
    SQL> var o_output refcursor;
    SQL> exec test_proc(:o_output);
    PL/SQL procedure successfully completed.
    Elapsed: 00:00:00.04
    SQL> print o_output;
      PLAN_NUM    LOC_NUM LOC
            11         22 aaa
            11         22 aaa
            11         22 aaa
            11         22 aaa
            11         22 aaa
    3999 rows selected.
    Elapsed: 00:00:04.75
    SQL> select 11 plan_num, 22  loc_num, 'aaa' loc_nm from dual connect by level < 4000;
      PLAN_NUM    LOC_NUM LOC
            11         22 aaa
            11         22 aaa
            11         22 aaa
            11         22 aaa
            11         22 aaa
            11         22 aaa
    3999 rows selected.
    Elapsed: 00:00:04.75
    That's the result I expect to see, both taking the same amount of time to do the same thing.
    Please demonstrate how you are running it and getting different results.

  • Open sys_refcursor for select from table variable?

    Hi,
    I've got a challenge for you! :-)
    I've got a procedure that has a lot of logic to determine what data should be loaded into a table variable. Because of various application constraints, i can not create a global temporary table. Instead, i'd like to create a table variable and populate it with stuff as i go through the procedure.
    The end result of the procedure is that i must be able to pass the results back as a sys_refcursor. This is a requirement that is beyond my control as well.
    Is there a way to make this sort of procedure work?
    Create Or Replace Procedure Xtst
    Mu_Cur In Out Sys_Refcursor
    Is
    Type Xdmlrectype Is Record (Col1 Varchar2(66));
    Type Xdmltype Is Table Of Xdmlrectype;
    Rtn Xdmltype;
    Begin
    Select Internal_Id Bulk Collect Into Rtn From Zc_State;
    open mu_cur for select col1 from table(rtn);
    end;
    11/42 PLS-00642: local collection types not allowed in SQL statements
    11/36 PL/SQL: ORA-22905: cannot access rows from a non-nested table item
    11/19 PL/SQL: SQL Statement ignored
    Show Errors;

    Not anything i'd want to personally implement.
    But for educational purposes only of course....
    create table this_will_be_gross
       column1 number,
       column2 varchar2(30)
    insert into this_will_be_gross values (1, 'begin the ugliness');
    insert into this_will_be_gross values (2, 'end the ugliness');
    variable x refcursor;
    ME_XE?
    declare
       Rtn sys.ODCIVARCHAR2LIST;
    BEGIN
       SELECT
          column1 || '-' || column2 Bulk Collect
       INTO
          Rtn
       FROM
          this_will_be_gross;
       OPEN :x FOR
       SELECT 
          regexp_substr (column_value, '[^-]+', 1, 1) as column1,
          regexp_substr (column_value, '[^-]+', 1, 2) as column2      
       FROM TABLE(CAST(rtn AS sys.ODCIVARCHAR2LIST));
    end;
    17  /
    PL/SQL procedure successfully completed.
    Elapsed: 00:00:00.09
    ME_XE?
    ME_XE?print :x
    COLUMN1                        COLUMN2
    1                              begin the ugliness
    2                              end the ugliness
    2 rows selected.
    Elapsed: 00:00:00.11In the above example i 'knew' that a hypen was a safe character to use to break up my data elements (as it would not be found anywhere in the data itself).
    I would strongly encourage you not to implement something like this. I realize it's tempting when you are working in strict environments where it can take a serious battle to get structures like temporary tables or SQL Types created, but that's really the proper approach to be taking.

  • Issue with sys_refcursor  in oracle  10.2.0.4.0

    hi,
    java is front end application and they want result set to be returned from oracle plsql, for simplicity i am writing code something like below.
    create or replace function fun () retrun sys_refcursor is
    tablename_cur sys_Refcursor;
    begin
    open tablename_cur for select statement;
    return tablename_cur ;
    end;
    its all looks good.. but my client IT person questioned me about not closing cursor..
    i feel it is good way of doing, not closing this type of cursor variable is fine i.e. tablename_cur in this case, does it cause any issues otherwise.. since i am about write not less 300+ such functions and would like to know on this if this is right practice or would it cuase any increase of opened cursor and never closed,.... therafter any performance issues..
    or any other good practive to perform the same task. .. please suggest..
    thanks in advance...

    knowledgespring wrote:
    I assume once sys_Refcursor returned all the rows it get closed automatically... i.e. fetched all the rows from it closes the sys_refcursor.. otherwise provide info.
    according to you, does it mean if they close result set they use in java would result close of sys_refcursor!!.. not before.. may be somthing like
    ResultSet rs = call oracle function which uses sys_refcursor
    rs.close --> does it close sys_refcursor .. (would it open till then??!!!)..
    java developers says we call functions written in oracle... and resultset to be returned.. (They are different team)..I don't know java, but it's correct, the consumer of the cursor is responsible for closing it.
    e.g.
    SQL> ed
    Wrote file afiedt.buf
      1  create or replace function test_rc return sys_refcursor is
      2    v_rc sys_refcursor;
      3  begin
      4    open v_rc for 'select * from emp';
      5    return v_rc;
      6* end;
    SQL> /
    Function created.
    SQL> var x refcursor;
    SQL> exec :x := test_rc();
    PL/SQL procedure successfully completed.
    SQL> print x;
         EMPNO ENAME      JOB              MGR HIREDATE          SAL       COMM     DEPTNO
          7369 SMITH      CLERK           7902 17/12/1980        800                    20
          7499 ALLEN      SALESMAN        7698 20/02/1981       1600        300         30
          7521 WARD       SALESMAN        7698 22/02/1981       1250        500         30
          7566 JONES      MANAGER         7839 02/04/1981       2975                    20
          7654 MARTIN     SALESMAN        7698 28/09/1981       1250       1400         30
          7698 BLAKE      MANAGER         7839 01/05/1981       2850                    30
          7782 CLARK      MANAGER         7839 09/06/1981       2450                    10
          7788 SCOTT      ANALYST         7566 19/04/1987       3000                    20
          7839 KING       PRESIDENT            17/11/1981       5000                    10
          7844 TURNER     SALESMAN        7698 08/09/1981       1500          0         30
          7876 ADAMS      CLERK           7788 23/05/1987       1100                    20
          7900 JAMES      CLERK           7698 03/12/1981        950                    30
          7902 FORD       ANALYST         7566 03/12/1981       3000                    20
          7934 MILLER     CLERK           7782 23/01/1982       1300                    10
    14 rows selected.Here, the "print" command of SQL*Plus uses the returned ref cursor to fetch the data back from the database, and when it's done it (behind the scenes) closes the cursor.
    Oracle can't keep track (or even possibly know) of whether a client consumer of a ref cursor has finished fetching the records. Just because all the records may have been fetched, the cursor itself remains open until closed as it contains information about the state of the cursor e.g. whether there is more data to fetch or not.
    {thread:id=886365}

  • How to view SYS_REFCURSOR output parameters in TOAD

    Hi Team,
    Here is my procedure which was compiled succesfully...
    procedure SLA_FAILURE_PR_SR(
    startdate_i IN DATE,
    enddate_i IN DATE,
    pacifictimezone_i IN VARCHAR2,
    extranet_user_i IN VARCHAR2,
    severity_i IN NUMBER,
    reportRC_o out sys_refcursor
    IS
    BEGIN
    logpkg.info ('Begin ramOpsReportSummaryPkg.SLA_FAILURE_PR_SR');
    open reportRC_o for
    SELECT
    customer "Client",
    case_id_ "Case ID",
    to_char(aradmin.datepkg.unixTimeToDate(create_time, 'PST', 'Y'),'MM-DD-YYYY HH12:MI:SS PM') "Created",
    to_char(aradmin.datepkg.unixTimeToDate(resolved_time, 'PST', 'Y'),'MM-DD-YYYY HH12:MI:SS PM') "Resolved",
    total_downtime__min_ "Down Time",
    assigned_to_group_ || ' ' || ASSIGNED_TO_INDIVIDUAL_ "Group Assigned",
    reason_for_missed_sla "Reason For Miss",
    assigned_to_group_ "Group That Missed",
    internal_mgmt_summary "Ops Mgmt summary",
    follow_up_proactive_actions "Follow-Up Proactive Actions"
    FROM aradmin.hpd_helpdesk
    WHERE
    create_time >= datepkg.dateToUnixTime(TO_DATE(startdate_i,'YYYY-MM-DD'),pacifictimezone_i)
    AND create_time < datepkg.dateToUnixTime(TO_DATE(enddate_i,'YYYY-MM-DD')+7,pacifictimezone_i)
    AND extranet_user=extranet_user_i
    AND severity = severity_i
    AND (MET_RESOLUTION_SLA_=0 or MET_CONTACT_SLA_=0);
    logpkg.info ('END ramOpsReportSummaryPkg.SLA_FAILURE_PR_SR');
    END SLA_FAILURE_PR_SR;
    --The query inside cursor is fetching results. but i couldnt get the results when i executed whole procedure.
    -- Can anyone help on this and give me the procedure how to execute it in toad. I am using oracle 10g and Toad 9.6 versions.

    In Toad type:
    BEGIN
        SLA_FAILURE_PR_SR(
                          DATE '02-01-2013', -- substitute with proper start date
                          DATE '02-18-2013', -- substitute with proper end date
                          'put pacifictimezone_i value',
                          'put extranet_user_i value',
                          1, -- substitute with proper severity
                          :ref_cur
    END;
    /Click on Execute/Compile Statement (green triangle). Variables dialog will pop-up. Choose variable type - cursor and direction out. Cursor content will be displayed in Data Grid pane (click on it to see results).
    SY.

  • Regular expression help to solve sys_refcursor for a record

    In reference to my thread Question on sys_refcursor with record type , I thought it can be solved differently. That is:
    I have a string like '8:1706,1194,1817~1:1217,1613,1215,1250'
    I need to do some manipulation using regular expressions and acheive some thing like
    select * from <table> where
    c1 in (8,1)
    and c2 in (1706,1194,1817,1217,1613,1215,1250);Is it possible using regular expressions in a single select statement?

    Hi,
    Clearance 6`- 8`` wrote:
    Your understanding is absolutely correct. But unfortunately it did not work Frank.
    SQL> SELECT COUNT (*)
    2    FROM (SELECT sp.*
    3            FROM spml sp, spml_assignment spag
    4           WHERE sp.spml_id = spag.spml_id
    5             AND spag.class_of_svc_id = 8
    6             AND spag.service_type_id IN (1706, 1194, 1817)
    7             AND spag.carrier_id = 4445
    8             AND NVL (spag.haulage_type_id, -1) = NVL (NULL, -1)
    9             AND spag.effdate = TO_DATE ('01/01/2000', 'mm/dd/yyyy')
    10             AND spag.unit_id = 5
    11             AND sales_org_id = 1
    12          UNION ALL
    13          SELECT sp.*
    14            FROM spml sp, spml_assignment spag
    15           WHERE sp.spml_id = spag.spml_id
    16             AND spag.class_of_svc_id = 1
    17             AND spag.service_type_id IN (1217, 1613, 1215, 1250)
    18             AND spag.carrier_id = 4445
    19             AND NVL (spag.haulage_type_id, -1) = NVL (NULL, -1)
    20             AND spag.effdate = TO_DATE ('01/01/2000', 'mm/dd/yyyy')
    21             AND spag.unit_id = 5
    22             AND sales_org_id = 1);
    COUNT(*)
    88
    SQL> SELECT COUNT (*)
    2    FROM spml sp, spml_assignment spag
    3   WHERE sp.spml_id = spag.spml_id
    4     AND spag.carrier_id = 4445
    5     AND NVL (spag.haulage_type_id, -1) = NVL (NULL, -1)
    6     AND spag.effdate = TO_DATE ('01/01/2000', 'mm/dd/yyyy')
    7     AND spag.unit_id = 5
    8     AND sales_org_id = 1
    9     AND REGEXP_LIKE ('8:1706,1194,1817~1:1217,1613,1215,1250',
    10                      '(^|~)' || spag.class_of_svc_id || ':'
    11                     )
    12     AND REGEXP_LIKE ('8:1706,1194,1817~1:1217,1613,1215,1250',
    13                      '(:|,)' || spag.service_type_id || '(,|$)'
    14                     );
    COUNT(*)
    140
    SQL> Edited by: Clearance 6`- 8`` on Aug 11, 2009 8:04 PMJust serving what you ordered!
    Originally, you said you were looking for something that produced the same result as
    where   c1 in (8, 1)
    and      c2 in (1706, 1194, 1817, 1217, 1613, 1215, 1250)that is, any of the c1s could be paired with any of the c2s.
    Now it looks like what you want is
    where     (     c1 = 8
         and     c2 IN (1706, 1194, 1817)
    or     (     c1 = 1
         and     c2 IN (1217, 1613, 1215, 1250)
         )that is, c1=8 and c2=1250 is no good; neither is c1=1 and c2=1706.
    In that case, try
    WHERE     REGEXP_LIKE ( s
                  , '(^|~)' || c1
                         || ':([0-9]+,)*'
                         || c2
                         || '(,|~|$)'
                  )

  • Output SYS_REFCURSOR when cursor structure is not known

    If i have a variable of type "SYS_REFCURSOR".
    This cursor will be passed to various procedures which open various recordset for that cursor, with various number of columns in cursor.
    How to output cursor all columns?
    1. Maybe java will have metadata information for cursor and can output the resultset of cursor. If so, then this is ok to choose this solution. also VbScript is ok, if it can help.
    2. Maybe one can create table temporarily based on the cursor. And table objects have meta data in oracle system tables, so i can output all cursor data.
    3. Maybe i can use so called try-catch clauses techique to help somehow. For example
    Try
      fetch cur1 into varchar2_var1, .., varchar2_var5
    catch (if error)
          try
              fetch cur1 into varchar2_var1, .., varchar2_var4
    Till we know how many fields there are.
    somehow this way to go next4. Maybe execute immediate can help somehow.

    If you're not in 11g and you at least have some options of structures you want to try and fetch to, you can make use of the rowtype_mismatch exception by catching it and trying to fetch into a different structure until you find it, by nesting PL/SQL begin...exception...end; blocks.
    You won't lose rows if you attempt to fetch into the wrong structure.
    In the example below I try to fetch into a type with 2 columns and it fails then I attempt again against a 3-column type.
    Note that the column type mismatch on implicit conversions will throw other exceptions as ORA-06504 or ORA-01722 for example.
    Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.4.0
    Connected as fsitja
    SQL> set serveroutput on
    SQL>
    SQL> DECLARE
      2    cur SYS_REFCURSOR;
      3    TYPE t_rec1 IS RECORD(
      4      col1 NUMBER,
      5      col2 VARCHAR2(100));
      6    v_rec1 t_rec1;
      7    TYPE t_rec2 IS RECORD(
      8      col3 NUMBER,
      9      col4 VARCHAR2(100),
    10      col5 VARCHAR2(100));
    11    v_rec2 t_rec2;
    12  BEGIN
    13    OPEN cur FOR
    14      SELECT 1 col3, 'a' col4, 'b' col5 FROM dual;
    15    FETCH cur
    16      INTO v_rec1;
    17    dbms_output.put_line('REC1.COL1: ' || v_rec1.col1);
    18    dbms_output.put_line('REC1.COL2: ' || v_rec1.col2);
    19  EXCEPTION
    20    WHEN rowtype_mismatch THEN
    21      FETCH cur
    22        INTO v_rec2;
    23      dbms_output.put_line('REC2.COL3: ' || v_rec2.col3);
    24      dbms_output.put_line('REC2.COL4: ' || v_rec2.col4);
    25      dbms_output.put_line('REC2.COL5: ' || v_rec2.col5);
    26  END;
    27  /
    REC2.COL3: 1
    REC2.COL4: a
    REC2.COL5: b
    PL/SQL procedure successfully completed
    SQL>

  • Stored procedure returning multiple records without using SYS_REFCURSOR

    Hello,
    I am new to oracle stored procedures, have done stored procs in SQL server in past. I am trying to write single stored proc which will return multiple records. I have the stored proc as below and that is compiled without any errors.
    We don't want to use SYS_REFCURSOR as output param b'coz the place from which this proc is gonna call, that system doesn't support SYS_REFCURSOR param.
    create or replace
    PROCEDURE p_get5500DATA_MB (
    IN_plan_ID IN T_5500DATA_QWP.Plan_ID%TYPE,
    IN_plan_ID_col OUT T_5500DATA_QWP.Plan_ID%TYPE,
    p_SEQNUM OUT T_5500DATA_QWP.SEQNUM%TYPE,
    p_HEADER_CD OUT T_5500DATA_QWP.HEADER_CD%TYPE,
    p_VALUE1 OUT T_5500DATA_QWP.VALUE1%TYPE,
    p_VALUE2 OUT T_5500DATA_QWP.VALUE2%TYPE
    ) AS
    BEGIN
    SELECT
    Plan_ID,
    SEQNUM,
    HEADER_CD,
    VALUE1,
    VALUE2
    INTO
    IN_plan_ID_col,
    p_SEQNUM,
    p_HEADER_CD,
    p_VALUE1,
    p_VALUE2
    FROM TRS1DBO.T_5500DATA_QWP
    WHERE Plan_ID = IN_plan_ID
    ORDER BY SeqNum;
    -- EXCEPTION
    -- WHEN OTHERS THEN
    -- RAISE_APPLICATION_ERROR(-210001, 'Error in fetching data from T_5500DATA_QWP....');
    END;
    Error:
    ORA-01422: exact fetch returns more than requested number of rows
    ORA-06512: at "TRS1DBO.P_GET5500DATA_MB", line 10
    ORA-06512: at line 11
    My questions is:
    - What would be the best practice for this type of simple stored procedures?
    - Is there any alternate or is there anything i can fix in above stored proc which return multiple records?
    Thank you,
    Vimal

    Just out of curiosity, what are you using for API or driver that doesn't support a ref cursor? Ref cursors are pretty much the defacto standard for passing multiple records out of an Oracle procedure. Oracle's ODP.NET, OLEDB, ODBC, JDBC, OCI, all support ref cursors. Chances are that if the driver you're using doesn't support something as basic/fundamental as a ref cursor, it's probably also not going to support something else either.
    You'll most likely want to check with the driver/api vendor on their recommended approach.

  • Using CASE statement in Procedure,  SYS_REFCURSOR as OUT parameter

    Hi all,
    What is the mistake in this procedure
    create or replace procedure ConditionalSelect( param1 number, refCur IN OUT SYS_REFCURSOR ) is     
    begin
    case
    when param1 = 1 then open refCur for select * from AA;
    when param1 = 2 then open refCur for select * from EMPLOYEE;
         end;          
    end;
    The error i am getting is
    Error
    [row:1,col:1] ORA-24344: success with compilation error
    [row:8,col:5] PLS-00103: Encountered the symbol ";" when expecting one of the following:
    case
    The symbol "case" was substituted for ";" to continue.
    Thanks in advance
    pal

    a. you are missing an "end case;"
    b. in select - use case only with end - in pl/sql you shulde use "end case"
    like "end loop", "end if"
    c. case is much more easy to read then a bunch of if's and else if's and else.
    Amiel.

  • Using SYS_REFCURSOR returned from function in a WHERE clause

    Hi All,
    I have a plsql function that returns a SYS_REFCURSOR. Typically it will be three columns wide and 1 or more rows. I'd like to use it like:
    SELECT *
    FROM schema_name.table_name a
    WHERE a.date_col BETWEEN trunc(add_months(SYSDATE,-12),'month') AND sysdate
    AND ((a.col_a, a.col_b, a.col_c) IN (
    open SYS_REFCURSOR returned by schema_name.package_name.function_name('x','y','z')
    I've tried casting it to a table, but it complains about an invalid relational operator:
    SELECT *
    FROM schema_name.table_name a
    WHERE a.date_col BETWEEN trunc(add_months(SYSDATE,-12),'month') AND sysdate
    AND ((a.col_a, a.col_b, a.col_c) IN (TABLE(schema_name.package_name.function_name('x','y','z')))
    Any suggestions would be appreciated!
    Thanks,
    Thomas

    Regarding 3360's xml functionality:
    SQL> create or replace function f
      2     return sys_refcursor
      3  as
      4     c   sys_refcursor;
      5  begin
      6     open c for
      7        select 7788 empno, 'SCOTT' ename from dual
      8        union all
      9        select 7900 empno, 'JAMES' ename from dual;
    10
    11     return c;
    12  end f;
    13  /
    Function created.
    SQL> select empno, ename
      2    from emp
      3   where (empno, ename) in
      4            (select extractvalue (column_value, 'ROW/EMPNO'),
      5                    extractvalue (column_value, 'ROW/ENAME')
      6               from table (xmlsequence (f)));
              EMPNO ENAME
               7788 SCOTT
               7900 JAMES

  • Accessing a returned SYS_REFCURSOR

    Hi,
    i have a problem accessing records in a weak sys_refcursor (that was returned from another function) inside a PL/SQL function. I alwys get a "PLS-00487: Invalid reference to variable 'REC2'" where rec2 is my loop record variable.
    Here is a simplified test which shows the same behaviour (the problem is marked in master_report):
    TYPE resType AS OBJECT (
    c1 VARCHAR2(80),
    c2 VARCHAR2(80),
    c3 VARCHAR2(80)
    TYPE resTable AS TABLE OF resType;
    CREATE OR REPLACE FUNCTION REPORT_01 (uId PLS_INTEGER)
    RETURN SYS_REFCURSOR
    IS
    st_cursor SYS_REFCURSOR;
    BEGIN
    -- Do various things, builds a dynamic sql query based in input parameters
    OPEN st_cursor FOR 'SELECT * FROM t1 LEFT JOIN t2 ON t1.id=t2.id LEFT JOIN t3 ON t1.id = t3.id';
    return st_cursor;
    END REPORT_01;
    CREATE OR REPLACE FUNCTION MASTER_REPORT (repId PLS_INTEGER)
    RETURN resTable PIPELINED
    IS
    res resType := resType(NULL,NULL,NULL);
    BEGIN
         FOR rec in
         ( SELECT * FROM report WHERE REP_ID = repId )
         LOOP
              IF rec.basisreport_key = 'basisreport.einsaetzeimunternehmen' THEN
    -- report_01 returns an open sys_refcursor
                   FOR rec2 IN report_01(rec.ben_id)
                   LOOP
    -- PROBLEM HERE: "Invalid reference to variable 'REC2'"
                        res.c1 := rec2.personalnummer;
                        res.c2 := rec2.name;
                        res.c3 := rec2.type;
    PIPE ROW(
    END LOOP;
    END IF;
    END LOOP;
    END MASTER_REPORT;
    So my question is: How am i supposed to acces the contents of the returned ref cursor?
    Thanks.
    Ulrich Petri

    Hello
    Aha! Sorry, I forgot that for it to work you have to select the columns "as" the object type like so:
    SQL> set serveroutput on
    SQL> CREATE OR REPLACE TYPE resType AS OBJECT (
      2  c1 VARCHAR2(80),
      3  c2 VARCHAR2(80),
      4  c3 VARCHAR2(80)
      5  )
      6  /
    Type created.
    SQL> DECLARE
      2
      3     my_cursor               sys_refcursor;
      4
      5     res                             resType;
      6
      7  BEGIN
      8
      9     OPEN my_cursor FOR 'SELECT ''C1'',''C2'',''C3'' FROM DUAL';
    10
    11     FETCH my_cursor INTO res;
    12
    13  END;
    14  /
    DECLARE
    ERROR at line 1:
    ORA-00932: inconsistent datatypes: expected UDT got CHAR
    ORA-06512: at line 11
    SQL> DECLARE
      2
      3     my_cursor               sys_refcursor;
      4
      5     res                             resType;
      6
      7  BEGIN
      8
      9     OPEN my_cursor FOR 'SELECT resType(''C1'',''C2'',''C3'') FROM DUAL';
    10
    11     FETCH my_cursor INTO res;
    12
    13     DBMS_OUTPUT.put_line(res.c1);
    14     DBMS_OUTPUT.put_line(res.c2);
    15     DBMS_OUTPUT.put_line(res.c3);
    16
    17  END;
    18  /
    C1
    C2
    C3
    PL/SQL procedure successfully completed.HTH
    David

Maybe you are looking for

  • Oracle Financials Implementation/Setup Documents

    Hello Gurus, Can you please send me documents like RD20,BP40/80, BR100, MD50 or any implementation related documents on (GL,AP,AR,FA,CM) and would really appreciate if you can send me Setup Documents of 11i/R12 (GL,AP,AR) as well. Thanks in advance,

  • Content aware move tool and recompose do not work.

    Content aware move tool and recompose do not work. Nothing happens...What can I possible do wrong?

  • Third party iTunes software

    I am seeking a FREE iTunes software system that will work on a Mac running 9.2.2. Please tell me where I can find this FREE iTunes software. It's best to send the information direct to [email protected] since I usually vist these forum pages every si

  • You are running an operating system that .... no longer supports.

    Everytime I want to download After effects etc... I am not allowed to. This message appears "You are running an operating system that After Effects no longer supports. Refer to the system requirements for a full list of supported platforms."   Can I

  • Certification ID and Certification Number

    what is Microsoft certification Number? and what is the difference between Microsoft certification ID and certification Number?