Using a strongly typed ref cursor doesn't enforce data type

I am trying to enforce the datatypes of the fields coming back from an oracle reference cursor by making it strongly typed. However, there seems to be no warning at compile time on the oracle side or exception in ODP.NET if the datatype coming back in the cursor does not match. For example here is my cursor and proc
create or replace
PACKAGE THIRDPARTY AS
type pricing_record is record
BaseIndexRate     number(6,5),
BaseIndexRateType     VARCHAR2(1 BYTE)
type cur_pricing2 IS ref CURSOR return pricing_record;
PROCEDURE getpricingbyappidtest(appid IN application.intid%TYPE, pricing OUT cur_pricing2);
END THIRDPARTY;
create or replace
PACKAGE BODY THIRDPARTY AS
PROCEDURE getpricingbyappidtest(appid IN application.appid%TYPE, pricing OUT cur_pricing2)
AS
BEGIN
     OPEN pricing FOR
     SELECT      somevarcharfield, someothervarcharfield
FROM application
WHERE A.appid = appid;
END getpricingbyappidtest;
I would expect this wouldn't compile since i am putting a varchar into a number field. But it does. Also if i check the datatype in the reader on the .net side it also is a string. So odp doesn't seem to care what type the cursor is
here is that code and output
var schemaTable = reader.GetSchemaTable();
using (var file = new System.IO.StreamWriter("c:\\_DefinitionMap_" + cursorName + ".txt"))
file.WriteLine("COLUMN" + "\t" + "DATATYPE");
foreach (DataRow myField in schemaTable.Rows)
file.WriteLine(myField["ColumnName"] + "\t" + myField["DataType"]);
COLUMN     DATATYPE
BaseIndexRate     System.String
BaseIndexRateType     System.String
Does anyone have an approach for enforcing datatypes in a ref cursor? Am I doing something wrong when defining the ref cursor?

Hello,
By using a ref cursor you are really using a pointer to a cursor. There is no way I know of to make a compile check of the cursor check unless you want to create a SQL type and cast the cursor to this type and even this wouldn't work in all cases. For instance, I could have function call within my cursor select which could return a varchar (with a number always in the varchar) which would be horribly sloppy but legal and you would expect Oracle to compile it.
If you are worried about this I would suggest not using ref cursors and go to UDT instead, where there will be more checking (because of a C# equivalence generated object). Oh and BTW, yes the cursor will throw an exception if the data is incorrect, but only at runtime - just like normal Oracle PLSQL.
Cheers
Rob.
http://www.scnet.com.au

Similar Messages

  • Return csv string as strongly typed ref cursor

    I have a column in a table that is csv delimited and I want to return it (and others) as a strongly typed ref cursor.
    eg
    create table test_tab (mydata varchar2(100))
    insert into test_tab(mydata) values ('"a1","b1","c1","d1"')
    insert into test_tab(mydata) values ('"a2","b2","c2","d2"')
    so test_tab has 1 column and 2 rows:
    "a1","b1","c1","d1"
    "a2","b2","c2","d2"
    So a,b,c,d represent columns in my strongly typed ref cursor
    If I then try something like:
    declare
    type my_rec is record(
    a varchar2(50),
    b varchar2(50),
    c varchar2(50),
    d varchar2(50)
    type my_rec_refc IS REF CURSOR RETURN my_rec;
    my_test_refc my_rec_refc;
    begin
    open my_test_refc for select mydata,mydata,mydata,mydata from test_tab;
    end;
    then it obviously works as my ref cursor is expecting 4 columns. However, what I want to do is break each individual element out of the mydata column. I've played around a bit with dynamic sql but only getting so far and apparently that can't be used with a ref cursor anyway. I need to return a strongly typed cursor as another program requires this.
    One option is to manually parse each row and insert into temp table that is basically definition of record (so record type no longer needed) and this becomes type of ref cursor. I can then simply select from the table. I'm not keen on this as it's just another object to worry about.
    Another option is to do some ugly instr/substr to extract each element in the sql statement (or write a function to do it but need to consider performance of this). The more generic the better as I need to reuse against multiple strongly typed ref cursors (kind of a contradiction in that by virtue of using strongly typed cursors I know exactly what I want returned!).
    Another option is for someone to shed some light on this as it must be possible to do in a simple way along the same lines I have started?
    thanks in advance

    That documentation seems to stay pretty vague. What constitutes the "right set of columns". Obviously my observed result matches what you are saying about not being able to enforce the datatypes in the fields of the strong typed cursor. But then I don't see the point of the strong typed cursor otherwise. Other sites i have read seem to focus on the %rowtype return rather than mapping it to a record. But the general consensus (at least to my understanding) is that if the cursor is strongly typed then the sql statement that used to open it must have the same set of columns and the datatypes must at least be able to implicitly convert.
    I will try the %rowtype strong ref cursor against a table and see if there is a different result. I am mainly interested in this because I would like to beable to ensure the datatype returned on the .net side through ODP
    I want to be able to know the datatype of a field coming back through a ref cursor at compile time not runtime. So it the answer to cast every field of the select statement?

  • Weak and Strongly Typed Reference Cursors in Reports

    Our custom reports has been using a reference cursor. I have inherited the code and not sure why there is a need to use a reference cursor when it can be done by a simple select statements. I see no dynamic select statements passed or any special parameters to reason out for use of reference cursor in our custom reports. Prior developers had reason out the benefits of using reference cursor for performance. I tested this by running a report with reference cursor versus plain select statement and still the report that is using the plain select statement performed better (faster) than the report that has the reference cursor, there is a big difference.
    I have seen some disadvantage of using reference cursor on the reports that when there is a database object change even if the package that sourced the reference cursor has not been updated or modified the reports needs to be recompiled each time we get this error message coming from the report server queue:
      Terminated with error: <br>REP-8: Run time error in the PL/SQL development
      environment (DE). PDE-PSD001 Could not resolve reference to <Unknown Program Unit>
      while loading <Unknown> <Unknown>. REP-0008: Unexpected memory error while
      initializing preferences.In 9iAS reports prior version the error is occurring rarely. When we moved to 10.1.2.2.0 reports it appears the error occurs most often. We have made an effort to research about the issue and appears to be a bug. One suggestion is to use a strongly typed reference cursor. I have tried to researched about the difference between a weak and strongly typed reference cursor but failed to understand them. I appreciate any help about examples differentiating a weak versus a strongly typed reference cursors.
    Thanks,
    Warren

    I guess my point, for what it's worth, is that whether you use only a strongly typed REF CURSOR, or whether you also use a weakly typed REF CURSOR, you may still end up getting the REP-0008 error (at least if your report is in .REP format). You can avoid this by using a pipelined function instead (or by putting the SQL directly in the report, or possibly by using .RDF or .JSP format).
    To test this, you might:
    1. Create a database package with an SQL*Plus script that that looks something like this:
    CREATE OR REPLACE PACKAGE TEST AS
        TYPE RECORD_TYPE IS RECORD
            USERNAME ALL_USERS.USERNAME%TYPE
        TYPE TABLE_TYPE IS TABLE OF RECORD_TYPE;
        TYPE WEAKLY_TYPED_REF_CURSOR_TYPE IS REF CURSOR;
        TYPE STRONGLY_TYPED_REF_CURSOR_TYPE IS REF CURSOR RETURN RECORD_TYPE;
        FUNCTION GET_WEAKLY_TYPED_REF_CURSOR RETURN WEAKLY_TYPED_REF_CURSOR_TYPE;
        FUNCTION GET_STRONGLY_TYPED_REF_CURSOR RETURN STRONGLY_TYPED_REF_CURSOR_TYPE;
        FUNCTION GET_PIPELINED_TABLE RETURN TABLE_TYPE PIPELINED;
    END TEST;
    CREATE OR REPLACE PACKAGE BODY TEST AS
        FUNCTION GET_WEAKLY_TYPED_REF_CURSOR RETURN WEAKLY_TYPED_REF_CURSOR_TYPE
        IS
            cWeaklyTypedRefCursor WEAKLY_TYPED_REF_CURSOR_TYPE;
        BEGIN
            OPEN cWeaklyTypedRefCursor FOR
            SELECT USERNAME FROM ALL_USERS;
            RETURN cWeaklyTypedRefCursor;
        END GET_WEAKLY_TYPED_REF_CURSOR;
        FUNCTION GET_STRONGLY_TYPED_REF_CURSOR RETURN STRONGLY_TYPED_REF_CURSOR_TYPE
        IS
            cStronglyyTypedRefCursor WEAKLY_TYPED_REF_CURSOR_TYPE;
        BEGIN
            OPEN cStronglyyTypedRefCursor FOR
            SELECT USERNAME FROM ALL_USERS;
            RETURN cStronglyyTypedRefCursor;
        END GET_STRONGLY_TYPED_REF_CURSOR;
        FUNCTION GET_PIPELINED_TABLE
        RETURN TABLE_TYPE PIPELINED
        IS
        BEGIN
            FOR rec IN
                SELECT USERNAME FROM ALL_USERS
            LOOP
                PIPE ROW(rec);
            END LOOP;
        END GET_PIPELINED_TABLE;
    END TEST;
    /2. Create a report based on REF CURSOR query using only a strongly typed REF CURSOR. The PL/SQL statement that you use in the report as the data source for the query might look something like this:
    function QR_1RefCurDS return test.strongly_typed_ref_cursor_type is
    begin
      return test.get_strongly_typed_ref_cursor;
    end;3. Compile the report to a .REP file and run it to make sure it works as expected.
    4. Drop and re-create the TEST package in the database.
    5. Try running the .REP file again. I expect you will get the REP-0008 error.
    6. Modify the REF CURSOR query to use an underlying weakly typed REF CURSOR by changing the PL/SQL statement (from Step 2) to something like this:
    function QR_1RefCurDS return test.strongly_typed_ref_cursor_type is
    begin
      return test.get_weakly_typed_ref_cursor;
    end;7. Repeat Steps 3 through 5. I expect you will get the REP-0008 error again.
    8. Replace the REF CURSOR query in report with an SQL query that looks something like this:
    SELECT * FROM TABLE(TEST.GET_PIPELINED_TABLE)9. Repeat Steps 3 through 5. I expect you will not get the REP-0008 error.
    Hope this helps.

  • How to use BULK COLLECT in ref cursor?

    hi,
    can we use bulk collect in ref cursor ? if yes then please give small example ..
    thanks

    Try this:
    create or replace type person_ot as object (name varchar2(10)) not final;
    create or replace type student_ot under person_ot (s_num number) not final;
    create type person_tt as table of person_ot;
    create table persons of person_ot;
    declare
    lv_person_list person_tt;
    lv_sql varchar2(1000);
    ref_cur sys_refcursor;
    begin
    lv_sql:= 'select new student_ot(''fred'', 100) from dual
    union all
    select new student_ot(''sally'', 200) from dual';
    open ref_cur for lv_sql;
    fetch ref_cur bulk collect into lv_person_list;
    close ref_cur;
    for i in lv_person_list.first..lv_person_list.last loop
    dbms_output.put_line(lv_person_list(i).name );
    end loop;
    forall i in lv_person_list.first..lv_person_list.last
    insert into persons values lv_person_list(i);
    end;
    /

  • Acrobat 9.3.4 doesn't enforce Date Formating

    After we upgraded to Acrobat 9.3.4 from a previous version of 9.3 acrobat doesn't enforce date formating..before in a Text field formated as Date mm/dd/yyyy it would autocompelete if we typed in 9/21 to 9/21/2010.. now it doesn't, we can type any random text in the field and it isn't validated.
    Ideas?

    Just checked, its enabled.. when I say validate I'm referring to Acrobat's internal date format validation, not JavaScript.
    For example if you create a text box, goto properties, format tab, format category = date, date options mm/dd/yyyy
    now if you type:
    "abcdef" in that text box it should say, "Invalid Date/time: please ensure that the date/time exists.
    if you type 9/21 it will automatically turn it into 9/21/2010.
    After Appling the 9.3.4 update no such validation takes place, any value entered is accepted..

  • Call to Oracle stored procedure that returns ref cursor doesn't work

    I'm trying to use an OData service operation with Entity Framework to call an Oracle stored procedure that takes an number as an input parameter and returns a ref cursor. The client is javascript so I'm using the rest console to test my endpoints. I have been able to successful call a regular Oracle stored procedure that takes a number parameter but doesn't return anything so I think I have the different component interactions correct. When I try calling the proc that has an ref cursor for the output I get the following an error "Invalid number or type of parameters". Here are my specifics:
    App.config
    <oracle.dataaccess.client>
    <settings>
    <add name="PGDATA_WC.ODATAPOC.GETWORKORDERSBYWINDFARMID.RefCursor.P_RESULTS" value="implicitRefCursor bindinfo='mode=Output'" />
    <add name="PGDATA_WC.ODATAPOC.GETWORKORDERSBYWINDFARMID.RefCursorMetaData.P_RESULTS.Column.0" value="implicitRefCursor metadata='ColumnName=WINDFARM_ID;BaseColumnName=WINDFARM_ID;BaseSchemaName=PGDATA_WC;BaseTableName=WORKORDERS;NATIVEDATATYPE=Number;ProviderType=Int32'" />
    <add name="PGDATA_WC.ODATAPOC.GETWORKORDERSBYWINDFARMID.RefCursorMetaData.P_RESULTS.Column.1" value="implicitRefCursor metadata='ColumnName=STARTTIME;BaseColumnName=STARTTIME;BaseSchemaName=PGDATA_WC;BaseTableName=WORKORDERS;NATIVEDATATYPE=Varchar2;ProviderType=Varchar2'" />
    <add name="PGDATA_WC.ODATAPOC.GETWORKORDERSBYWINDFARMID.RefCursorMetaData.P_RESULTS.Column.2" value="implicitRefCursor metadata='ColumnName=ENDTIME;BaseColumnName=ENDTIME;BaseSchemaName=PGDATA_WC;BaseTableName=WORKORDERS;NATIVEDATATYPE=Varchar2;ProviderType=Varchar2'" />
    <add name="PGDATA_WC.ODATAPOC.GETWORKORDERSBYWINDFARMID.RefCursorMetaData.P_RESULTS.Column.3" value="implicitRefCursor metadata='ColumnName=TURBINE_NUMBER;BaseColumnName=TURBINE_NUMBER;BaseSchemaName=PGDATA_WC;BaseTableName=WORKORDERS;NATIVEDATATYPE=Varchar2;ProviderType=Varchar2'" />
    <add name="PGDATA_WC.ODATAPOC.GETWORKORDERSBYWINDFARMID.RefCursorMetaData.P_RESULTS.Column.4" value="implicitRefCursor metadata='ColumnName=NOTES;BaseColumnName=NOTES;BaseSchemaName=PGDATA_WC;BaseTableName=WORKORDERS;NATIVEDATATYPE=Varchar2;ProviderType=Varchar2'" />
    <add name="PGDATA_WC.ODATAPOC.GETWORKORDERSBYWINDFARMID.RefCursorMetaData.P_RESULTS.Column.5" value="implicitRefCursor metadata='ColumnName=TECHNICIAN_NAME;BaseColumnName=TECHNICIAN_NAME;BaseSchemaName=PGDATA_WC;BaseTableName=WORKORDERS;NATIVEDATATYPE=Varchar2;ProviderType=Varchar2'" />
    <add name="PGDATA_WC.ODATAPOC.GETWORKORDERSBYID.RefCursor.P_RESULTS" value="implicitRefCursor bindinfo='mode=Output'" />
    </settings>
    OData Service Operation:
    public class OracleODataService : DataService<OracleEntities>
    // This method is called only once to initialize service-wide policies.
    public static void InitializeService(DataServiceConfiguration config)
    // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
    // Examples:
    config.SetEntitySetAccessRule("*", EntitySetRights.All);
    config.SetServiceOperationAccessRule("GetWorkOrdersByWindfarmId", ServiceOperationRights.All);
    config.SetServiceOperationAccessRule("CreateWorkOrder", ServiceOperationRights.All);
    config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
    [WebGet]
    public IQueryable<GetWorkOrdersByWindfarmId_Result> GetWorkOrdersByWindfarmId(int WindfarmId)
    return this.CurrentDataSource.GetWorkOrdersByWindfarmId(WindfarmId).AsQueryable();
    [WebGet]
    public void CreateWorkOrder(int WindfarmId)
    this.CurrentDataSource.CreateWorkOrder(WindfarmId);
    Here is the stored procedure:
    procedure GetWorkOrdersByWindFarmId(WINDFARMID IN NUMBER,
    P_RESULTS OUT REF_CUR) is
    begin
    OPEN P_RESULTS FOR
    select WINDFARM_ID,
    STARTTIME,
    ENDTIME,
    TURBINE_NUMBER,
    NOTES,
    TECHNICIAN_NAME
    from WORKORDERS
    where WINDFARM_ID = WINDFARMID;
    end GetWorkOrdersByWindFarmId;
    I defined a function import for the stored procedure using the directions I found online by creating a new complex type. I don't know if I should be defining the input parameter, WindfarmId, in my app.config? If I should what would that format look like? I also don't know if I'm invoking the stored procedure correctly in my service operation? I'm testing everything through the rest console because the client consuming this information is written in javascript and expecting a json format. Any help is appreciated!
    Edited by: 1001323 on Apr 20, 2013 8:04 AM
    Edited by: jennyh on Apr 22, 2013 9:00 AM

    Making the change you suggested still resulted in the same Oracle.DataAccess.Client.OracleException {"ORA-06550: line 1, column 8:\nPLS-00306: wrong number or types of arguments in call to 'GETWORKORDERSBYWINDFARMID'\nORA-06550: line 1, column 8:\nPL/SQL: Statement ignored"}     System.Exception {Oracle.DataAccess.Client.OracleException}
    I keep thinking it has to do with my oracle.dataaccess.client settings in App.Config because I don't actually put the WindfarmId and an input parameter. I tried a few different ways to do this but can't find the correct format.

  • Using plsql table and ref cursor in oracle forms 10g

    Hi all,
    Can anyone give me an example of a scenario where we need to create a form manually based on a database stored procedures.
    And in that procedure i have created a pl/sql table and a ref cursor in data base level.
    CREATE OR REPLACE PACKAGE SCOTT.BONUS_PKG IS TYPE bonus_rec
    IS RECORD(
    empno     bonus_EMP.empno%TYPE,
    ename     bonus_EMP.ename%TYPE,
    job     bonus_EMP.job%TYPE,
    sal     bonus_EMP.sal%TYPE,
    comm     bonus_EMP.comm%TYPE);
    TYPE b_cursor IS REF CURSOR RETURN bonus_rec;
    TYPE bontab IS TABLE OF bonus_rec INDEX BY BINARY_INTEGER;
    PROCEDURE bonus_refcur(bonus_data IN OUT b_cursor);
    PROCEDURE bonus_query(bonus_data IN OUT bontab);
    END bonus_pkg;
    CREATE OR REPLACE PACKAGE BODY SCOTT.BONUS_PKG IS
    PROCEDURE bonus_query(bonus_data IN OUT bontab) IS
    ii NUMBER;
    CURSOR bonselect IS
    SELECT empno, ename, job, sal, comm FROM bonus_EMP ORDER BY empno;
    BEGIN
    OPEN bonselect;
    ii := 1;
    LOOP
    FETCH bonselect INTO
    bonus_data( ii ).empno,
    bonus_data( ii ).ename,
    bonus_data( ii ).job,
    bonus_data( ii ).sal,
    bonus_data( ii ).comm;
    EXIT WHEN bonselect%NOTFOUND;
    ii := ii + 1;
    END LOOP;
    END bonus_query;
    PROCEDURE bonus_refcur(bonus_data IN OUT b_cursor) IS
    BEGIN
    OPEN bonus_data FOR SELECT empno, ename, job, sal, comm FROM bonus_EMP ORDER BY empno;
    END bonus_refcur;
    END bonus_pkg;
    i want to populate the data in forms manually not using forms data block wizard and programmatically.
    please reply...

    Can anyone give me an example of a scenario where we need to create a form manually based on a database stored procedures.Typically, you would use a procedure based block when you have a collection of data from multiple tables presented in a Form and your user needs to be able to update the information displayed.
    From your code example, it looks like you are using Oracle Support document "Basing a Block on a Stored Procedure - Sample Code [ID 66887.1]". If this is the case, keep following the document - it walks you through all of the steps. There is no need to Manually configure things that the Data Block Wizard will perform for you!
    i want to populate the data in forms manually not using forms data block wizard and programmatically. Why? Let the Data Block Wizard take care of configuring your block based on a procedure for you. There is no need to manually loop through the data! I've actually done what you are attempting and it was more work than was needed. Let Forms do the work for you. :)
    If you absolutely must do things manually, I recommend you use the PROCEDURE bonus_query(bonus_data IN OUT bontab) instead of the bonus_refcur(bonus_data IN OUT b_cursor) . Then, in your code create a variable of type BONTAB and then call the bonus_query procedure. Then it is a simple case of looping through the table of records returned by the bonus_query procedure. For example:
    DECLARE
       t_bonus    bonus_pkb.bontab;
    BEGIN
       bonus_pkg.bonus_query(t_bonus);
       FOR i in 1 .. t_bonus.count LOOP
          :YOUR_BLOCK.EMPLOYEE_NUMBER := t_bonus(i).empno;
          :YOUR_BLOCK.EMPLOYEE_NAME := t_bonus(i).ename;
          :YOUR_BLOCK.EMPLOYEE_JOB := t_bonus(i).job;
          :YOUR_BLOCK.EMPLOYEE_SALARY := t_bonus(i).sal;
          :YOUR_BLOCK.EMPLOYEE_COMMISSION := t_bonus(i).comm;
       END LOOP;
    END;This code sample demonstrates the basics, but as it is sample code - you will have to adapt it to your situation.
    Also, I strongly recommend you look at the article InoL listed. This is a very comprehensive discussion on REF CURSORs. If you are set on using a procedure based data source - it is more efficient to pass the table of records back to your form than it is to pass a ref cursor. Using a ref cursor, you might as well just using a standard named cursor and loop through your named cursor. The effect is the same (one row returned at a time creating lots of network traffic). Using the table of records is more efficient because the entire data set is returned so network traffic is reduced.
    Hope this helps,
    Craig B-)
    If someone's response is helpful or correct, please mark it accordingly.

  • Using BIND VARIABLES in REF CURSOR(s)

    Hello I am having trouble making my pl/sql program work using bind variables.
    here is a little snipit from my code:
    declare
    type ref_type is REF CURSOR;
    ref_cursor ref_type;
    summation_table varchar2(4000);
    begin
    summation_table := 'table_sum tsum';
    open ref_cursor for
    select * from :summation_table
    where tsum.revenue = 1000
    USING summation_table;
    end;
    The Error that I get is
    "bad bind variable 'summation_table'"
    could someone please help? I think the way 'tsum' is used could be a problem, but I don't know.

    SQL> CREATE TABLE TABLE_SUM(REVENUE NUMBER(10),
      2                         OTHER   NUMBER(10));
    Table created.
    SQL> INSERT INTO TABLE_SUM VALUES(1000,1);
    1 row created.
    SQL> INSERT INTO TABLE_SUM VALUES(1000,2);
    1 row created.
    SQL> variable alpha refcursor
    SQL> INSERT INTO TABLE_SUM VALUES(2000,3);
    1 row created.
    SQL> DECLARE
      2     summation_table varchar2(30) := 'table_sum tsum';
      3     PROCEDURE MYTEST(p_out out sys_refcursor)
      4     IS
      5     BEGIN
      6       OPEN p_out for 'select * from '||summation_table||
      7                      ' where tsum.revenue = :val' using 1000;
      8     END;
      9  BEGIN
    10     MYTEST(:alpha);
    11  END;
    12  /
    PL/SQL procedure successfully completed.
    SQL> print alpha
       REVENUE      OTHER
          1000          1
          1000          2
    SQL>

  • Using bind variable for ref cursors

    Hi
    I have a procedure that recieves a tablename in srcTable variable . A query is formed SELECT_Q with values from global varray.
    Table name will be dynamic and query is to be used with a ref cursor. Since table name is not known how to make the refcursor.
    tried the following.....not sure how to do it. pls help.
    PROCEDURE Process1(srcTable VARCHAR2, trgTable VARCHAR2) IS
         TYPE CURSORTYPE IS REF CURSOR RETURN :x%ROWTYPE;
         REC_CUR CURSORTYPE;
         REC_CUR_DATA :x%ROWTYPE;
         DBMS_SQL.BIND_VARIABLE(REC_CUR, ':x', SourceT);
         DBMS_SQL.BIND_VARIABLE(REC_CUR_DATA, ':x', SourceT);
         COUNTi NUMBER :=0;
         SELECT_Q VARCHAR2(1000) := 'SELECT ';
    BEGIN
    FOR COUNTi IN 1..COLUMN_NAME_ARR.COUNT-1 LOOP
              SELECT_Q := SELECT_Q || COLUMN_NAME_ARR(COUNTi) || ',';
    END LOOP;
         SELECT_Q := SELECT_Q || COLUMN_NAME_ARR(COLUMN_NAME_ARR.COUNT) || ' FROM '||SourceT;
         DBMS_OUTPUT.PUT_LINE(SELECT_Q);
    -- query to be used for making cursor.
    ---how to make the cursor
         OPEN REC_CUR FOR Select_Q;
         LOOP
         FETCH REC_CUR INTO REC_CUR_DATA;
         EXIT WHEN REC_CUR%NOTFOUND;
         END LOOP;
    END TableSnapShot_Process1;

    For online books you can start with the documentation.
    PL/SQL Packages and Types Reference
    http://download-east.oracle.com/docs/cd/B19306_01/appdev.102/b14258/toc.htm
    PL/SQL User's Guide and Reference
    http://download-east.oracle.com/docs/cd/B19306_01/appdev.102/b14261/toc.htm
    Print books
    Oracle PL/SQL Programming By Steven Feuerstein is good book to have.
    http://www.oreilly.com/catalog/oraclep4/

  • 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 Ref Cursor as parameter to object type method

    I am encountering a problem passing a parameter of type REF CURSOR to methods of a set of object types I am developing.
    Here is an example of what I am trying to do:
    create or replace package p1 as
    type c_Cursor is ref cursor;
    end p1;
    create or replace type t_Object as object
    not instantiable method m1(p_Cursor in p1.c_Cursor) return varchar2
    ) not instantiable not final;
    create or replace type t_Subtype under t_Object as
    overriding method m1(p_Cursor in p1.c_Cursor)
    return varchar2
    The problem is that the PL/SQL compiler gives the error message PLS-00201 "p1.c_Cursor" not defined.
    According to my PL/SQL book (SF's Oracle PL/SQL Programming) the only way to use a ref cursor as a parameter to functions/procedures is to wrap them in a package. Indeed I have developed a test procedure in a different package that uses p1.c_Cursor as a parameter and it works fine.
    Oracle's documemtation suggests that object security (roles etc) can cause this error but as all the objects are being created in the same schema I don't see how this should be a problem.
    If anyone can suggest how to get around this problem I will be very grateful.
    BTW, if there are any mistakes in my sample code it's because I am writing it from memory as I don't have Internet access at work.
    Thanks,
    Charles.

    Thanks for your reply. I am still baffled as to why it doesn't work but, as you correctly point out, SYS_REFCURSOR works just fine. I figured that out earlier today and now the problem is solved.
    Charles.

  • Ref cursor not returning any data

    Hi
    How can I raise an exception when ref cursor is not retrieving any data.
    create or replace function getempdetails(p_deptno in number)
    return sys_refcursor
    is
    v_refcursor sys_refcursor;
    begin
    open v_refcursor for
    select * from emp
    where deptno = p_deptno;
    return v_refcursor;
    exception
    when no_data_found then
    dbms_output.put_lline('No data available for p_deptno');
    end;
    Say for example p_deptno = 12
    Thanks
    Raghu
    Message was edited by:
    user584123

    It is useless but... you can do this
    create or replace function getempdetails(
         p_deptno in number
    return sys_refcursor
    is
         v_refcursor sys_refcursor;
         flag number;
    begin
         select count(*)
              into flag
         from emp
         where deptno = p_deptno
              and rownum = 1;
         if ( flag = 0) then
              dbms_output.put_lline('No data available for p_deptno');
              return null;
         else
              open v_refcursor for
              select * from emp
              where deptno = p_deptno;
              return v_refcursor;
         end if;          
    end;Bye Alessandro
    Message was edited by:
    Alessandro Rossi
    Or this
    create or replace function getempdetails(
         p_deptno in number
    return sys_refcursor
    is
         v_refcursor sys_refcursor;
         flag number;
    begin
         select 1
              into flag
         from emp
         where deptno = p_deptno
              and rownum = 1; -- This throws the exception
         open v_refcursor for
         select * from emp
         where deptno = p_deptno;
         return v_refcursor;
    end;

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

  • Workaround for opening a strongly typed cursor using native dynamic SQL

    Hi All,
    In reading the PL/SQL documentation for Oracle 9i, I noted that the OPEN-FOR
    statement with a dynamic SQL string only allows the use of weakly typed cursors.
    I have verified this limitation with my own experimentation as follows:
    DECLARE
    type rec_type is record(
    str     varchar2(40),
    num     number(22)
    type cur_type is ref cursor return rec_type;
    my_cur     cur_type;
    que     varchar2(100);
    tab     varchar2(40);
    BEGIN
    tab := 'dynamic_table_name';
    que := 'select key_name, key_value from ' || tab || ' where key_name like ''01%''';
    open my_cur for que;
    loop
    if my_cur%found then
    dbms_output.put_line('source_name: ' || my_cur.str || ', page_sn: ' || my_cur.num);
    exit;
    end if;
    end loop;
    close my_cur;
    END;
    Running the above trivial example in an anonymous sql block yields the following
    errors as expected:
    ORA-06550: line 10, column 8:
    PLS-00455: cursor 'MY_CUR' cannot be used in dynamic SQL OPEN statement
    ORA-06550: line 10, column 3:
    PL/SQL: Statement ignored
    ORA-06550: line 13, column 54:
    PLS-00487: Invalid reference to variable 'MY_CUR'
    ORA-06550: line 13, column 7:
    PL/SQL: Statement ignored
    Is there a workaround to the situation? Since I do not know the table name at run
    time, I must use Native Dynamic SQL. I have a long and complex record type
    that I wish to return through JDBC using the REFCURSOR Oracle type in order to
    avoid having to register an inordinate number of OUT parameters. Moreover, I
    would like to return potentially one or more results in a ResultSet. Using the
    standard method of registering native SQL types for the IN and OUT bindings
    can only return one result. Hence the reason I would like to return a strong
    cursor type. Also, the type of query I am doing is complex, and needs to be
    executed in a PL/SQL procedure for performance reasons. Therefore simply
    executing a SELECT query dynamically built up on the the JDBC client won't
    do the trick.
    If anybody has experience with a similar problem and would like to volunteer
    information on their workaround, I would really appreciate it.
    Best Regards,
    J. Metcalf

    We can use strongly-typed REF CURSORs in DNS, but the typing derives from a table e.g.
    TYPE EmpCurTyp IS REF CURSOR RETURN emp%ROWTYPE;
    so the problem is your use of "return rec_type" bit.
    Forgive my bluntness but I think you have misunderstood strong and weak typing. You actually want to be using weakly-typed cursors. I mean this:
    Moreover, I would like to return potentially one or more results in a ResultSet. suggests that the structure of your resultset may vary, which is precisely what a weakly-typed ref cursor allows us to do. Then we can use the JDBC metadata methods to interrogate the structure of the resultset, innit.
    so try this:
    DECLARE
    type cur_type is ref cursor;
    my_cur cur_type;
    que varchar2(100);
    tab varchar2(40);
    BEGIN
    tab := 'dynamic_table_name';
    que := 'select key_name, key_value from ' || tab || ' where key_name like ''01%''';
    open my_cur for que;
    loop
    if my_cur%found then
    dbms_output.put_line('source_name: ' || my_cur.str || ', page_sn: ' || my_cur.num);
    exit;
    end if;
    end loop;
    close my_cur;
    END;
    ras malai, APC
    Cheers, APC

  • Ref Cursors

    I was looking at this example given for ref cursor
    CREATE TABLE employees (
    empid NUMBER(5),
    empname VARCHAR2(30));
    INSERT INTO employees (empid, empname) VALUES (1, 'Dan Morgan');
    INSERT INTO employees (empid, empname) VALUES (2, 'Hans Forbrich');
    INSERT INTO employees (empid, empname) VALUES (3, 'Caleb Small');
    COMMIT;
    CREATE OR REPLACE PROCEDURE pass_ref_cur(p_cursor SYS_REFCURSOR) IS
    TYPE array_t IS TABLE OF VARCHAR2(4000)
    INDEX BY BINARY_INTEGER;
    rec_array array_t;
    BEGIN
    FETCH p_cursor BULK COLLECT INTO rec_array;
    FOR i IN rec_array.FIRST .. rec_array.LAST
    LOOP
    dbms_output.put_line(rec_array(i));
    END LOOP;
    END pass_ref_cur;
    set serveroutput on
    DECLARE
    rec_array SYS_REFCURSOR;
    BEGIN
    OPEN rec_array FOR
    'SELECT empname FROM employees';
    pass_ref_cur(rec_array);
    CLOSE rec_array;
    END;
    In this P_cursor is weaklytyped ref cursor. My question is
    1. How does the fetch identifies which columns are there in the cursor ?
    2. If I add another column (say empid) to cursor query it is throwing error message !
    3. In my case; I need to use the cursor columns for futher processing in my proc. In such cases how do we define the cursor ?
    TIA

    1. How does the fetch identifies which columns are there in the cursor ?It doesn't. It just puts the first value into the first variable, the second into the next and so on. If it doesn't fit you get an exception (as you found).
    In fact a strongly typed ref cursor is the same underneath, it just makes your code declare things slightly more specifically.
    2. If I add another column (say empid) to cursor query it is throwing error message !You would have to modify the target variable and the fetch to match the cursor.
    3. In my case; I need to use the cursor columns for futher processing in my proc. In such cases how do we define the cursor ?You have to know what columns you are fetching so that you can do something with them. Even if you parsed it out (as SQL*Plus does when it prints a refcursor variable for example) the rest of your code would need to know what it was referring to, how many columns, their datatypes etc.

Maybe you are looking for

  • Does the warranty cover the power adapter?

    Lately my power adapter's light has been cutting in and out. Tonight I noticed it's frayed where the cable meets the input of the adapter. I'm wondering if the adapter is covered under Apple's warranty. I have Apple Care. Furthermore, the battery als

  • Installing Dirsync on Windows 2008 Server Standard FE

    Hello all, I need to Dirsync my only domain controller i have to Office 365.  My server is a Windows 2008 Server Standard FE.  I installed all requirement for dirsync to be installed (and all Windows updates also) and i still get an error when trying

  • XE look and feel in Oracle 10g Enterprise Edition

    Hi! I have both Enterprise Edition 10gR2 and XE installed on Linux. I want to use Enterprise Edition as my main database. But I want XE "look and feel" for 10gR2 What do I have to do to accomplish this? regards Paal

  • I am trying to understand servlets

    In the tutorial it says : 2. In a terminal window <INSTALL>/j2eetutorial14/examples/web/bookstore1/. What is the terminal window is this a J2EE editor window of some sort? I do not quite understand what they mean by "terminal window".

  • Photoshop trial error

    I downloaded a trial of cs6 master edition and everything works fine except both photoshop and photoshop extended either make the image all black or it changes the whole artboard to transparent. If I click on the layer it brings the picture back up b