Курсор cx_Oracle забывает масштаб столбца при агрегации

Для созданной мной таблицы Oracle, MYTABLE, у меня есть столбец COL1, который объявлен как NUMBER(20,3); он может иметь 3 значащих цифры после запятой. Когда я запускаю курсор cx_Oracle в этой таблице:

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)]

Во втором случае я потерял точность и масштаб. Сами данные в порядке (и отображают значения с десятичными разрядами).

Мне нужен надежный способ сказать в обоих случаях, какие типы данных ожидать (чтобы я мог решить, как форматировать мои данные в пользовательском интерфейсе клиента и т. д.). Глядя на описание курсора, вы могли бы подумать, что нет значащих цифр после десятичной точки разрешены во втором случае, и моя нижестоящая логика пользовательского интерфейса отображает числа как целые числа, что нежелательно.

Является ли это ошибкой, и если да, то есть ли способ однозначно выяснить по курсору во втором случае, какие данные я мог ожидать?


person Vineet Bansal    schedule 28.05.2013    source источник


Ответы (1)


Я думаю, что то, что вы видите здесь, является встроенной попыткой Oracle избежать ошибки ORA-01438 при применении функции к числу с ограниченной точностью и масштабом. По умолчанию вы не хотите, чтобы точность и масштаб COL1 и COL2 применялись в выражении (COL1/COL2) или AVG(COL1).

Таким образом, Oracle применяет общий тип данных NUMBER без ограничений по точности и масштабу. Я считаю, что это делает что-то подобное с функциями VarChar2.

Возможно, стоит попробовать явно указать результат Sum():

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

Если вы превысите точность 22 в результате, вы получите:

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

Наконец, если вы не знали, превышение масштаба не приводит к ошибке — если вы превышаете указанный масштаб, число просто округляется до максимально возможного масштаба.

person David Aldridge    schedule 29.05.2013