Domanda

For an Oracle table that I've created, MYTABLE, I have a column COL1, which is declared as a NUMBER(20,3); it can have 3 significant digits after the decimal point. When I run a cx_Oracle cursor on this table:

cursor.execute('SELECT COL1 FROM MYTABLE')

cursor.description
>> [('COL1', <type 'cx_Oracle.NUMBER'>, 25, 22, 20, 3, 1)]

cursor.execute('SELECT SUM(COL1) FROM MYTABLE')

cursor.description
>> [('SUM(COL1)', <type 'cx_Oracle.NUMBER'>, 127, 22, 0, 0, 1)]

In the second case, I've lost the precision and the scale. The data itself is fine (and shows up the values with the decimal places).

I do need a reliable way to tell in both cases what data types to expect (so I can decide how to format my data on the client UI etc.) Looking at the cursor description, you would believe that no significant digits after the decimal point are allowed in the second case, and my UI logic downstream renders the numbers as in integer, which is undesirable.

Is this a bug, and if so, is there any way to figure out unambiguously from the cursor in the second case what kind of data I could expect?

È stato utile?

Soluzione

I think that what you're seeing here is Oracle's built-in effort to avoid an ORA-01438 error when applying a function to a number with restricted precision and scale. By default you would not want the precision and scale of COL1 and COL2 to be applied in the expression (COL1/COL2), or AVG(COL1).

So, Oracle applies a generic NUMBER data type without restrictions on precision and scale. I believe it does something similar with VarChar2 functions.

What might be worth trying is to explicitly cast the Sum() result:

Cast(Sum(col1) as Number(22,3))

If you exceed a precision of 22 on the result though you'll get an:

ORA-01438: value larger than specified precision allowed for this column

Lastly, in case you weren't aware, exceeding the scale does not raise an error -- if you exceed the specified scale the number just gets rounded to the maximum scale possible.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top