9 Replies Latest reply: Apr 18, 2013 2:35 PM by Alex.Keh .Product.Manager-Oracle RSS

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

    288036
      * .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
          User11343241-Oracle
          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
            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
              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
                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
                  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 .Product.Manager-Oracle
                    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
                      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
                        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