Ref Cursor Attribute

Hi
I wanted to take count of ref cursors return records.
I have added OUT parameter for procedure and i m returning records from this OUT parameter,
so i wanted to check count of record before returning it from procedure.
please do the needful.

also
there is no way way to find out how many records at all will be retrieved in a cursor BEFORE you fetch the very last row from it. Cursor_name%rowcount gives the number of rows selected so far and that count increments every time you fetch.
You use %rowcount only with implicit cursors that do insert/update/delete.

Similar Messages

  • [Solved] 27.8.4 How to Create a VO on a REF CURSOR - Missing first row

    Searching the forum I found: BC4J - Get one less row from view object.
    Dive into BC4J related  --REF CURSOR (Resultset)
    The first message did not have any answers, and the second had a follow up question - still no answers though - and I thought I would try a different title.
    (This is off topic, but it would be a great help if the search results also displayed the number of replys in the thread. That way, I wouldn't have to view the messages that don't have responses.)
    (This will be deployed on a server that has the ADF for JDeveloper 10.1.2 installed, so using that version of JDeveloper to develop the app.)
    Okay, back to the problem ==>
    I created a VO from a ref cursor, using the manual as a guide. When I run a page that displays a read only table of the view object, I am missing the first row. (Always the first row!) I don't have any order set, and if I call the ref cursor in a Java program for testing, I see all rows and the count is correct.
    One other point, when I call the page, I get the following validation error:
    Validation Error
    You must correct the following error(s) before proceeding:
    * JBO-29000: Unexpected exception caught: java.lang.ClassCastException, msg=null
    * null
    I still see the table, it is just missing the first row of data.
    In my form I have first, previous set, next set , and last
    navigation buttons. If I press last then first, the error goes away. I still don't see the missing row though.
    Any guidance would be appreciated! I can post my code, but it is pretty much the same code in the AdvancedViewObjectExamples.zip in the ViewObjectOnRefCursor example. I just substituted my two package calls (getRefCursor and getRefCursorCount).
    Thanks, Ken

    Went back to a backup copy of the source. Fixed the error. Now I'm back to just not being able to see the first row of data.
    Additional Note: I had removed fields in the display. Once I truncated the ps_txn table in the schema defined by the model, the data would display (Still without the first record.)
    Are there any examples that are more in depth than the few pages in the developer guide?
    Here is the code for my VOImpl class:
    package newslinearchive.model.datamodel;
    import java.math.BigDecimal;
    import java.sql.CallableStatement;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Timestamp;
    import java.sql.Types;
    import oracle.jbo.InvalidParamException;
    import oracle.jbo.JboException;
    import oracle.jbo.domain.Date;
    import oracle.jbo.domain.Number;
    import oracle.jbo.server.DBTransaction;
    import oracle.jbo.server.QueryCollection;
    import oracle.jbo.server.SQLBuilder;
    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;
    // --- File generated by Oracle ADF Business Components Design Time.
    // --- Custom code may be added to this class.
    // --- Warning: Do not modify method signatures of generated methods.
    public class SearchRefCursorImpl extends ViewObjectImpl {
    * This is the default constructor (do not remove)
    public SearchRefCursorImpl() {
    * Overridden framework method.
    * Executed when the framework needs to issue the database query for
    * the query collection based on this view object. One view object
    * can produce many related result sets, each potentially the result
    * of different bind variable values. If the rowset in query is involved
    * in a framework-coordinated master/detail viewlink, then the params array
    * will contain one or more framework-supplied bind parameters. If there
    * are any user-supplied bind parameter values, they will PRECEED the
    * framework-supplied bind variable values in the params array, and the
    * number of user parameters will be indicated by the value of the
    * numUserParams argument.
    protected void executeQueryForCollection(Object qc,Object[] params,int numUserParams) {
    storeNewResultSet(qc,retrieveRefCursor(qc,params));
    super.executeQueryForCollection(qc, params, numUserParams);
    * Overridden framework method.
    * Wipe out all traces of a built-in query for this VO
    protected void create() {
    getViewDef().setQuery(null);
    getViewDef().setSelectClause(null);
    setQuery(null);
    * Overridden framework method.
    * The role of this method is to "fetch", populate, and return a single row
    * from the datasource by calling createNewRowForCollection() and populating
    * its attributes using populateAttributeForRow().
    protected ViewRowImpl createRowFromResultSet(Object qc, ResultSet rs) {
    * We ignore the JDBC ResultSet passed by the framework (null anyway) and
    * use the resultset that we've stored in the query-collection-private
    * user data storage
    rs = getResultSet(qc);
    * Create a new row to populate
    ViewRowImpl r = createNewRowForCollection(qc);
    try {
    * Populate new row by attribute slot number for current row in Result Set
    // populateAttributeForRow(r,0, rs.getLong(1));
    // populateAttributeForRow(r,1, rs.getString(2));
    // populateAttributeForRow(r,2, rs.getString(3));
    // MASTERID NOT NULL NUMBER
    populateAttributeForRow(r,0, rs.getBigDecimal(1));
    //ID NOT NULL NUMBER
    populateAttributeForRow(r,1, rs.getBigDecimal(2));
    // CAID NOT NULL NUMBER
    populateAttributeForRow(r,2, rs.getBigDecimal(3));
    // LANGUAGE NOT NULL VARCHAR2(30)
    populateAttributeForRow(r,3, rs.getString(4));
    // IS_CURRENT_VERSION NOT NULL NUMBER(1)
    populateAttributeForRow(r,4, rs.getBigDecimal(5));
    // FOLDER_ID NOT NULL NUMBER
    populateAttributeForRow(r,5, rs.getBigDecimal(6));
    // FOLDER_REGION_ID NOT NULL NUMBER
    populateAttributeForRow(r,6, rs.getBigDecimal(7));
    // NAME NOT NULL VARCHAR2(256)
    populateAttributeForRow(r,7, rs.getString(8));
    // DISPLAY_NAME VARCHAR2(256)
    populateAttributeForRow(r,8, rs.getString(9));
    // ITEMTYPE NOT NULL VARCHAR2(30)
    populateAttributeForRow(r,9, rs.getString(10));
    // SUBTYPE VARCHAR2(40)
    populateAttributeForRow(r,10, rs.getString(11));
    // SUBTYPE_CAID NUMBER
    populateAttributeForRow(r,11, rs.getBigDecimal(12));
    // PARENT_ITEM_ID NUMBER
    populateAttributeForRow(r,12, rs.getBigDecimal(13));
    // CATEGORY_ID NUMBER
    populateAttributeForRow(r,13, rs.getBigDecimal(14));
    // CATEGORY_CAID NUMBER
    populateAttributeForRow(r,14, rs.getBigDecimal(15));
    // AUTHOR VARCHAR2(50)
    populateAttributeForRow(r,15, rs.getString(16));
    // DESCRIPTION VARCHAR2(2000)
    populateAttributeForRow(r,16, rs.getString(17));
    // PUBLISH_DATE NOT NULL DATE
    populateAttributeForRow(r,17, rs.getDate(18));
    // EXPIREMODE VARCHAR2(90)
    populateAttributeForRow(r,18, rs.getString(19));
    // EXPIRENUMBER NUMBER
    populateAttributeForRow(r,19, rs.getBigDecimal(20));
    // EXPIREDATE DATE
    populateAttributeForRow(r,20, rs.getDate(21));
    // IMAGE VARCHAR2(350)
    populateAttributeForRow(r,21, rs.getString(22));
    // KEYWORDS VARCHAR2(2000)
    populateAttributeForRow(r,22, rs.getString(23));
    // URL VARCHAR2(4000)
    populateAttributeForRow(r,23, rs.getString(24));
    // FILENAME VARCHAR2(350)
    populateAttributeForRow(r,24, rs.getString(25));
    // TEXT CLOB()
    populateAttributeForRow(r,25, rs.getClob(26));
    // FOLDER_LINK_ID NUMBER
    populateAttributeForRow(r,26, rs.getBigDecimal(27));
    // FOLDER_LINK_CAID NUMBER
    populateAttributeForRow(r,27, rs.getBigDecimal(28));
    // ACTIVE NOT NULL NUMBER(1)
    populateAttributeForRow(r,28, rs.getBigDecimal(29));
    // CAN_BE_CHECKEDOUT NUMBER(1)
    populateAttributeForRow(r,29, rs.getBigDecimal(30));
    // IS_ITEM_CHECKEDOUT NUMBER(1)
    populateAttributeForRow(r,30, rs.getBigDecimal(31));
    // CHECKER_USERNAME VARCHAR2(256)
    populateAttributeForRow(r,31, rs.getString(32));
    // CHECKOUT_DATE DATE
    populateAttributeForRow(r,32, rs.getDate(33));
    // FULLSCREEN NOT NULL NUMBER(1)
    populateAttributeForRow(r,33, rs.getBigDecimal(34));
    // INPLACE NOT NULL NUMBER(1)
    populateAttributeForRow(r,34, rs.getBigDecimal(35));
    // CREATEDATE NOT NULL DATE
    populateAttributeForRow(r,35, rs.getDate(36));
    // CREATOR NOT NULL VARCHAR2(256)
    populateAttributeForRow(r,36, rs.getString(37));
    // UPDATEDATE DATE
    populateAttributeForRow(r,37, rs.getDate(38));
    // UPDATOR VARCHAR2(256)
    populateAttributeForRow(r,38, rs.getString(39));
    // SECURITY VARCHAR2(25)
    populateAttributeForRow(r,39, rs.getString(40));
    // VISIBLE NOT NULL NUMBER(1)
    populateAttributeForRow(r,40, rs.getBigDecimal(41));
    // SEQUENCE NOT NULL NUMBER
    populateAttributeForRow(r,41, rs.getBigDecimal(42));
    // CATEGORY_SEQUENCE NOT NULL NUMBER
    populateAttributeForRow(r,42, rs.getBigDecimal(43));
    // AUTHOR_SEQUENCE NOT NULL NUMBER
    populateAttributeForRow(r,43, rs.getBigDecimal(44));
    // CREATE_DATE_SEQUENCE NOT NULL NUMBER
    populateAttributeForRow(r,44, rs.getBigDecimal(45));
    // ITEMTYPE_SEQUENCE NOT NULL NUMBER
    populateAttributeForRow(r,45, rs.getBigDecimal(46));
    catch (SQLException s) {
    throw new JboException(s);
    return r;
    * Overridden framework method.
    * Return true if the datasource has at least one more record to fetch.
    protected boolean hasNextForCollection(Object qc) {
    ResultSet rs = getResultSet(qc);
    boolean nextOne = false;
    try {
    nextOne = rs.next();
    * When were at the end of the result set, mark the query collection
    * as "FetchComplete".
    if (!nextOne) {
    setFetchCompleteForCollection(qc, true);
    * Close the result set, we're done with it
    rs.close();
    catch (SQLException s) {
    throw new JboException(s);
    return nextOne;
    * Overridden framework method.
    * The framework gives us a chance to clean up any resources related
    * to the datasource when a query collection is done being used.
    protected void releaseUserDataForCollection(Object qc, Object rs) {
    * Ignore the ResultSet passed in since we've created our own.
    * Fetch the ResultSet from the User-Data context instead
    ResultSet userDataRS = getResultSet(qc);
    if (userDataRS != null) {
    try {
    userDataRS.close();
    catch (SQLException s) {
    /* Ignore */
    super.releaseUserDataForCollection(qc, rs);
    * Overridden framework method
    * Return the number of rows that would be returned by executing
    * the query implied by the datasource. This gives the developer a
    * chance to perform a fast count of the rows that would be retrieved
    * if all rows were fetched from the database. In the default implementation
    * the framework will perform a SELECT COUNT(*) FROM (...) wrapper query
    * to let the database return the count. This count might only be an estimate
    * depending on how resource-intensive it would be to actually count the rows.
    public long getQueryHitCount(ViewRowSetImpl viewRowSet) {
    Long result = (Long)callStoredFunction(NUMBER,
    "PORTAL.SEARCH_REFCURSOR.getRefCursorCount",
    viewRowSet.getParameters(true));
    return result.longValue();
    // ------------- PRIVATE METHODS ----------------
    * Return a JDBC ResultSet representing the REF CURSOR return
    * value from our stored package function.
    * new Object[]{getNamedBindParamValue("Email",params)}
    private ResultSet retrieveRefCursor(Object qc, Object[] params) {
    ResultSet rs = (ResultSet)callStoredFunction(OracleTypes.CURSOR,
    "PORTAL.SEARCH_REFCURSOR.getRefCursor",
    null);
    return rs ;
    private Object getNamedBindParamValue(String varName, Object[] params) {
    Object result = null;
    if (getBindingStyle() == SQLBuilder.BINDING_STYLE_ORACLE_NAME) {
    if (params != null) {
    for (Object param : params) {
    Object[] nameValue = (Object[])param;
    String name = (String)nameValue[0];
    if (name.equals(varName)) {
    return (String)nameValue[1];
    throw new JboException("No bind variable named '"+varName+"'");
    * Store a new result set in the query-collection-private user-data context
    private void storeNewResultSet(Object qc, ResultSet rs) {
    ResultSet existingRs = getResultSet(qc);
    // If this query collection is getting reused, close out any previous rowset
    if (existingRs != null) {
    try {existingRs.close();} catch (SQLException s) {}
    setUserDataForCollection(qc,rs);
    hasNextForCollection(qc); // Prime the pump with the first row.
    * Retrieve the result set wrapper from the query-collection user-data
    private ResultSet getResultSet(Object qc) {
    return (ResultSet)getUserDataForCollection(qc);
    * Return either null or a new oracle.jbo.domain.Date
    private static Date nullOrNewDate(Timestamp t) {
    return t != null ? new Date(t) : null;
    * Return either null or a new oracle.jbo.domain.Number
    private static Number nullOrNewNumber(BigDecimal b) {
    try {
    return b != null ? new Number(b) : null;
    catch (SQLException s) { }
    return null;
    //----------------[ Begin Helper Code ]------------------------------
    public static int NUMBER = Types.NUMERIC;
    public static int DATE = Types.DATE;
    public static int VARCHAR2 = Types.VARCHAR;
    public static int CLOB = Types.CLOB;
    * Simplifies calling a stored function with bind variables
    * You can use the NUMBER, DATE, and VARCHAR2 constants in this
    * class to indicate the function return type for these three common types,
    * otherwise use one of the JDBC types in the java.sql.Types class.
    * NOTE: If you want to invoke a stored procedure without any bind variables
    * ==== then you can just use the basic getDBTransaction().executeCommand()
    * @param sqlReturnType JDBC datatype constant of function return value
    * @param stmt stored function statement
    * @param bindVars Object array of parameters
    * @return function return value as an Object
    protected Object callStoredFunction(int sqlReturnType, String stmt,
    Object[] bindVars) {
    CallableStatement st = null;
    try {
    st = getDBTransaction().createCallableStatement("begin ? := " + stmt +
    "; end;", 0);
    st.registerOutParameter(1, sqlReturnType);
    if (bindVars != null) {
    for (int z = 0; z < bindVars.length; z++) {
    st.setObject(z + 2, bindVars[z]);
    st.executeUpdate();
    return st.getObject(1);
    catch (SQLException e) {
    throw new JboException(e);
    finally {
    if (st != null) {
    try {
    st.close();
    catch (SQLException e) {}
    /**Gets the bind variable value for Email
    public String getEmail() {
    return (String)getNamedWhereClauseParam("Email");
    /**Sets <code>value</code> for bind variable Email
    public void setEmail(String value) {
    setNamedWhereClauseParam("Email", value);
    /**getEstimatedRowCount - overridden for custom java data source support.
    public long getEstimatedRowCount() {
    long value = super.getEstimatedRowCount();
    return value;
    Thanks, Ken

  • Manipulating data from a ref cursor in the data block of a form

    I am using Oracle Forms 10g. I have a ref cursor which returns columns A, B, C, D, E where B, C, D, E are values. The "Query Data Source Name" attribute in the datablock contains "CCTR_Extract_pkg.cctr_refcur". The "Column Name" attribute of item A contains "A", item B contains "B", etc. All of these columns are displayed on the form and it all works perfectly.
    I have a new request, the users would like a 6th column displayed - column F - where it equals D - B.
    Is there any way of doing this in the form only or do I need to change the ref cursor to accomodate the new column and then the form?
    If it can be achieved in the Form (only) - then how do I reference the 2 columns?
    Thanks in anticipation
    Michael
    Edited by: user8897365 on 24-Aug-2011 10:32

    Is there any way of doing this in the form only or do I need to change the ref cursor to accomodate the new column and then the form? The REF_CURSOR is the data source of your block so you will have to modify the CCTR_Extract_pkg package and cctr_refcur REF_CURSOR.
    If it can be achieved in the Form (only) - then how do I reference the 2 columns?After you have modified your database package, I recommend you run the Data Block Wizard on your block and let Forms detect the 2 new columns. You can do this manually, but it is safer to let Forms do it for you. If you want to do it manually, open the Query Data Source Columns property and add your new columns.
    Hope this helps,
    Craig B-)
    If someone's response is helpful or correct, please mark it accordingly.

  • How to get an UPDATABLE REF CURSOR from the STORED PROCEDURE

    using C# with
    ORACLE OLE DB version: 9.0.0.1
    ADO version: 2.7
    I returns a REF CURSOR from a stored procedure seems like:
    type TCursor is ref cursor;
    procedure test_out_cursor(p_Dummy in varchar, p_Cur out TCursor) is
    begin
         open p_Cur for select * from DUAL;
    end;
    I create an ADO Command object and set
    cmd.Properties["IRowsetChange"].Value = true;
    cmd.Properties["Updatability"].Value = 7;
    cmd.Properties["PLSQLRSet"].Value = 1;
    cmd.CommandText = "{CALL OXSYS.TEST.TEST_OUT_CURSOR(?)}";
    and I use a Recordset object to open it:
    rs.Open(cmd, Missing.Value,
    ADODB.CursorTypeEnum.adOpenStatic,
    ADODB.LockTypeEnum.adLockBatchOptimistic,
    (int) ADODB.CommandTypeEnum.adCmdText +
    (int) ADODB.ExecuteOptionEnum.adOptionUnspecified);
    The rs can be opened but can NOT be updated!
    I saved the recordset into a XML file and there's no
    rs:baseschema/rs:basetable/rs:basecolumn
    attributes for "s:AttributeType" element.
    Any one have idea about this?
    thanks very much

    It is not possible through ADO/OLEDB.
    Try ODP.NET currently in Beta, it is possible to update DataSet created with refcursors. You need to specify your custom SQL or SP to send update/insert/delete.
    As I remember there is a sample with ODP.NET Beta 1 just doing this.

  • Ref cursors in Database adapter

    Hi,
    Is the database adapter capable of handling ref cursors as the datatype of the output parameters of a pl/sql procedure?
    For instance if I have the following in my package-spec:
    TYPE SomeRecordType IS RECORD
    ( record_pk mut_table.record_pk%TYPE
    , person_nr person_table.person_nr%TYPE
    , field_1 mut_table.field_1%type
    , field_2 mut_table.field_2%type
    , field_3 mut_table.field_3%type
    TYPE SomeCursorType IS REF CURSOR RETURN SomeRecordType;
    PROCEDURE read_records
    ( cursor_out OUT SomeCursorType
    , exception_code OUT number
    , exception_message OUT varchar2
    Can the database adapter call the read_records procedure?
    I've never seen this in any doc. I know it can't handle record types (that is in 10.1.2 it couldn't as far as I know). So I figure that the above is not possible.
    Thanks in advance.
    Regards,
    Martien

    We have successfully used a sys_refcursor OUT parameter for a database procedure call and which is used by a DBAdapter to return a single dataset.
    At the time I remember attempting to use a strongly typed ref cursor as the parameter. I think this is what you are attempting to do. I rejected this approach at the time as I was not able to do this. It was, in our case, as simple as using the system defined ref cursor type (i.e. weakly typed).
    The handling of the returned dataset was not immediately obvious, but can be handled by as fairly simple XSL transformation to a locally defined variable of the requisite xml structure. I won't describe in detail how to do it as it is specific to our process. Suffice to say the transformation loops over all result rows assign via a test to the correct result field in our local variable.
    e.g.
    <xsl:template match="/">
    <ns1:BatchRequest004>
    <xsl:for-each select="/db:OutputParameters/db:P_SCHSHP_REF_CUR/db:Row">
    <ns1:statusRqst>
    <xsl:if test='db:Column/@name = "ID"'>
    <xsl:attribute name="id">
    <xsl:value-of select="db:Column[1.0]"/>
    </xsl:attribute>
    </xsl:if>
    </ns1:statusRqst>
    </xsl:for-each>
    </ns1:BatchRequest004>
    HTH and that I haven't misidentified your problem.

  • XSQL ERROR with bind-params in ref-cursor-function

    Hi Steve
    I always get the error
    ORA-01006 bind variable does not exist
    when using a bind variable in a <xsql:ref-cursor-function> action element.
    when I replace the bind variable with a @ - parameter substitution, all works fine.
    My configuration:
    XSQL 1.0.4.1 on Win200Pro ,Apache + Jserv + DB from ORA 8.1.7 installation
    My Source
    <xsql:ref-cursor-function
    dbconn="ekat"
    eblike="%"
    list="a0"
    bind-params="eblike"
    include-schema="no"
    null-indicator="no"
    id-attribute=""
    fetch-size="500"
    >
    {@dbconn}o.ekatkategcv.open_cv_ebh ('{@list}', :1)
    </xsql:ref-cursor-function>
    ( dbconn selects my schema, not changed often, which contains package ekatkategcv with
    function open_cv_ebh returning a cursor)
    Any fix would be appreciated to avoid reparsing on each call.
    BTW, is it right, that a ref-cursor funtion is reparsed whenever the content of
    a parameter used with @ changes?
    Best regards
    H.Buschmann ([email protected])
    null

    I have tried it using ? instead of :1, this method works fine.
    I haven't tried the name method (:bindvar) yet.
    Until now, I only used xsl:query and xsql:ref-cursor-function, so I didn't check
    the other action handlers with bind variables like :1
    null

  • PL/SQL Cursor-attribute %ROWCOUNT

    Hi to everybody,
    I have a question regrading to Cursor attributes.
    I'm written a funtion(you can see the code below) with REF CURSOR as its Return value.
    Now I want to use the Cursor Attribute ROWCOUNT to check out how many rows the function gives back, but I always become 0.
    The funtion itself work without any problems except for the ROWCOUNT Attribute which gives always 0 back.
    Can somebody told me what I make wrong????
    Thanxxx
    Schoeib Amin
    Create or Replace Function PIFS.indizierteWerte_fr_test
    (match IN string,
    Dauer IN number)
    return
    types.cursorType --Package where I defined a REF CURSOR TYPE
    AS
    Rate1 number;
    match_ VARCHAR2(15);
    c_cursor types.cursorType;
    Anfangsdatum date;
    jetziges_datum date;
    Anzahl number;
    BEGIN
    match_:=match;
    Anfangsdatum:=gebe_anfangsdatum(Dauer);
    jetziges_Datum:=sysdate;
    Rate1:=berechne_fr(match_,Anfangsdatum);
    OPEN c_cursor FOR
    Select
    (fr.indiziert)*Rate1 INDIZIERT,fr.DATUM
    from
    fondsreihe fr
    where
    fr.match=match_
    and fr.Datum between Anfangsdatum and to_char(jetziges_Datum,'DD.MM.YYYY') order by fr.DATUM;
    anzahl:=c_cursor%ROWCOUNT;
    dbms_output.put_line(anzahl);
    return c_cursor;
    END indizierteWerte_fr_test;

    Schoeib: Your function is defined as returning a REF CURSOR, there fore it must return a REF CURSOR. You cannot assign a number to a REF CURSOR variable to get sround this. If all you want to do in your function is get the number of rows returned by the dursor, then change the return type of the function to NUMBER, then iterate through the cursor to get the row count.
    Gavin: Unfortunately, there is no way to get the number of rows returned from a statement without executing the statement. If you are using the Cost Based Optimizer, and all tables in the query are correctly (i.e. recently) analyzed, and you have also analysed the columns, then the Explain plan would give a reasonable (but no guarantees) extimate of the number of rows the query will return.

  • Using a ref cursor

    I have a function that I created and am trying to use it to output data using a ref cursor. My function call is
    declare
    ret_cursor crsiweb.types.cursorType;
    type output_rec_type is record(
    location varchar2(100),
    client varchar2(100),
    number_in long,
    number_out long,
    total_cost varchar2(100),
    total_charge varchar2(100),
    net varchar2(100),
    average varchar2(100)
    output output_rec_type;
    begin
    ret_cursor := all_db.net_profit.net_profit(to_date(:P1_Date_Chart,'DD-Mon-RR'));
    fetch ret_cursor into output;
    dbms_output.put_line('Location' || ',' || 'Company'|| ',' || 'In' ||
    ','|| 'Out'|| ',' || 'Cost'|| ',' || 'Charge'
    || ',' || 'Net' || ',' || '30 Day Average');
    while ret_cursor%FOUND loop
    dbms_output.put_line(output.location || ',' || output.client || ',' || output.number_in ||
    ','|| output.number_out || ',' || output.total_cost || ',' || output.total_charge
    || ',' || output.net || ',' || output.average);
    fetch ret_cursor into output;
    end loop;
    close ret_cursor;
    end;
    i have it as a PL/SQL Procedure (anonymous block) in a region. When executed I get the following error:
    "ORA-06550: line 15, column 25: PLS-00904: insufficient privilege to access object ALL_DB.NET_PROFIT ORA-06550: line 15, column 4: PL/SQL: Statement ignored"
    The function is as follows: ( I created the function in OEM)
    create or replace procedure all_db.net_profit.net_profit
    as
    function net_profit(sdate IN date) return crsiweb.types.cursortype as
    ret_cursor crsiweb.types.cursortype;
    begin
    open ret_cursor for select 'a_chase' "Location",a."Client" "Client", sum(nvl(b."In",0)) "In", sum(nvl(a."Out",0)) "Out", to_char(sum(nvl(a."Cost",0)
    + nvl(b."Cost",0)),'FM$9999999990.00PR') "Cost",
    to_char(sum(nvl(a."Charge",0) + nvl(b."Charge",0)),'FM$9999999990.00PR') "Charge", to_char(sum(nvl(a."Net",0)
    + nvl(b."Net",0)),'FM$9999999990.00PR') "Net",
    to_char(sum(nvl("Average",0)),'FM$9999999990.00PR') "30 Day Average"
    -- Get Out, Cost, Net by date_out
    from (select client_name "Client", count(date_sent) "Out",
    round(sum(nvl(product_cost,0) + nvl(acost1,0) + nvl(acost2,0) + nvl(acost3,0) +
    nvl(acost4,0) + nvl(acost5,0) + nvl(acost6,0) + nvl(acost7,0)
    + nvl(acost8,0) + nvl(acost9,0) + nvl(acost10,0)),2)"Cost",
    round(sum(nvl(product_fee,0) + nvl(copy_fee,0) + nvl(afee1,0) + nvl(afee2,0)+ nvl(afee3,0)
    + nvl(afee4,0)+ nvl(afee5,0)+ nvl(afee6,0)+ nvl(afee7,0)+ nvl(afee1,8)+ nvl(afee1,9)
    + nvl(afee1,10)),2) "Charge",
    round(sum((nvl(product_fee,0) + nvl(copy_fee,0) + nvl(afee1,0) + nvl(afee2,0)+ nvl(afee3,0)
    + nvl(afee4,0)+ nvl(afee5,0)+ nvl(afee6,0)+ nvl(afee7,0)+ nvl(afee1,8)+ nvl(afee1,9)
    + nvl(afee1,10)) - (nvl(product_cost,0) + nvl(acost1,0) + nvl(acost2,0) + nvl(acost3,0) +
    nvl(acost4,0) + nvl(acost5,0) + nvl(acost6,0) + nvl(acost7,0)
    + nvl(acost8,0) + nvl(acost9,0) + nvl(acost10,0))),2) "Net"
    from a_chase.jim a
    inner join a_chase.clients b
    on a.clientid = b.clientid
    where trunc(date_sent) = trunc(sdate)
    group by client_name) a
    --Get In, Cost, Net by date_In
    left outer join (select client_name "Client", count(date_in) "In",
    round(sum(nvl(product_cost,0) + nvl(acost1,0) + nvl(acost2,0) + nvl(acost3,0) +
    nvl(acost4,0) + nvl(acost5,0) + nvl(acost6,0) + nvl(acost7,0)
    + nvl(acost8,0) + nvl(acost9,0) + nvl(acost10,0)),2)"Cost",
    round(sum(nvl(product_fee,0) + nvl(copy_fee,0) + nvl(afee1,0) + nvl(afee2,0)+ nvl(afee3,0)
    + nvl(afee4,0)+ nvl(afee5,0)+ nvl(afee6,0)+ nvl(afee7,0)+ nvl(afee1,8)+ nvl(afee1,9)
    + nvl(afee1,10)),2) "Charge",
    round(sum((nvl(product_fee,0) + nvl(copy_fee,0) + nvl(afee1,0) + nvl(afee2,0)+ nvl(afee3,0)
    + nvl(afee4,0)+ nvl(afee5,0)+ nvl(afee6,0)+ nvl(afee7,0)+ nvl(afee1,8)+ nvl(afee1,9)
    + nvl(afee1,10)) - (nvl(product_cost,0) + nvl(acost1,0) + nvl(acost2,0) + nvl(acost3,0) +
    nvl(acost4,0) + nvl(acost5,0) + nvl(acost6,0) + nvl(acost7,0)
    + nvl(acost8,0) + nvl(acost9,0) + nvl(acost10,0))),2) "Net"
    from a_chase.jim a
    inner join a_chase.clients b
    on a.clientid = b.clientid
    where trunc(date_in) = trunc(sdate)
    group by client_name) b
    on a."Client" = b."Client"
    -- Get 30 Day Average
    inner join (select client_name, round(avg("Net"),2) "Average" from
    (select trunc(date_in) "In", client_name, round(sum((nvl(product_fee,0) + nvl(copy_fee,0) + nvl(afee1,0) + nvl(afee2,0)+ nvl(afee3,0)
    + nvl(afee4,0)+ nvl(afee5,0)+ nvl(afee6,0)+ nvl(afee7,0)+ nvl(afee1,8)+ nvl(afee1,9)
    + nvl(afee1,10)) - (nvl(product_cost,0) + nvl(acost1,0) + nvl(acost2,0) + nvl(acost3,0) +
    nvl(acost4,0) + nvl(acost5,0) + nvl(acost6,0) + nvl(acost7,0)
    + nvl(acost8,0) + nvl(acost9,0) + nvl(acost10,0))),2) "Net"
    from a_chase.jim a
    inner join a_chase.clients b
    on a.clientid = b.clientid
    where trunc(date_in) between (trunc(sdate) - 30) and trunc(sdate)
    group by trunc(date_in), client_name)
    group by client_name) c
    on a."Client" = c.client_name
    group by a."Client"
    union --BU_TS
    select 'bu_ts' "Location",a."Client" "Client", sum(nvl(b."In",0)) "In", sum(nvl(a."Out",0)) "Out", to_char(sum(nvl(a."Cost",0)
    + nvl(b."Cost",0)),'FM$9999999990.00PR') "Cost",
    to_char(sum(nvl(a."Charge",0) + nvl(b."Charge",0)),'FM$9999999990.00PR') "Charge", to_char(sum(nvl(a."Net",0)
    + nvl(b."Net",0)),'FM$9999999990.00PR') "Net",
    to_char(sum(nvl("Average",0)),'FM$9999999990.00PR') "30 Day Average"
    -- Get Out, Cost, Net by date_out
    from (select client_name "Client", count(date_sent) "Out",
    round(sum(nvl(product_cost,0) + nvl(acost1,0) + nvl(acost2,0) + nvl(acost3,0) +
    nvl(acost4,0) + nvl(acost5,0) + nvl(acost6,0) + nvl(acost7,0)
    + nvl(acost8,0) + nvl(acost9,0) + nvl(acost10,0)),2)"Cost",
    round(sum(nvl(product_fee,0) + nvl(copy_fee,0) + nvl(afee1,0) + nvl(afee2,0)+ nvl(afee3,0)
    + nvl(afee4,0)+ nvl(afee5,0)+ nvl(afee6,0)+ nvl(afee7,0)+ nvl(afee1,8)+ nvl(afee1,9)
    + nvl(afee1,10)),2) "Charge",
    round(sum((nvl(product_fee,0) + nvl(copy_fee,0) + nvl(afee1,0) + nvl(afee2,0)+ nvl(afee3,0)
    + nvl(afee4,0)+ nvl(afee5,0)+ nvl(afee6,0)+ nvl(afee7,0)+ nvl(afee1,8)+ nvl(afee1,9)
    + nvl(afee1,10)) - (nvl(product_cost,0) + nvl(acost1,0) + nvl(acost2,0) + nvl(acost3,0) +
    nvl(acost4,0) + nvl(acost5,0) + nvl(acost6,0) + nvl(acost7,0)
    + nvl(acost8,0) + nvl(acost9,0) + nvl(acost10,0))),2) "Net"
    from bu_ts.jim a
    inner join bu_ts.clients b
    on a.clientid = b.clientid
    where trunc(date_sent) = trunc(sdate)
    group by client_name) a
    --Get In, Cost, Net by date_In
    left outer join (select client_name "Client", count(date_in) "In",
    round(sum(nvl(product_cost,0) + nvl(acost1,0) + nvl(acost2,0) + nvl(acost3,0) +
    nvl(acost4,0) + nvl(acost5,0) + nvl(acost6,0) + nvl(acost7,0)
    + nvl(acost8,0) + nvl(acost9,0) + nvl(acost10,0)),2)"Cost",
    round(sum(nvl(product_fee,0) + nvl(copy_fee,0) + nvl(afee1,0) + nvl(afee2,0)+ nvl(afee3,0)
    + nvl(afee4,0)+ nvl(afee5,0)+ nvl(afee6,0)+ nvl(afee7,0)+ nvl(afee1,8)+ nvl(afee1,9)
    + nvl(afee1,10)),2) "Charge",
    round(sum((nvl(product_fee,0) + nvl(copy_fee,0) + nvl(afee1,0) + nvl(afee2,0)+ nvl(afee3,0)
    + nvl(afee4,0)+ nvl(afee5,0)+ nvl(afee6,0)+ nvl(afee7,0)+ nvl(afee1,8)+ nvl(afee1,9)
    + nvl(afee1,10)) - (nvl(product_cost,0) + nvl(acost1,0) + nvl(acost2,0) + nvl(acost3,0) +
    nvl(acost4,0) + nvl(acost5,0) + nvl(acost6,0) + nvl(acost7,0)
    + nvl(acost8,0) + nvl(acost9,0) + nvl(acost10,0))),2) "Net"
    from bu_ts.jim a
    inner join bu_ts.clients b
    on a.clientid = b.clientid
    where trunc(date_in) = trunc(sdate)
    group by client_name) b
    on a."Client" = b."Client"
    -- Get 30 Day Average
    inner join (select client_name, round(avg("Net"),2) "Average" from
    (select trunc(date_in) "In", client_name, round(sum((nvl(product_fee,0) + nvl(copy_fee,0) + nvl(afee1,0) + nvl(afee2,0)+ nvl(afee3,0)
    + nvl(afee4,0)+ nvl(afee5,0)+ nvl(afee6,0)+ nvl(afee7,0)+ nvl(afee1,8)+ nvl(afee1,9)
    + nvl(afee1,10)) - (nvl(product_cost,0) + nvl(acost1,0) + nvl(acost2,0) + nvl(acost3,0) +
    nvl(acost4,0) + nvl(acost5,0) + nvl(acost6,0) + nvl(acost7,0)
    + nvl(acost8,0) + nvl(acost9,0) + nvl(acost10,0))),2) "Net"
    from bu_ts.jim a
    inner join bu_ts.clients b
    on a.clientid = b.clientid
    where trunc(date_in) between (trunc(sdate) - 30) and trunc(sdate)
    group by trunc(date_in), client_name)
    group by client_name) c
    on a."Client" = c.client_name
    group by a."Client"
    union --BU
    select 'BU' "Location", a."Company" "Client", sum(nvl(b."In",0)) "In", sum(nvl(a."Out",0)) "Out", to_char(sum(nvl(a."Cost",0)
    + nvl(b."Cost",0)),'FM$9999999990.00PR') "Cost",
    to_char(sum(nvl(a."Charge", 0) + nvl(b."Charge",0)),'FM$9999999990.00PR') "Charge", to_char(sum(nvl(a."Net",0)
    + nvl(b."Net",0)),'FM$9999999990.00PR') "Net",
    to_char(sum(nvl("Average",0)),'FM$9999999990.00PR') "30 Day Average"
    from
    (--Out Query
    select b.clcompanyname "Company", count(*) "Out",
    round(sum(nvl(cost1,0) + nvl(cost2,0) + nvl(cost3,0) + nvl(cost4,0) + nvl(cost5,0) + nvl(costx1,0)
    + nvl(costx2,0)+ nvl(costx3,0)+ nvl(costx4,0)+ nvl(costx5,0)+ nvl(costy1,0)+ nvl(costy2,0)+ nvl(costy3,0)
    + nvl(costy4,0)+ nvl(costy5,0)),2) "Cost",
    round(sum(nvl(fee1,0) + nvl(fee2,0) + nvl(fee3,0) + nvl(fee4,0) + nvl(fee5,0) + nvl(feex1,0)
    + nvl(feex2,0)+ nvl(feex3,0)+ nvl(feex4,0)+ nvl(feex5,0)+ nvl(feey1,0)+ nvl(feey2,0)+ nvl(feey3,0)
    + nvl(feey4,0)+ nvl(feey5,0)),2) "Charge",
    round( sum(nvl(fee1,0) + nvl(fee2,0) + nvl(fee3,0) + nvl(fee4,0) + nvl(fee5,0) + nvl(feex1,0)
    + nvl(feex2,0)+ nvl(feex3,0)+ nvl(feex4,0)+ nvl(feex5,0)+ nvl(feey1,0)+ nvl(feey2,0)+ nvl(feey3,0)
    + nvl(feey4,0)+ nvl(feey5,0) - nvl(cost1,0) - nvl(cost2,0) - nvl(cost3,0) - nvl(cost4,0) - nvl(cost5,0) - nvl(costx1,0)
    - nvl(costx2,0)- nvl(costx3,0)- nvl(costx4,0)- nvl(costx5,0)- nvl(costy1,0)- nvl(costy2,0)- nvl(costy3,0)
    - nvl(costy4,0)- nvl(costy5,0)),2) "Net"
    from [email protected] a
    inner join [email protected] b
    on a.clientid = b.clientid
    where trunc(compdate1) = trunc(sdate)
    or trunc(compdate2) = trunc(sdate)
    or trunc(compdate3) = trunc(sdate)
    or trunc(compdate4) = trunc(sdate)
    or trunc(compdate5) = trunc(sdate)
    group by b.clcompanyname) a
    --in Query
    left outer join (select b.clcompanyname "Company", count(a.loandatein) "In",
    round(sum(nvl(cost1,0) + nvl(cost2,0) + nvl(cost3,0) + nvl(cost4,0) + nvl(cost5,0) + nvl(costx1,0)
    + nvl(costx2,0)+ nvl(costx3,0)+ nvl(costx4,0)+ nvl(costx5,0)+ nvl(costy1,0)+ nvl(costy2,0)+ nvl(costy3,0)
    + nvl(costy4,0)+ nvl(costy5,0)),2) "Cost",
    round(sum(nvl(fee1,0) + nvl(fee2,0) + nvl(fee3,0) + nvl(fee4,0) + nvl(fee5,0) + nvl(feex1,0)
    + nvl(feex2,0)+ nvl(feex3,0)+ nvl(feex4,0)+ nvl(feex5,0)+ nvl(feey1,0)+ nvl(feey2,0)+ nvl(feey3,0)
    + nvl(feey4,0)+ nvl(feey5,0)),2) "Charge",
    round( sum(nvl(fee1,0) + nvl(fee2,0) + nvl(fee3,0) + nvl(fee4,0) + nvl(fee5,0) + nvl(feex1,0)
    + nvl(feex2,0)+ nvl(feex3,0)+ nvl(feex4,0)+ nvl(feex5,0)+ nvl(feey1,0)+ nvl(feey2,0)+ nvl(feey3,0)
    + nvl(feey4,0)+ nvl(feey5,0) - nvl(cost1,0) - nvl(cost2,0) - nvl(cost3,0) - nvl(cost4,0) - nvl(cost5,0) - nvl(costx1,0)
    - nvl(costx2,0)- nvl(costx3,0)- nvl(costx4,0)- nvl(costx5,0)- nvl(costy1,0)- nvl(costy2,0)- nvl(costy3,0)
    - nvl(costy4,0)- nvl(costy5,0)),2) "Net"
    from [email protected] a
    inner join [email protected] b
    on a.clientid = b.clientid
    where trunc(a.loandatein) = trunc(sdate)
    group by b.clcompanyname) b
    on a."Company" = b."Company"
    --Avg Query
    inner join (select "Company", round(avg("Net"),2) "Average" from
    (select trunc(loandatein) "In", b.clcompanyname "Company",
    round( sum(nvl(fee1,0) + nvl(fee2,0) + nvl(fee3,0) + nvl(fee4,0) + nvl(fee5,0) + nvl(feex1,0)
    + nvl(feex2,0)+ nvl(feex3,0)+ nvl(feex4,0)+ nvl(feex5,0)+ nvl(feey1,0)+ nvl(feey2,0)+ nvl(feey3,0)
    + nvl(feey4,0)+ nvl(feey5,0) - nvl(cost1,0) - nvl(cost2,0) - nvl(cost3,0) - nvl(cost4,0) - nvl(cost5,0) - nvl(costx1,0)
    - nvl(costx2,0)- nvl(costx3,0)- nvl(costx4,0)- nvl(costx5,0)- nvl(costy1,0)- nvl(costy2,0)- nvl(costy3,0)
    - nvl(costy4,0)- nvl(costy5,0)),2) "Net"
    from [email protected] a
    inner join [email protected] b
    on a.clientid = b.clientid
    where trunc(loandatein) between (trunc(sdate) - 30) and trunc(sdate)
    group by trunc(loandatein), b.clcompanyname)
    group by "Company") c
    on a."Company" = c."Company"
    group by a."Company";
    return(ret_cursor);
    end;
    end;
    I also have given htmldb_public_user grant/execute privileges on this function. Any help would be greatly appreciated.
    Thanks,
    Scott

    thanks, lalit. that's almost correct. htmldb_public_user is the username through which the mod_plsql DAD connects to the database. he has just the privs he needs to serve that function. the htmldb engine compiles into a FLOWS_010500 schema in the production release. having said that, lalit's suggestion is correct. you need to make sure your htmldb application schema (identified by the application-level attribute "Default Parsing Schema") has been directly granted privileges (directly as opposed to coming through a role rant) to run the objects it's calling.
    hope this helps,
    raj

  • 26.4 Basing an entity Object on a PL/SQL Package API - Ref Cursor, no View

    I am hoping that I could get some help in the details of a problem. I am trying to follow the directions in the Oracle Application Development Framework Developer's Guide for Forms/4GL Developers, Section 26.4 - Basing an Entity Object on a PL/SQL Package API.
    There is example code in the downloadable AdvancedEntityExamples - EntityWrappingPL/SQLPackage
    The question is, how will the implementation change if the entity is based entirely on PL/SQL - simply stated - no view is available, just ref cursors and insert,update,delete procedures.
    In the example code, there are two procedures, lock_product and select_product. This is where things get more complicated. I can create a function to return a single record ref cursor, instead of the list of OUT variables defined in both functions (select_product and lock_product). It makes sense that I just return one cursor and get all of the columns from that instead of lots of OUT variables.
    So what's stopping me you may ask... There is one difference between select_product and select_lock. Select_lock has a select that includes "FOR UPDATE NOWAIT". I don't have that as an option when creating my ref cursor. I am not sure what the impact of "FOR UPDATE NOWAIT" is? Can I ignore it?
    In the problem I am working with, (getting data from Oracle Portal 10.1.4) I return the following:
    function getRefCursor return ref_cursor is
    v_tab wwsbr_all_items_object_type := wwsbr_all_items_object_type();
    p_recordset wwsbr_types.cursor_type;
    l_results wwsrc_api.items_result_array_type;
    begin
    wwctx_api.set_context(<username>,<password>);
    l_results := wwsrc_api.item_search(.. parameters..);
    <snip>
    ... Loop through the objects and populate v_tab
    <snip>
    open p_recordset for
    select * from table(cast(v_tab as wwsbr_all_items_object_type));
    return p_recordset;
    end getRefCursor;
    With this sample, it would be easy to return a single row by passing the masterid as a parameter.
    So I am still left with, how should the implementation of callLockProcedureAndCheckForRowInconsistency() and callSelectProcedure() be changed in order to use a ref cursor instead of a view? The user guide was missing that extra section <bg>.
    What would be REALLY helpful, is an example, say 26.4A that demonstrates creating an entity object from a ref cursor and procedures from PL/SQL only without a view.
    Thank you, Ken

    The lock procedure is expected to obtain a row-level lock on the row, given its key.
    Depending on the setting of jbo.locking.mode, the entity object's lock() method will be invoked either as soon as the first persistent attribute is successfully modified by the user (in the case of jbo.locking.mode=pessimistic), or it will be called during commit processing just before the row is updated in the database (with jbo.locking.mode=optimistic).
    Usually 2-tier Swing applications use pessimistic mode, while web applications use optimistic mode.
    The FOR UPDATE NOWAIT is the Oracle clause that can be appened to a SELECT statement to acquire a row-level lock on the selected rows. The NOWAIT modifier means that rather than hanging, waiting for a row locked by another user to free up, it will raise an exception if any of the rows being selected-and-locked are not available to lock.
    If you're not able to work the FOR UPDATE NOWAIT into the syntax of the ref cursor, perhaps you can initially perform the lock using a different cursor inside the stored procedure, then return your ref cursor.

  • What is the better approach to populate Ref cursor into ADF business Component

    HI All,
    I have a requirement where I get the search results by joining more than 10 tables for my search criteria.
    What is the best approach to populate into ADF BCs.
    I have to go with Stored Procedure approach where I input the search Criteria and get the cursor back from the same.
    If I populate VO programmatically then the filtering at column level is a challenge.
    Anyone Please help me. Thanks in Advance.
    Thanks,
    Balaji Mucheli.

    The number of tables to be joined for a VO's query shouldn't matter - if the query is valid and fixed.
    Are you saying that you have logic to decide which tables to join to create the correct query?  I admit that would be a difficult thing to do, other than with a programmatic VO.  However, there are two possible solutions for doing this without a programmatic VO.
    Instead of your procedure returning a REF CURSOR, you can create an object type (CREATE TYPE) and a nested table of that type.  Then you have a function that returns an instance of the nested table.  The query in the VO is SELECT my_column... FROM TABLE(CAST my_table_function(:bind_variable) AS my_table_type).  You may have trouble getting the VO to accept this query as valid SQL, but it IS valid and it DOES work.
    Create a VO to be the master VO - it should have all the attributes that you intend to use, but the query can be anything, even a SELECT from DUAL.  Then create other VOs that subclass the master VO - one for each major variation of the query.  When you use the VO, use the data control for the master VO to create your pages, but change the pageDef to make the VO name a variable (with expression language).  Then you can set that variable to the correct child VO for the query that needs to execute.

  • Dive into BC4J related  --REF CURSOR

    I read through the article (Dive into BC4J )and generated several questions:
    1)If I have to execute a ref cursor:
    private static final String SQL =
    "begin ? := RefCursor.getSomthing(?, ?);end;";
    Now I need to pass two parameters to the stored procedure,
    assume first is ID varchar2, second Name varchar2
    In my client code: I use vo.executeQuery()
    then how can I pass these two parameters? (so that the executeQueryForCollection(Object qc,Object[] params,int numUserParams) can use them)
    NOTES: The viewobject I created is not based on any sql statement, but an expert mode, i.e., I created the attributes myself.
    2)createRowFromResultSet(...) function calls
    populateAttributeForRow(r,0, nullOrNewNumber(rs.getBigDecimal(1)));
    If there are more than one rows in the reseultset, will
    this function be called "automatically" by the frame work to iterate through each every row in the resultset?
    Thanks.
    Scott

    In short, yes. :-)

  • 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.

Maybe you are looking for