Oracle returns decimal value for a specific column NUMBER (4)

I am executing a query using ODP.NET. The query selects many columns from the table, including several NUMBER (4) columns.

When querying a local instance of dev 10.2, all NUMBER (4) columns are returned as Int16 instances. This is normal and expected.

When executing a query against another instance of 11.2, all but the last columns of NUMBER (4) are also instances of Int16, but the last is an instance of the decimal code that is currently breaking my code. I can fix the problem in my application, but the arbitrariness of this kills me. How could this happen? Is it possible? I mean, the same query, the same table, all columns of the same type, but one of them gets the other C # in the data reader. How could this happen?

EDIT -> I run tests. The problem arises even if I SELECT only one column from this single table without JOINs or UNION or WHERE or anything else. I tried to reset the column and recreate it; same problem. I tried to create a copy of the table with the same columns, the problem continues to occur. I tried to create a copy of the table with fewer columns, the problem stopped. Is it possible that this is solely due to the number of columns / position of the wrong column inside the table? (The table contains 77 columns, and the problem column is the last column in the table).

+4
source share
1 answer

, - ODP.NET NUMBER OracleDecimal .

, NUMBER , , . NUMBER (N, 0) , ODP.NET .NET / .

, , ExecuteDataReader() :

  using(var reader = cmd.ExecuteReader())
  {
    while(reader.Read())
    {
      var v = Convert.ToInt16(reader["name"]);
    }
  }

, OracleDecimal IConvertible Int32 Convert.ToInt32() ( ).

, OracleDataReader.GetInt16() :

  int num2 = (int) this.m_pOpoMetValCtx->pColMetaVal[i].Scale;
  int num3 = (int) this.m_pOpoMetValCtx->pColMetaVal[i].Precision;
  if (num2 > 0 || num3 - num2 >= 5)
    throw new InvalidCastException();

, , , , - . , NUMBER ODP.NET OracleDecimal, Int16, Int32, Int64, Float, Double Decimal

,

  SELECT CAST(1 AS NUMBER(3,0)) as c1, CAST(220 AS NUMBER) as c2 FROM DUAL

:

  var v = Convert.ToInt16(reader["c2"]);

:

  var v = reader.GetInt16(1); // InvalidCastException

, , , OracleDbTypeEx .

,

  var p = new OracleParameter("name",OracleDbType.Int32, ParameterDirection.Output)

OracleDecimal , , :

  var p = new OracleParameter("name",OracleDbType.Int32, ParameterDirection.Output);
  p.OracleDbCodeEx = OracleDbType.Int32;

.net System.Int32.

ODP.NET , . OracleDataReader.GetOrdinal() . .

+3

Source: https://habr.com/ru/post/1543117/


All Articles