Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Oracle number to C# decimal

I know there are several threads and posts regarding this issue in the internet and I've read them (not every article, I have to admit) but none of them did fully satisfy me.

My situation:
I'm using ODP.net (dll version 2.111.6.0) to access the Oracle DB (version 10 + 11) and a DataReader to retrieve the data (.NET 3.5, C#).

Using this code results in a 'System.OverflowException (Arithmetic operation resulted in an overflow.)'


decimal.TryParse(oraReader.GetOracleDecimal(0).Value.ToString(), 
  NumberStyles.Any, null, out parsedOraDecimal)

and this one results in a value of '3,000000000000000000000000000000000000000000000000000000000E-126'


decimal.TryParse(oraReader.GetOracleValue(0).ToString(), 
  NumberStyles.Any, null, out parsedOraDecimal)

Now I have to find some way to retrieve and evaluate this value properly - the DB is also used from other apps which are out of my control so changes there are not possible.

Converting the types in my C# code from 'decimal' to 'double' is also not really an option.

Any ideas?

like image 633
robert.oh. Avatar asked Dec 15 '09 10:12

robert.oh.


People also ask

What is number datatype in Oracle?

The Oracle NUMBER data type is used to store numeric values that can be negative or positive. The following illustrates the syntax of the NUMBER data type: NUMBER[(precision [, scale])] The Oracle NUMBER data type has precision and scale. The precision is the number of digits in a number.

What is the use of To_number in Oracle?

TO_NUMBER converts expr to a value of NUMBER datatype. The expr can be a BINARY_FLOAT or BINARY_DOUBLE value or a value of CHAR , VARCHAR2 , NCHAR , or NVARCHAR2 datatype containing a number in the format specified by the optional format model fmt .

How many byte is a number in Oracle?

Each value is stored in scientific notation, with 1 byte used to store the exponent. The database uses up to 20 bytes to store the mantissa, which is the part of a floating-point number that contains its significant digits. Oracle Database does not store leading and trailing zeros.


2 Answers

OracleDecimal has a larger precision than decimal. For that reason, you have to reduce the precision first. Forget all the parsing, use implicit conversion. Try something along the lines of (untested):

decimal d = (decimal)(OracleDecimal.SetPrecision(oraReader.GetOracleDecimal(0), 28));
like image 64
Erich Kitzmueller Avatar answered Oct 23 '22 00:10

Erich Kitzmueller


I just had a similar issue, and tried the approach of changing the OracleDataAdapter to return Oracle specific types ( data_adapter.ReturnProviderSpecificTypes = true; ), but this is just a PITA, you end up casting OracleStrings back to strings, etc.

In the end I solved it by doing the precision rounding in the SQL statement using Oracle's round function:

SELECT round( myfield, 18 ) FROM mytable

Dotnet will then happily convert the figure to a decimal.

like image 9
Dave Glassborow Avatar answered Oct 23 '22 01:10

Dave Glassborow