This discussion is archived
9 Replies Latest reply: Apr 18, 2013 12:35 PM by Alex_Keh - Oracle_Product_Manager RSS

ODP.Net Managed Provider Beta: Exception thrown on call to GetOracleDecimal

288036 Newbie
Currently Being Moderated
* .Net Framework 4.0
* ODP.Net Managed Provider Beta
* Oracle 10g Server (10.2.0.5.0)
System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at OracleInternal.Core.OracleNumberCore.IsPositive(Byte[] byteRep)
   at Oracle.ManagedDataAccess.Types.OracleDecimal..ctor(Byte[] numBytes, Boolean bContainsLength)
   at OracleInternal.Common.HelperClass.GetOracleDecimal(OraType oraType, Byte[] bytes, Int32 offset)
   at Oracle.ManagedDataAccess.Client.OracleDataReader.GetOracleDecimal(Int32 i)
Hi Alex

i get this exception on an explicit call to GetOracleDecimal for a field of data type ORA_NUMBER in which each of the returned values is null.

The stored program I'm calling is in a Package and returns a ref cursor.

This happens after I have successfully iterated many rows of the the returned resultset, successfully calling GetOracleDecimal for the same field.

For the successful calls to GetOracleDecimal, the OracleDecimal value is {Null} with an InternalByteRepresentation of null.

I think what might be happening is that for the failing call, the 'raw data' value is an initialised byte array of zero length (i.e. {byte[0]}
I'm guessing the cause of the throw is because IsPositive is trying to access the first element in an initialised byte array containing no elements?

The same error is thrown if you try to run the enumerator on the OracleDataReader.

Please let me know if it isn't appropriate to post this here or if you would like me to post a ticket on metalink.

Kind regards

Shaun

PS: I can't get the Trace logging to work correctly.
* relative path file system location ending in '\' doesn't work
* when '\' omitted, file is written in .\..\ and directory name is concatenated with file name.
* OracleTraceLevel.Private logs don't seem to be appearing in log file (I might be mistaken in this.)
  • 1. Re: ODP.Net Managed Provider Beta: Exception thrown on call to GetOracleDecimal
    966771 Newbie
    Currently Being Moderated
    Hello Shaun ..

    do you have any simple test case which reproduce this issue ?
  • 2. Re: ODP.Net Managed Provider Beta: Exception thrown on call to GetOracleDecimal
    288036 Newbie
    Currently Being Moderated
    It's not straightforward for me to provide a simple test case.
  • 3. Re: ODP.Net Managed Provider Beta: Exception thrown on call to GetOracleDecimal
    288036 Newbie
    Currently Being Moderated
    create or replace package SHAUN is

    type ref_cur_type is ref cursor;

    function recreate_issue_1 return ref_cur_type;

    function fake_inline
    return varchar2;
    pragma restrict_references(fake_inline, wnps, wnds);

    end SHAUN;
    /
    create or replace package body SHAUN is

    --D00003890 

    function recreate_issue_1
    return ref_cur_type
    is
    ref_cur ref_cur_type;

    begin
    open ref_cur for
    select
    UO.object_name
    , to_number(null) bad_field
    , SHAUN.fake_inline fake
    from user_objects UO;

    return ref_cur;
    end recreate_issue_1;

    function fake_inline
    return varchar2
    is
    fld varchar2(200) := 'ABCDGOLDFISH';
    i integer := 0;
    begin
    for i in 0..10000 loop
    null;
    end loop;

    return fld;
    end;

    end SHAUN;
    /
    ----

    //C# Console application

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    using Oracle.ManagedDataAccess.Client;
    using Oracle.ManagedDataAccess.Types;
    using System.Data;

    namespace NoddyConsole
    {
    public class Program
    {
    public static int Main(string[] args)
    {
    int errors = 0;

    try
    {

    var conn = new OracleConnection("User Id=USER;Password=PASS;Data Source=//your-host:1521/your-sid");

    conn.Open();

    var cmd = conn.CreateCommand();
    cmd.CommandText = "BEGIN :rc := SHAUN.recreate_issue_1; END;";

    var prm = cmd.CreateParameter();
    prm.ParameterName = "rc";
    prm.Direction = ParameterDirection.ReturnValue;
    prm.OracleDbType = OracleDbType.RefCursor;

    cmd.Parameters.Add(prm);

    var reader = cmd.ExecuteReader();

    while (reader.Read())
    {
    var values = new object[reader.FieldCount];

    reader.GetOracleValues(values);

    for (int i = 0; i < values.Length; ++i)
    Console.WriteLine(values);
    }
    }
    catch (Exception ex)
    {
    Console.Error.WriteLine(ex.Message);
    errors++;
    }
    finally
    {
    Console.ReadKey(true);
    }
    return errors;
    }
    }
    }
  • 4. Re: ODP.Net Managed Provider Beta: Exception thrown on call to GetOracleDecimal
    288036 Newbie
    Currently Being Moderated
    Actually looking at this again, the loop in fake_inline does not need to be there.
  • 5. Re: ODP.Net Managed Provider Beta: Exception thrown on call to GetOracleDecimal
    288036 Newbie
    Currently Being Moderated
    Apologies - this will also reproduce the issue.

    ----

    create or replace package SHAUN is

    type ref_cur_type is ref cursor;

    function recreate_issue_1 return ref_cur_type;

    end SHAUN;
    /
    create or replace package body SHAUN is

    --D00003890 

    function recreate_issue_1
    return ref_cur_type
    is
    ref_cur ref_cur_type;

    begin
    open ref_cur for
    select
    UO.object_name
    , to_number(null) bad_field
    from user_objects UO;

    return ref_cur;
    end recreate_issue_1;

    end SHAUN;
    /

    ----

    Alter above C# snippet to change while loop to:

    long rowcount = 0;
    while (reader.Read())
    {
    var values = new object[reader.FieldCount];

    reader.GetOracleValues(values);

    for (int i = 0; i < values.Length; ++i)
    Console.WriteLine("{0:X4}:{1}", rowcount, values);
    ++rowcount;
    }

    ----

    NB: Note the WORD size at point of failure.
  • 6. Re: ODP.Net Managed Provider Beta: Exception thrown on call to GetOracleDecimal
    Alex_Keh - Oracle_Product_Manager Expert
    Currently Being Moderated
    I was able to run both the last test case you provided, as well as the test case you emailed to the Oracle .NET email alias, successfully. I didn't encounter any error and the array values were output successfully. I ran it on a machine with 32-bit XP and Oracle DB 11.2, but the OS nor DB server version should really make a difference if this is code you've run successfully before with unmanaged ODP.NET.

    I'll ask one my engineers to take a look to see if there are any ideas to finding the root cause of this problem. Can you provide a call stack?

    Edited by: Alex Keh - Oracle Product Manager on Nov 8, 2012 2:43 PM
  • 7. Re: ODP.Net Managed Provider Beta: Exception thrown on call to GetOracleDecimal
    288036 Newbie
    Currently Being Moderated
    Hi Alex

    Thanks very much for getting back to me.

    Here is the call-stack from the test application:

    at Oracle.ManagedDataAccess.Types.OracleDecimal..ctor(Byte[] numBytes, Boolean bContainsLength)
    at Oracle.ManagedDataAccess.Client.OracleDataReader.GetOracleDecimal(Int32 i)
    at Oracle.ManagedDataAccess.Client.OracleDataReader.GetOracleValue(Int32 i)
    at Oracle.ManagedDataAccess.Client.OracleDataReader.GetOracleValues(Object[] values)
    at NoddyConsole.Program.Main(String[] args) in C:\Users\smcgrath\Documents\src\api-harness-odpm\NoddyConsole\Program.cs:line 42

    I've tried this on a number of different versions of Oracle Server with the same results.

    Again, I think this is caused by an attempt to access the first element in an initialised byte array with no elements.

    Kind regards

    Shaun McGrath

    Edited by: mcgraths on Nov 9, 2012 12:18 PM
  • 8. Re: ODP.Net Managed Provider Beta: Exception thrown on call to GetOracleDecimal
    288036 Newbie
    Currently Being Moderated
    Hi Alex

    This issue has been resolved in the Beta 2 release of the Oracle.ManagedDataAccess.Client dll (4.112.3.60, of 2013-04-10).

    Many thanks

    Shaun

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points