Doubt in ref cursor

hi,
in this below procedure i want to use bulk collect and for all.
i want to create pl/sql table for every column or any other way is there?
plese help.
PROCEDURE sp_update_cust_statement(P_ou_code POS_TRAN_HEADER.ou_code%type ,P_uploadid POS_TRAN_HEADER.uploadid%type) IS
v_point_bal CUST_ACC_STMT.POINTS_BAL%TYPE;
v_cust_id CUST_ACC_STMT.CUST_ACC_ID%TYPE;
BEGIN
SELECT nvl(MAX(NVL(CUST_ACC_ID,1)),0)+ 1 INTO v_cust_id FROM CUST_ACC_STMT;
FOR cur_rec_C_HEAD IN (SELECT *
FROM POS_TRAN_HEADER
WHERE ou_code = P_ou_code and
                              uploadid = P_uploadid
                              ORDER BY ACC_NUM,INV_NUM)
LOOP
-- EXIT WHEN SQL%NOTFOUND;
--get the already available basic points for account number
v_point_bal :=pkg_point_calculation_new.fnc_get_balancepts(cur_rec_C_HEAD .acc_num);
INSERT INTO CUST_ACC_STMT(CUST_ACC_ID ,
                         TRAN_OU ,
               ACC_NUM ,
               CARD_NUM ,
               CUST_TIER ,
TRAN_DATE ,
SHOP_CODE ,
                         INV_NUM ,
                         INV_NET_AMT ,
                         INV_GROSS_AMT ,
                         TRAN_TYPE ,
                              TRAN_REMARKS ,
                         POINTS ,
                         POINTS_AVAIL,
                         POINTS_USED ,
                         POINTS_BAL ,
                         REMARKS1 ,
                         REMARKS2 ,
                         REMARKS3 ,
                         ACTIVE_FLG ,
                         LAST_MOD_USER ,
                         LAST_MOD_DATETIME )
VALUES ( v_cust_id ,
cur_rec_C_HEAD .OU_CODE,
                         cur_rec_C_HEAD .acc_num,
                         cur_rec_C_HEAD .CARD_num,
                         '1',
                         cur_rec_C_HEAD .INV_DATE,
                         cur_rec_C_HEAD .SHOP_CODE,
                         cur_rec_C_HEAD .INV_NUM,
                         cur_rec_C_HEAD .INV_NET_AMT,
                         cur_rec_C_HEAD .INV_GROSS_AMT,
                         'B',
                         'Basic points',
                         cur_rec_C_HEAD .BASIC_PTS,
                         cur_rec_C_HEAD .BASIC_PTS,
                         0,
                         v_point_bal + cur_rec_C_HEAD .BASIC_PTS,
                         NULL,
                         NULL,
                         NULL,
'Y',
'BATCH',
SYSDATE);
END LOOP;
COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
WHEN OTHERS THEN
NULL;
END sp_update_cust_statement;

Your formatted code looks like this.
PROCEDURE sp_update_cust_statement
                    P_ou_code      POS_TRAN_HEADER.ou_code%type ,
                    P_uploadid      POS_TRAN_HEADER.uploadid%type
IS
     v_point_bal CUST_ACC_STMT.POINTS_BAL%TYPE;
     v_cust_id CUST_ACC_STMT.CUST_ACC_ID%TYPE;
BEGIN
     SELECT nvl(MAX(NVL(CUST_ACC_ID,1)),0)+ 1
       INTO v_cust_id
       FROM CUST_ACC_STMT;
     FOR cur_rec_C_HEAD IN (SELECT *
                     FROM POS_TRAN_HEADER
                    WHERE ou_code = P_ou_code
                      AND uploadid = P_uploadid
                    ORDER BY ACC_NUM,INV_NUM)
     LOOP
          --get the already available basic points for account number
          v_point_bal :=pkg_point_calculation_new.fnc_get_balancepts(cur_rec_C_HEAD .acc_num);
          INSERT INTO CUST_ACC_STMT
                         CUST_ACC_ID ,
                         TRAN_OU ,
                         ACC_NUM ,
                         CARD_NUM ,
                         CUST_TIER ,
                         TRAN_DATE ,
                         SHOP_CODE ,
                         INV_NUM ,
                         INV_NET_AMT ,
                         INV_GROSS_AMT ,
                         TRAN_TYPE ,
                         TRAN_REMARKS ,
                         POINTS ,
                         POINTS_AVAIL,
                         POINTS_USED ,
                         POINTS_BAL ,
                         REMARKS1 ,
                         REMARKS2 ,
                         REMARKS3 ,
                         ACTIVE_FLG ,
                         LAST_MOD_USER ,
                         LAST_MOD_DATETIME
          VALUES
                         v_cust_id ,
                         cur_rec_C_HEAD .OU_CODE,
                         cur_rec_C_HEAD .acc_num,
                         cur_rec_C_HEAD .CARD_num,
                         '1',
                         cur_rec_C_HEAD .INV_DATE,
                         cur_rec_C_HEAD .SHOP_CODE,
                         cur_rec_C_HEAD .INV_NUM,
                         cur_rec_C_HEAD .INV_NET_AMT,
                         cur_rec_C_HEAD .INV_GROSS_AMT,
                         'B',
                         'Basic points',
                         cur_rec_C_HEAD .BASIC_PTS,
                         cur_rec_C_HEAD .BASIC_PTS,
                         0,
                         v_point_bal + cur_rec_C_HEAD .BASIC_PTS,
                         NULL,
                         NULL,
                         NULL,
                         'Y',
                         'BATCH',
                         SYSDATE
     END LOOP;
     COMMIT;
EXCEPTION
     WHEN NO_DATA_FOUND THEN
          NULL;
END sp_update_cust_statement;Point 1:
Removed the WHEN OTHERS THEN NULL part of your code. I have removed it here. Its too Dangerous.
Point 2:
v_point_bal :=pkg_point_calculation_new.fnc_get_balancepts(cur_rec_C_HEAD .acc_num);Here you are passing acc_num to the function 1 by 1. If you use bulk collect how are you trying to modify your code?
Point 3:
If you want to use FORALL then you need to have separate collection types for each field that you want to associate in the operation. You cant just have a single table type of records. You will get the following error
PLS-00436: implementation restriction: cannot reference fields of BULK In-BIND
table of recordsThanks,
Karthick.
Edited by: Karthick_Arp on Jan 26, 2009 9:31 PM

Similar Messages

  • Is BC4J a viabl option for database with stored procedure (ref cursor) API?

    I'm about to begin a Web application development project. As foundation, we have a (Oracle) database of certain complexity that have a data access API developed with PL/SQL packages.
    This API is designed to get data through stored procedures/functions that return REF CURSOR.
    Personally I have been investigating about Oracle ADF/JSF, and a number of others J2EE technologies, and at this moment I am doubting if ADF BC are a viable option to my development team.
    I think this because I have noticed that one of the great drawback in ADF BC is the lack of simplicity to get data through stored procedures/functions that returns REF CURSORS.
    I have been looking for documentation and the only thing that I have found are two examples:
    1.- One that really do not work (fails in get data from ref cursor): ADF BC StoredProcedure Sample application.
    2.- And other published by Steve Muench in
    http://radio.weblogs.com/0118231/stories/2003/03/03/gettingAViewObjectsResultRowsFromARefCursor.html. This sample works fine.
    But, the problem with the approach of this last article is the amount (and complexity) of the code necessary to make so basic and recurrent operation as is "obtain data through a stored procedure (ref cursor)".
    Below it is the code that I have constructed to call a function that returns a ref cursor (based on steve's article).
    If this is the only way to make this (historically so basic and simple) task, then it is obvious that BC is not a viable technology to my (or I am in a mistake?), since we have about 50 stored procedures/functions to access the underlying data; that stored procedures/functions are key to development of the new application (and, still more, currently are used to anothers apps ).
    By all this, I would like consult to Oracle's people:
    1.- I really must reject BC as technology to implement this project ?
    2.- It is possible to access stored procedures in a simpler way using BC?
    3.- If the answer to 2 is NOT: in near future, the BC team has plans to give more support to the simple access to stored procedures?
    4.- If the answer to 3 is NOT: what another technology you recommend to construct my data access/business tier and still be able to using the others characteristics of ADF?
    Thank you very much for your guidelines.
    Regards, RL.
    ** And the code!!!
    ** ###   I am forced to do this for each call to a procedure???? ###
    package myrefcursor.model;
    import java.math.BigDecimal;
    import java.sql.CallableStatement;
    import java.sql.ResultSet;
    import java.sql.ResultSetMetaData;
    import java.sql.SQLException;
    import java.sql.Types;
    import oracle.jbo.JboException;
    import oracle.jbo.domain.NullValue;
    import oracle.jbo.domain.Number;
    import oracle.jbo.server.DBTransaction;
    import oracle.jbo.server.ViewObjectImpl;
    import oracle.jbo.server.ViewRowImpl;
    import oracle.jbo.server.ViewRowSetImpl;
    import oracle.jdbc.driver.OracleCallableStatement;
    import oracle.jdbc.driver.OracleTypes;
    public class TraePolizasViewImpl extends ViewObjectImpl {
        private static final String SQL = "begin ? := PKG_PRUEBA.trae_polizas(?);end;";
        private static final String COUNTSQL = "begin ? := PKG_PRUEBA.count_trae_polizas(?);end;";
        public TraePolizasViewImpl() {
        protected void executeQueryForCollection(Object qc,Object[] params,int numUserParams) {
            BigDecimal rut_contratante = null;
            Object[] theUserParam = null;
            System.out.println(params);
            System.out.println(params[0]);
            if (params != null)
                theUserParam = (Object[]) params[0];
            //if (theUserParam != null && theUserParam.length > 0 )
            if (! (theUserParam[1]   instanceof NullValue) )
                rut_contratante = (BigDecimal)theUserParam[1];
            storeNewResultSet(qc ,retrieveRefCursor(qc, rut_contratante));
            super.executeQueryForCollection(qc, params, numUserParams);
        protected void create() {
          getViewDef().setQuery(null);
          getViewDef().setSelectClause(null);
          setQuery(null);
        protected ViewRowImpl createRowFromResultSet(Object qc, ResultSet rs) {
          rs = getResultSet(qc);
          ViewRowImpl r = createNewRowForCollection(qc);
          try {
            populateAttributeForRow(r,0, nullOrNewNumber(rs.getBigDecimal(1)));
            populateAttributeForRow(r,1, rs.getString(2));
          catch (SQLException s) {
           throw new JboException(s);
          return r;
        protected boolean hasNextForCollection(Object qc) {
          ResultSet rs = getResultSet(qc);
          boolean nextOne = false;
          try {
            nextOne = rs.next();
            if (!nextOne) {
              setFetchCompleteForCollection(qc, true);
              rs.close();
          catch (SQLException s) {
           throw new JboException(s);
          return nextOne;
        protected void releaseUserDataForCollection(Object qc, Object rs) {
           ResultSet userDataRS = getResultSet(qc);
           if (userDataRS != null) {
            try {    userDataRS.close();    }
            catch (SQLException s) { ; }  
          super.releaseUserDataForCollection(qc, rs);
        public long getQueryHitCount(ViewRowSetImpl viewRowSet) {
          return viewRowSet.getRowCount();
        private ResultSet retrieveRefCursor(Object qc, BigDecimal rut_contratante) {
          CallableStatement st = null;
          try {
            st = getDBTransaction().createCallableStatement(SQL, DBTransaction.DEFAULT);
            st.registerOutParameter(1,OracleTypes.CURSOR);
            if (rut_contratante == null)
                st.setNull(2, Types.NUMERIC);
            else
                st.setBigDecimal(2, rut_contratante);
            st.execute();
            ResultSet rs = ((OracleCallableStatement)st).getCursor(1);
            rs.setFetchSize(getFetchSize());
            return rs ;
          catch (SQLException s) {
            throw new JboException(s);
          finally {try {st.close();} catch (SQLException s) {;}}
        private void storeNewResultSet(Object qc, ResultSet rs) {
          ResultSet existingRs = getResultSet(qc);
          if (existingRs != null) {
            try {existingRs.close();} catch (SQLException s) {;}  
          setUserDataForCollection(qc,rs);
          hasNextForCollection(qc); // Prime the pump with the first row.
        private ResultSet getResultSet(Object qc) {
            return (ResultSet)getUserDataForCollection(qc);
        private static Number nullOrNewNumber(BigDecimal b) {
             try {
               return b != null ? new Number(b) : null;
             catch (SQLException s) { ; }
             return null;
        public BigDecimal getprutcontratante() {
            return (BigDecimal)getNamedWhereClauseParam("prutcontratante");
        public void setprutcontratante(BigDecimal value) {
            setNamedWhereClauseParam("prutcontratante", value);
    }

    no?

  • Describe weak ref cursor

    I want to implement a stored procedure which takes a
    weak ref cursor as one of its IN parameters. In the body
    of the SP I want to analyze the "structure" of the weak
    ref cursor: column names and types.
    Any hints how to do this in PL/SQL?? Of course, in C via OCI
    describing a (weak) ref cursor at run-time is no problem at
    all.
    Tobias.

    it is not possible to fetch into some variable, which doesn't match the structure of the cursor variable.....
    There is one way.....you can discard the first n records while assigning the query to cursor variable....
    Frame ur query that ur going to assocaite to the cursor in the following way....
    select * from (select rownum a, test.* from test) where a > N
    where 'N' is the no of records that u don't want to be in the cursor.....
    if u have doubt in this approach get back to me...

  • Weak REF CURSOR: discarding records?

    Hi,
    I'd like to discard the first N records from a weak REF CURSOR without having to specify the structure of the cursor. Is this possible?
    For example:
    LOOP
    FETCH results INTO garbagecan
    EXIT WHEN results%NOTFOUND;
    END LOOP;
    It seems that FETCH statement requires INTO to be specified with the correct structure.
    -Jerome
    null

    it is not possible to fetch into some variable, which doesn't match the structure of the cursor variable.....
    There is one way.....you can discard the first n records while assigning the query to cursor variable....
    Frame ur query that ur going to assocaite to the cursor in the following way....
    select * from (select rownum a, test.* from test) where a > N
    where 'N' is the no of records that u don't want to be in the cursor.....
    if u have doubt in this approach get back to me...

  • How to return integer used wit DMBS_SQL as ref cursor ?

    I am trying to return a ref cursor form a procedure to be used by xsql to output hierarchical XML.
    I created the query using the DBMS_SQL package, did an OPEN_CURSOR and then PARSE.
    Can I, and if so how, return the integer from the PARSE as a ref cursor out of my procedure ? According to the docs the integer in the PARSE is the ID number for a cursor.
    thanks,
    Reinier

    I suspect that you are a little confused. I doubt that what you are asking for is what you really need. I believe you want the contents of a ref cursor, not an integer that is the cursor id. Since you are using Oracle 8i, as mentioned in your other post, you don't need DBMS_SQL; You just need to open a ref cursor dynmacially. Please see my response to your other post:
    Re: Error while compiling form in AS 10g  deployed on Linux

  • Passing value to ref cursor

    Hi,
    I have a doubt in the code mentioned below ..indicated in the code by
    " -- id shoud be the value fetched from variable v_samp;".
    I am not sure of how I get the value into the ref cursor from the variable
    declare
    Cursor C1
    Is Select Table_Name,Rownum R_Num From User_Tables Where Table_Name Like 'T%' Order By Table_Name;
    Cursor C2 Is Select Sample From code_tbl;
    Type Ref1 Is Ref Cursor;
    R_1 Ref1;
    Type T_Samp Is Table Of Varchar2(100);
    Lv_Samp T_Samp;
    lv_geno T_Samp;
    Begin
    For L1 in C1 loop
    V_tbl := L1.table_name;
    For L2 In C2 Loop
    V_samp := L2.sample;
    Open R_1 for 'Select sample_id, genotype from ' || V_tbl || ' where id = ? '; -- id shoud be the value fetched from variable v_samp;
    Loop
    Fetch R_1 Bulk Collect Into Lv_Samp,Lv_Geno Limit 10000;
    FOR indx IN 1 .. lv_samp.COUNT
    Loop
    V1 := V1 || lv_geno(indx);
    End Loop;
    EXIT WHEN Lv_samp.COUNT = 0;
    end loop;
    end loop;
    end loop;
    end;
    Thanks

    Sorry about my approach..I did that using tool. I don't know how to keep it..I do apologize if I did hurt you..
    This is my complete requirement...
    For every sample in table all_f if it exists in table t1
    then the output should be the concatenated value of type
    for the corresponding sample. Let me know if I need to do anything else..There are million types for every sample.
    The output should be
    'AB35652626-G8' 1 1 1 1 1 1 1 1 1 1 0 0
    since only this id exists in c3 (table t1).
    This is just a sample...I have huge number of rows to be concatenated for multiple id's.
    So that is the reason why I don't want to do any processing in the loop except concatenation.
    DDL's and DML's are as follows :
    create table all_f (sample varchar2(20), typeo varchar2(20));
    insert into all_f (SAMPLE, typeo)
    values ('AB35053903-C10', '2');
    insert into all_f (SAMPLE, typeo)
    values ('AB35053995-A10', '1');
    insert into all_f (SAMPLE, typeo)
    values ('AB35054283-C3', '1');
    insert into all_f (SAMPLE, typeo)
    values ('AB35054582-A7', '2');
    insert into all_f (SAMPLE, typeo)
    values ('AB35055053-H12', '1');
    insert into all_f (SAMPLE, typeo)
    values ('AB35055158-B2', '1');
    insert into all_f (SAMPLE, typeo)
    values ('AB35500856-F4', '1');
    insert into all_f (SAMPLE, typeo)
    values ('AB35501332-G11', '1');
    insert into all_f (SAMPLE, typeo)
    values ('AB35501428-B9', '1');
    insert into all_f (SAMPLE, typeo)
    values ('AB35504972-F11', '1');
    insert into all_f (SAMPLE, typeo)
    values ('AB35505551-H7', '2');
    insert into all_f (SAMPLE, typeo)
    values ('AB35506138-G5', '1');
    insert into all_f (SAMPLE, typeo)
    values ('AB35507097-C11', '1');
    insert into all_f (SAMPLE, typeo)
    values ('AB35507190-G9', '1');
    insert into all_f (SAMPLE, typeo)
    values ('AB35561723-H10', '1');
    insert into all_f (SAMPLE, typeo)
    values ('AB35651275-E6', '1');
    insert into all_f (SAMPLE, typeo)
    values ('AB35896175-C8', '1');
    insert into all_f (SAMPLE, typeo)
    values ('AB35897805-A3', '2');
    insert into all_f (SAMPLE, typeo)
    values ('AB35899249-H8', '1');
    insert into all_f (SAMPLE, typeo)
    values ('AB35899918-H6', '1');
    insert into t1 (SAMPLE, TYPEO)
    values ('AB35652626-G8', '1');
    commit;
    create table t1 (sample_id varchar2(20), type varchar2(20));
    insert into t1 (SAMPLE_ID, TYPE)
    values ('AB35652626-G8', '1');
    insert into t1 (SAMPLE_ID, TYPE)
    values ('AB35652626-G8', '1');
    insert into t1 (SAMPLE_ID, TYPE)
    values ('AB35652626-G8', '1');
    insert into t1 (SAMPLE_ID, TYPE)
    values ('AB35652626-G8', '1');
    insert into t1 (SAMPLE_ID, TYPE)
    values ('AB35652626-G8', '1');
    insert into t1 (SAMPLE_ID, TYPE)
    values ('AB35652626-G8', '1');
    insert into t1 (SAMPLE_ID, TYPE)
    values ('AB35652626-G8', '1');
    insert into t1 (SAMPLE_ID, TYPE)
    values ('AB35652626-G8', '1');
    insert into t1 (SAMPLE_ID, TYPE)
    values ('AB35652626-G8', '1');
    insert into t1 (SAMPLE_ID, TYPE)
    values ('AB35652626-G8', '1');
    insert into t1 (SAMPLE_ID, TYPE)
    values ('AB35652626-G8', '0');
    insert into t1 (SAMPLE_ID, TYPE)
    values ('AB35652626-G8', '0');
    Thanks,

  • How do i return data, when my sql was opened in a ref cursor.

    In Pl/sql, I was been bunged in the following situation:
    I am opening a ref cursor, where i couldn't determine the return type. In that case how will i return the data for those sql.
    Sample code :
    Declare
    Type a_ref IS REF CURSOR;
    C1 a_ref;
    Begin
    Open c1 for ‘select a, b, c from D’;
    Fetch c1 into ??????;
    Close c1;
    End;
    My doubt resides in ??? part..
    The columns in the select clause will vary dynamically.
    Hence how can I declare my variable..
    Regards,
    Bala

    Well, nothing is over to change mind if possible. I think the knowledge of
    alternatives is always useful... :).
    As for DBMS_SQL, it's an alternative to ref cursors too, but surely inside PL/SQL:
    SQL> declare
      2   c integer;
      3   desc_t DBMS_SQL.DESC_TAB;
      4   col_cnt integer;
      5   type gvarray is varray(25) of varchar(40);
      6   values1 gvarray := gvarray();
      7   a integer;
      8  begin
      9   values1.extend(25);
    10   c := dbms_sql.open_cursor;
    11   DBMS_SQL.PARSE(c,'select hiredate,ename from emp' ,DBMS_SQL.NATIVE);
    12   DBMS_SQL.DESCRIBE_COLUMNS (
    13     c,
    14     col_cnt,
    15     desc_t);
    16   for j in 1..col_cnt loop
    17     dbms_sql.define_column(c,j,values1(j),40);
    18   end loop;
    19   a:=dbms_sql.execute(c);
    20   loop
    21     if dbms_sql.fetch_rows(c) > 0 then
    22      for j in 1..col_cnt loop
    23        dbms_sql.column_value(c,j,values1(j));
    24        dbms_output.put_line('Row number ' || j || ', column ' || desc_t(j).col_name || ', value
    25        || values1(j) );
    26      end loop;
    27     else
    28       exit;
    29     end if;
    30   end loop;
    31   dbms_sql.close_cursor(c);
    32  end;
    33  /
    Row number 1, column HIREDATE, value 17.12.80
    Row number 2, column ENAME, value SMITH
    Row number 1, column HIREDATE, value 20.02.81
    Row number 2, column ENAME, value ALLEN
    Row number 1, column HIREDATE, value 22.02.81
    Row number 2, column ENAME, value WARD
    Row number 1, column HIREDATE, value 02.04.81
    Row number 2, column ENAME, value JONES
    Row number 1, column HIREDATE, value 28.09.81
    Row number 2, column ENAME, value MARTIN
    Row number 1, column HIREDATE, value 01.05.81
    Row number 2, column ENAME, value BLAKE
    Row number 1, column HIREDATE, value 09.06.81
    Row number 2, column ENAME, value CLARK
    Row number 1, column HIREDATE, value 19.04.87
    Row number 2, column ENAME, value SCOTT
    Row number 1, column HIREDATE, value 17.11.81
    Row number 2, column ENAME, value KING
    Row number 1, column HIREDATE, value 08.09.81
    Row number 2, column ENAME, value TURNER
    Row number 1, column HIREDATE, value 23.05.87
    Row number 2, column ENAME, value ADAMS
    Row number 1, column HIREDATE, value 03.12.81
    Row number 2, column ENAME, value JAMES
    Row number 1, column HIREDATE, value 03.12.81
    Row number 2, column ENAME, value FORD
    Row number 1, column HIREDATE, value 23.01.82
    Row number 2, column ENAME, value MILLER
    PL/SQL procedure successfully completed.Rgds.

  • Regarding the Ref Cursor functional;ity

    HI,
    I am using ref cursor to return Result Set to .Net.
    I am in doubt that , Is it requires multiple server trips to fill the DataSet at front end.
    As my assumption it will return the address of the work area provided in Oracle server. After that for each row it make a server trip .
    Is my assumption is right ?
    Can any one tell me the functionality behind returning a Ref Cursor .
    Thank you....

    This is (or ought to be) configurable on the .NET side. There will be a server round-trip to fetch every N records where N is a setting on the client. I'm not particularly experienced with .NET, so I'm not sure where this setting is set, but the folks over in the .NET forum might.
    Justin
    Distributed Database Consulting, Inc.
    http://www.ddbcinc.com/askDDBC

  • Odd error while opening a ref cursor

    Hi.
    I have a procedure in a package that has both in and out parameters. One of those out parameters is a ref cursor. The procedure creates a dynamic query and then executes it, then it opens the cursor:
    PROCEDURE PROC(
    A IN VARCHAR2,
    B IN VARCHAR2,
    C OUT TYPES.cursorType; --(TYPES is a package whose only use is to declare a cursor type)
    ) IS
    --DECLARATIONS
    OPEN C FOR 'SELECT A, B, C, D...';
    END;
    When I execute the package in an anonymous block it throws the error:
    ORA-00938: not enough arguments for function, just in the line where the cursor is being opened.
    Any ideas?

    is everything defined correctly?
    create or replace package types  as
      type cursorType is ref cursor;
    end types;
    SQL> set serveroutput on
    SQL> declare
      2 
      3    ref_C types.cursorType;
      4   
      5    v_a varchar2(1);
      6    v_b varchar2(1);
      7    v_c varchar2(1);
      8    v_d varchar2(1);
      9   
    10    procedure Proc (a in varchar2
    11                   ,b in varchar2
    12                   ,C out types.cursorType) as
    13 
    14      begin
    15        open C for 'select :1, :2, ''c'', ''d'' from dual' using a, b;
    16    end  Proc;
    17  begin
    18 
    19 
    20    Proc('a', 'b', ref_C);
    21   
    22    fetch ref_C into v_a, v_b, v_c, v_d;
    23    if (ref_C%found) then
    24      dbms_output.put_line(v_a);
    25      dbms_output.put_line(v_b);
    26      dbms_output.put_line(v_c);
    27      dbms_output.put_line(v_d);
    28    end if;
    29   
    30   
    31  end;
    32  /
    a
    b
    c
    dP;
    Edited by: bluefrog on Feb 18, 2010 6:07 PM

  • Ref Cursor and For Loop

    The query below will return values in the form of
    bu     seq     eligible
    22     2345     Y
    22     2345     N
    22     1288     N
    22     1458     Y
    22     1458     N
    22     1234     Y
    22     1333     N
    What I am trying to accomplish is to loop through the records returned.
    for each seq if there is a 'N' in the eligible column return no record for that seq
    eg seq 2345 has 'Y' and 'N' thus no record should be returned.
    seq 1234 has only a 'Y' then return the record
    seq 1333 has 'N' so return no record.
    How would I accomplish this with a ref Cursor and pass the values to the front end application.
    Procedure InvalidNOs(io_CURSOR OUT T_CURSOR)
         IS
              v_CURSOR T_CURSOR;
         BEGIN
    OPEN v_CURSOR FOR
    '     select bu, seq, eligible ' ||
    '     from (select bu, seq, po, tunit, tdollar,eligible,max(eligible) over () re ' ||
    '          from (select bu, seq, po, tunit, tdollar,eligible ' ||
    '          from ( ' ||
    '          select bu, seq, po, tunit, tdollar, eligible, sum(qty) qty, sum(price*qty) dollars ' ||
    '               from ' ||
    '               ( select /*+ use_nl(t,h,d,s) */ ' ||
    '               h.business_unit_id bu, h.edi_sequence_id seq, d.edi_det_sequ_id dseq, ' ||
    '                    s.edi_size_sequ_id sseq, h.po_number po, h.total_unit tUnit, h.total_amount tDollar, ' ||
    '                    s.quantity qty, s.unit_price price,' ||
    '               (select (case when count(*) = 0 then ''Y'' else ''N'' end) ' ||
    '          from sewn.NT_edii_po_det_error ' ||
    '          where edi_det_sequ_id = d.edi_det_sequ_id ' ||
    '               ) eligible ' ||
    '     from sewn.nt_edii_purchase_size s, sewn.nt_edii_purchase_det d, ' ||
    '     sewn.nt_edii_purchase_hdr h, sewn.nt_edii_param_temp t ' ||
    '     where h.business_unit_id = t.business_unit_id ' ||
    '     and h.edi_sequence_id = t.edi_sequence_id ' ||
    '     and h.business_unit_id = d.business_unit_id ' ||
    '     and h.edi_sequence_id = d.edi_sequence_id ' ||
    '     and d.business_unit_id = s.business_unit_id ' ||
    '     and d.edi_sequence_id = s.edi_sequence_id ' ||
    '     and d.edi_det_sequ_id = s.edi_det_sequ_id ' ||
    '     ) group by bu, seq, po, tunit, tdollar, eligible ' ||
    '     ) ' ||
    '     group by bu, seq, po, tunit, tdollar, eligible)) ';
              io_CURSOR := v_CURSOR;
    END     InvalidNOs;

    One remark why you should not use the assignment between ref cursor
    variables.
    (I remembered I saw already such thing in your code).
    Technically you can do it but it does not make sense and it can confuse your results.
    In the opposite to usual variables, when your assignment copies value
    from one variable to another, cursor variables are pointers to the memory.
    Because of this when you assign one cursor variable to another you just
    duplicate memory pointers. You don't copy result sets. What you do for
    one pointer is that you do for another and vice versa. They are the same.
    I think the below example is self-explained:
    SQL> /* usual variables */
    SQL> declare
      2   a number;
      3   b number;
      4  begin
      5   a := 1;
      6   b := a;
      7   a := a + 1;
      8   dbms_output.put_line('a = ' || a);
      9   dbms_output.put_line('b = ' || b);
    10  end;
    11  /
    a = 2
    b = 1
    PL/SQL procedure successfully completed.
    SQL> /* cursor variables */
    SQL> declare
      2   a sys_refcursor;
      3   b sys_refcursor;
      4  begin
      5   open a for select empno from emp;
      6   b := a;
      7   close b;
      8 
      9   /* next action is impossible - cursor already closed */
    10   /* a and b are the same ! */
    11   close a;
    12  end;
    13  /
    declare
    ERROR at line 1:
    ORA-01001: invalid cursor
    ORA-06512: at line 11
    SQL> declare
      2   a sys_refcursor;
      3   b sys_refcursor;
      4   vempno emp.empno%type;
      5 
      6  begin
      7   open a for select empno from emp;
      8   b := a;
      9 
    10   /* Fetch first row from a */
    11   fetch a into vempno;
    12   dbms_output.put_line(vempno);
    13 
    14   /* Fetch from b gives us SECOND row, not first -
    15      a and b are the SAME */
    16 
    17   fetch b into vempno;
    18   dbms_output.put_line(vempno);
    19 
    20 
    21  end;
    22  /
    7369
    7499
    PL/SQL procedure successfully completed.Rgds.
    Message was edited by:
    dnikiforov

  • Dynamic sql and ref cursors URGENT!!

    Hi,
    I'm using a long to build a dynamic sql statement. This is limited by about 32k. This is too short for my statement.
    The query results in a ref cursor.
    Does anyone have an idea to create larger statement or to couple ref cursors, so I can execute the statement a couple of times and as an result I still have one ref cursor.
    Example:
    /* Determine if project is main project, then select all subprojects */
    for i in isMainProject loop
    if i.belongstoprojectno is null then
    for i in ProjectSubNumbers loop
    if ProjectSubNumbers%rowcount=1 then
    SqlStatement := InitialStatement || i.projectno;
    else
    SqlStatement := SqlStatement || PartialStatement || i.projectno;
    end if;
    end loop;
    else
    for i in ProjectNumber loop
    if ProjectNumber%rowcount=1 then
    SqlStatement := InitialStatement || i.projectno;
    else
    SqlStatement := SqlStatement || PartialStatement || i.projectno;
    end if;
    end loop;
    end if;
    end loop;
    /* Open ref cursor */
    open sql_output for SqlStatement;
    Thanks in advance,
    Jeroen Muis
    KCI Datasystems BV
    mailto:[email protected]

    Example for 'dynamic' ref cursor - dynamic WHERE
    (note that Reports need 'static' ref cursor type
    for building Report Layout):
    1. Stored package
    CREATE OR REPLACE PACKAGE report_dynamic IS
    TYPE type_ref_cur_sta IS REF CURSOR RETURN dept%ROWTYPE; -- for Report Layout only
    TYPE type_ref_cur_dyn IS REF CURSOR;
    FUNCTION func_dyn (p_where VARCHAR2) RETURN type_ref_cur_dyn;
    END;
    CREATE OR REPLACE PACKAGE BODY report_dynamic IS
    FUNCTION func_dyn (p_where VARCHAR2) RETURN type_ref_cur_dyn IS
    ref_cur_dyn type_ref_cur_dyn;
    BEGIN
    OPEN ref_cur_dyn FOR
    'SELECT * FROM dept WHERE ' | | NVL (p_where, '1 = 1');
    RETURN ref_cur_dyn;
    END;
    END;
    2. Query PL/SQL in Reports
    function QR_1RefCurQuery return report_dynamic.type_ref_cur_sta is
    begin
    return report_dynamic.func_dyn (:p_where);
    end;
    Regards
    Zlatko Sirotic
    null

  • ORA-01008 with ref cursor and dynamic sql

    When I run the follwing procedure:
    variable x refcursor
    set autoprint on
    begin
      Crosstab.pivot(p_max_cols => 4,
       p_query => 'select job, count(*) cnt, deptno, row_number() over (partition by job order by deptno) rn from scott.emp group by job, deptno',
       p_anchor => Crosstab.array('JOB'),
       p_pivot  => Crosstab.array('DEPTNO', 'CNT'),
       p_cursor => :x );
    end;I get the following error:
    ^----------------
    Statement Ignored
    set autoprint on
    begin
    adsmgr.Crosstab.pivot(p_max_cols => 4,
    p_query => 'select job, count(*) cnt, deptno, row_number() over (partition by
    p_anchor => adsmgr.Crosstab.array('JOB'),
    p_pivot => adsmgr.Crosstab.array('DEPTNO', 'CNT'),
    p_cursor => :x );
    end;
    ORA-01008: not all variables bound
    I am running this on a stored procedure as follows:
    create or replace package Crosstab
    as
        type refcursor is ref cursor;
        type array is table of varchar2(30);
        procedure pivot( p_max_cols       in number   default null,
                         p_max_cols_query in varchar2 default null,
                         p_query          in varchar2,
                         p_anchor         in array,
                         p_pivot          in array,
                         p_cursor in out refcursor );
    end;
    create or replace package body Crosstab
    as
    procedure pivot( p_max_cols          in number   default null,
                     p_max_cols_query in varchar2 default null,
                     p_query          in varchar2,
                     p_anchor         in array,
                     p_pivot          in array,
                     p_cursor in out refcursor )
    as
        l_max_cols number;
        l_query    long;
        l_cnames   array;
    begin
        -- figure out the number of columns we must support
        -- we either KNOW this or we have a query that can tell us
        if ( p_max_cols is not null )
        then
            l_max_cols := p_max_cols;
        elsif ( p_max_cols_query is not null )
        then
            execute immediate p_max_cols_query into l_max_cols;
        else
            RAISE_APPLICATION_ERROR(-20001, 'Cannot figure out max cols');
        end if;
        -- Now, construct the query that can answer the question for us...
        -- start with the C1, C2, ... CX columns:
        l_query := 'select ';
        for i in 1 .. p_anchor.count
        loop
            l_query := l_query || p_anchor(i) || ',';
        end loop;
        -- Now add in the C{x+1}... CN columns to be pivoted:
        -- the format is "max(decode(rn,1,C{X+1},null)) cx+1_1"
        for i in 1 .. l_max_cols
        loop
            for j in 1 .. p_pivot.count
            loop
                l_query := l_query ||
                    'max(decode(rn,'||i||','||
                               p_pivot(j)||',null)) ' ||
                                p_pivot(j) || '_' || i || ',';
            end loop;
        end loop;
        -- Now just add in the original query
        l_query := rtrim(l_query,',')||' from ( '||p_query||') group by ';
        -- and then the group by columns...
        for i in 1 .. p_anchor.count
        loop
            l_query := l_query || p_anchor(i) || ',';
        end loop;
        l_query := rtrim(l_query,',');
        -- and return it
        execute immediate 'alter session set cursor_sharing=force';
        open p_cursor for l_query;
        execute immediate 'alter session set cursor_sharing=exact';
    end;
    end;
    /I can see from the error message that it is ignoring the x declaration, I assume it is because it does not recognise the type refcursor from the procedure.
    How do I get it to recognise this?
    Thank you in advance

    Thank you for your help
    This is the version of Oracle I am running, so this may have something to do with that.
    Oracle9i Enterprise Edition Release 9.2.0.8.0 - Production
    With the Partitioning, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.8.0 - Production
    I found this on Ask Tom (http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:3027089372477)
    Hello, Tom.
    I have one bind variable in a dynamic SQL expression.
    When I open cursor for this sql, it gets me to ora-01008.
    Please consider:
    Connected to:
    Oracle8i Enterprise Edition Release 8.1.7.4.1 - Production
    JServer Release 8.1.7.4.1 - Production
    SQL> declare
      2    type cur is ref cursor;
      3    res cur;
      4  begin
      5    open res for
      6    'select * from (select * from dual where :p = 1) connect by 1 = 1'
      7    using 1;
      8  end;
      9  /
    declare
    ERROR at line 1:
    ORA-01008: not all variables bound
    ORA-06512: at line 5
    SQL> declare
      2    type cur is ref cursor;
      3    res cur;
      4  begin
      5    open res for
      6    'select * from (select * from dual where :p = 1) connect by 1 = 1'
      7    using 1, 2;
      8  end;
      9  /
    PL/SQL procedure successfully completed.
    And if I run the same thing on 10g -- all goes conversely. The first part runs ok, and the second
    part reports "ORA-01006: bind variable does not exist" (as it should be, I think). Remember, there
    is ONE bind variable in sql, not two. Is it a bug in 8i?
    What should we do to avoid this error running the same plsql program code on different Oracle
    versions?
    P.S. Thank you for your invaluable work on this site.
    Followup   June 9, 2005 - 6pm US/Eastern:
    what is the purpose of this query really?
    but it would appear to be a bug in 8i (since it should need but one).  You will have to work that
    via support. I changed the type to tarray to see if the reserved word was causing a problem.
    variable v_refcursor refcursor;
    set autoprint on;
    begin 
         crosstab.pivot (p_max_cols => 4,
                 p_query => 
                   'SELECT job, COUNT (*) cnt, deptno, ' || 
                   '       ROW_NUMBER () OVER ( ' || 
                   '          PARTITION BY job ' || 
                   '          ORDER BY deptno) rn ' || 
                   'FROM   emp ' ||
                   'GROUP BY job, deptno',
                   p_anchor => crosstab.tarray ('JOB'),
                   p_pivot => crosstab.tarray ('DEPTNO', 'CNT'),
                   p_cursor => :v_refcursor);
    end;
    /Was going to use this package as a stored procedure in forms but I not sure it's going to work now.

  • Ref cursors and dynamic sql..

    I want to be able to use a fuction that will dynamically create a SQL statement and then open a cursor based on that SQL statement and return a ref to that cursor. To achieve that, I am trying to build the sql statement in a varchar2 variable and using that variable to open the ref cursor as in,
    open l_stmt for refcurType;
    where refcurType is a strong ref cursor. I am unable to do so because I get an error indication that I can not use strong ref cursor type. But, if I can not use a strong ref cursor, I will not be able to use it to build the report based on the ref cursor because Reports 9i requires strong ref cursors to be used. Does that mean I can not use dynamic sql with Reports 9i ref cursors? Else, how I can do that? Any documentation available?

    Philipp,
    Thank you for your reply. My requirement is that, sometimes I need to construct a whole query based on some input, and sometimes not. But the output record set would be same and the layout would be more or less same. I thought ref cursor would be ideal. Ofcourse, I could do this without dynamic SQL by writing the SQL multiple times if needed. But, I think dynamic SQL is a proper candidate for this case. Your suggestion to use lexical variable is indeed a good alternative. In effect, if needed, I could generate an entire SQL statement and place in some place holder (like &stmt) and use it as a static SQL query in my data model. In that case, why would one ever need ref cursor in reports? Is one more efficient over the other? My guess is, in the lexical variable case, part of the processing (like parsing) is done on the app server while in a function based ref cursor, the entire process takes place in the DB server and there is probably a better chance for re-use(?)
    Thanks,
    Murali.

  • Ref cursor and dynamic sql

    Hi..
    I'm using a ref cursor query to fetch data for a report and works just fine. However i need to use dynamic sql in the query because the columns used in the where condition and for some calculations may change dynamically according to user input from the form that launches the report..
    Ideally the query should look like this:
    select
    a,b,c
    from table
    where :x = something
    and :y = something
    and (abs(:x/:y........)
    The user should be able to switch between :x and :y
    Is there a way to embed dynamic sql in a ref cursor query in Reports 6i?
    Reports 6i
    Forms 6i
    Windows 2000 PRO

    Hello Nicola,
    You can parameterize your ref cursor by putting the query's select statement in a procedure/function (defined in your report, or in the database), and populating it based on arguments accepted by the procedure.
    For example, the following procedure accepts a strongly typed ref cursor and populates it with emp table data based on the value of the 'mydept' input parameter:
    Procedure emp_refcursor(emp_data IN OUT emp_rc, mydept number) as
    Begin
    -- Open emp_data for select all columns from emp where deptno = mydept;
    Open emp_data for select * from emp where deptno = mydept;
    End;
    This procedure/function can then be called from the ref cursor query program unit defined in your report's data model, to return the filled ref cursor to Reports.
    Thanks,
    The Oracle Reports Team.

  • Ref Cursor over Implicit and explicit cursors

    Hi,
    In my company when writing PL/SQL procedure, everyone uses "Ref Cursor",
    But the article below, says Implicit is best , then Explicit and finally Ref Cursor..
    [http://www.oracle-base.com/forums/viewtopic.php?f=2&t=10720]
    I am bit confused by this, can any one help me to understand this?
    Thanks

    SeshuGiri wrote:
    In my company when writing PL/SQL procedure, everyone uses "Ref Cursor",
    But the article below, says Implicit is best , then Explicit and finally Ref Cursor..
    [http://www.oracle-base.com/forums/viewtopic.php?f=2&t=10720]
    I am bit confused by this, can any one help me to understand this?There is performance and there is performance...
    To explain. There is only a single type of cursor in Oracle - that is the cursor that is parsed and compiled by the SQL engine and stored in the database's shared pool. The "+client+" is then given a handle (called a SQL Statement Handle in many APIs) that it can use to reference that cursor in the SQL engine.
    The performance of this cursor is not determined by the client. It is determined by the execution plan and how much executing that cursor cost ito server resources.
    The client can be Java, Visual Basic, .Net - or a PL/SQL program. This client language (a client of SQL), has its own structures in dealing with that cursor handle received from the SQL engine.
    It can hide it from the developer all together - so that he/she does not even see that there is a statement handle. This is what implicit cursors are in PL/SQL.
    It can allow the developer to manually define the cursor structure - this is what explicit cursors, ref cursors, and DBMS_SQL cursors are in PL/SQL.
    Each of these client cursor structures provides the programmer with a different set of features to deal with SQL cursor. Explicit cursor constructs in PL/SQL do not allow for the use of dynamic SQL. Ref cursors and DBMS_SQL cursors do. Ref cursors do not allow the programmer to determine, at run-time, the structure of the SQL projection of the cursor. DBMS_SQL cursors do.
    Only ref cursors can be created in PL/SQL and then be handed over to another client (e.g. Java/VB) for processing. Etc.
    So each of the client structures/interfaces provides you with a different feature set for SQL cursors.
    Choosing implicit cursors for example does not make the SQL cursor go faster. The SQL engine does not know and does not care, what client construct you are using to deal with the SQL cursor handle it gave you. It does not matter. It does not impact its SQL cursor performance.
    But on the client side, it can matter - as your code in dealing with that SQL cursor determines how fast your interaction with that SQL cursor is. How many context switches you make. How effectively you use and re-use the SQL (e.g. hard parsing vs soft parsing vs re-using the same cursor handle). Etc.
    Is there any single client cursor construct that is better? No.
    That is an ignorant view. The client language provides a toolbox, where each tool has a specific application. The knowledgeable developer will use the right tool for the job. The idiot developer will select one tool and use it as The Hammer to "solve" all the problems.

Maybe you are looking for