TO_char возвращает значение косой черты после преобразования числа в строку

У меня есть столбец базы данных amount [Data type Number(32,12)]. Когда я использую to_char в поле amount, я получаю значение косой черты, добавленное к выходным данным.

Снимок экрана

Когда я напрямую использовал значение, хранящееся в поле суммы, я получаю правильное значение

select TO_Char(0.000000000099,'FM99999999999999999999999999999990.099999999999') from dual;

Выход: - 0.000000000099


person user1501147    schedule 11.01.2013    source источник
comment
Это на самом деле добавлено или это просто ваш графический интерфейс? Вы можете select ascii(substr(to_char(your_column, '<format model>'), -1)) from your_table? Если это числовое значение, оно должно быть в диапазоне 48-57.   -  person Ben    schedule 11.01.2013
comment
Это не из-за графического интерфейса. Значение сохраняется в представлении как / & #. Результат приведенного выше запроса будет равен 47. Что это за диапазон 48-57?   -  person user1501147    schedule 11.01.2013
comment
Это значения от 0 до 9 в кодировке ASCII, но в основном для большинства западных наборов символов. 47 - это /, поэтому вы добавляете один...   -  person Ben    schedule 11.01.2013
comment
Ok. Но я до сих пор не понимаю, почему / добавляется, когда я извлекаю значение из базы данных. ЕСЛИ я запускаю приведенный ниже тот же запрос с жестким кодированием значения в функции to_char, выберите TO_CHAR (0.000000000099, 'FM9999999999999999999999999999990.099999999999') как сумму из двойного; Я получаю правильный вывод 0.000000000099 вышеуказанного запроса. Также почему функция TO_CHAR округляет значения?   -  person user1501147    schedule 11.01.2013
comment
Если к строке действительно добавлен /, то применение To_Number() к результату вашего To_Char() не удастся, так что попробуйте.   -  person David Aldridge    schedule 11.01.2013
comment
Я получаю ошибку неверного числа в запросе   -  person user1501147    schedule 11.01.2013
comment
Является ли WK_hold_trans_calculation таблицей или представлением? Если это представление, основано ли оно на процедуре/функции? Похоже, что-то происходит под капотом, если это не ошибка SQL Developer, и похоже, что это уже исключено. Не уверен, как to_char все равно попадет в представление...   -  person Alex Poole    schedule 11.01.2013
comment
wk_hold_trans_calculation — это таблица, и в таблице с типом данных Number (32,12) есть поле суммы. Я использую Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 — 64-битная версия Production и PL/SQL Release 11.2.0.2.0 — Production   -  person user1501147    schedule 11.01.2013
comment
@ user1501147 что произойдет, если вы создадите простую тестовую таблицу create table foo (id number(32, 12)); insert into foo values (0.000000000099); и запустите для нее тот же выбор? также у вас есть cursor_sharing, установленный на аналогичный/принудительный или какие-либо нестандартные параметры? вероятно, лучше всего задействовать поддержку Oracle (здесь не воспроизводится на моем 11.2.0.2 db)   -  person DazzaL    schedule 11.01.2013
comment
Похоже, вы могли повредить значения в таблице (данные случайно не были импортированы?). Можете ли вы select amount, dump(amount, 16) для этих двух значений добавить результаты к вопросу? Они должны быть bb,64 и bc,11,51, но я подозреваю, что после них у них будет больше значений. Если они это сделают, это может быть воссоздано.   -  person Alex Poole    schedule 11.01.2013


Ответы (1)


Похоже, вы испортили данные в своей таблице. Что приводит к нескольким вопросам, в том числе как он туда попал и что вы можете с этим поделать?

Поврежденные числовые значения (или дата) часто поступают из программ OCI, но есть некоторые отчеты об ошибках, которые предполагают, что imp, как известно, вызвать коррупцию. Внутреннее представление задокументировано в примечании службы поддержки 1007641.6, но я нашел что-то вроде этого объяснения с ним легче работать при воссоздании проблем, а вместо программы OCI можно использовать блок PL/SQL.

Два числа, с которыми у вас возникли проблемы, должны быть представлены внутренне следующим образом:

select dump(0.000000000099, 16) as d1,
    dump(0.000000001680, 16) as d2
from dual;

D1                 D2
------------------ ---------------------
Typ=2 Len=2: bb,64 Typ=2 Len=3: bc,11,51

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

create table t42 (amount number(32,12)) nologging;

declare
    n number;
begin
    dbms_stats.convert_raw_value('bb65', n);
    insert into t42 (amount) values (n);
    dbms_stats.convert_raw_value('bc100000', n);
    insert into t42 (amount) values (n);
end;
/

Сброс значений показывает, что они выглядят немного странно:

column d1 format a25
column d2 format a25
select amount, dump(amount) d1, dump(amount, 16) d2
from t42;

                     AMOUNT D1                        D2                      
--------------------------- ------------------------- -------------------------
              0.00000000010 Typ=2 Len=2: 187,101      Typ=2 Len=2: bb,65        
             0.000000001499 Typ=2 Len=3: 188,16,0     Typ=2 Len=3: bc,10,0      

Запуск вашего форматирования с этим дает аналогичные результаты:

select amount as actual__________amount,
    TO_CHAR(amount,'FM99999999999999999999999999999990.099999999999')
        as amount__________Changed
from t42
order by amount;    

     ACTUAL__________AMOUNT AMOUNT__________CHANGED                      
--------------------------- ----------------------------------------------
              0.00000000010 ############################################## 
             0.000000001499 0.00000000150/

Если вы можете добавить к вопросу вывод dump() для своих собственных данных, я смогу увидеть, смогу ли я воссоздать именно те значения, которые вы видите.

Как ни странно, это можно было бы «исправить», обновив данные, например:

update t42 set amount = amount * 1;

select amount, dump(amount) d1, dump(amount, 16) d2
from t42;

                     AMOUNT D1                        D2                      
--------------------------- ------------------------- -------------------------
               0.0000000001 Typ=2 Len=2: 188,2        Typ=2 Len=2: bc,2         
             0.000000001499 Typ=2 Len=3: 188,15,100   Typ=2 Len=3: bc,f,64

select amount as actual__________amount,
    TO_CHAR(amount,'FM99999999999999999999999999999990.099999999999')
        as amount__________Changed
from t42
order by amount;

     ACTUAL__________AMOUNT AMOUNT__________CHANGED                      
--------------------------- ----------------------------------------------
               0.0000000001 0.0000000001                                   
             0.000000001499 0.000000001499                                 

Однако вы должны спросить, каково на самом деле правильное значение, которое, вероятно, связано с тем, как/почему/когда оно было повреждено. Я бы очень осторожно относился к этим данным, если они вообще важны, и мне действительно пришлось бы поддержать совет @DazzaL, чтобы привлечь службу поддержки Oracle, чтобы разобраться с этим.

person Alex Poole    schedule 14.01.2013
comment
У меня есть еще один вопрос. Вы сказали, что некоторые отчеты об ошибках предполагают, что имп, как известно, вызывает повреждение. Что это за имп??? - person user1501147; 16.01.2013
comment
@user1501147 — imp — это старый инструмент импорта. Не уверен, есть ли проблемы с более новым impdp; Я видел несколько ссылок на imp на сайте поддержки Oracle. Это только один из способов, которым могло произойти повреждение; если ваши данные не были перенесены из другой базы данных, то imp не имеет значения, и есть какая-то другая причина. - person Alex Poole; 16.01.2013
comment
Я понял, что это ты с первого предложения @alex :-). - person Ben; 16.01.2013
comment
Привет Алекс, В приведенной ниже статье они пояснили, что преобразование в 8-битную -UTF8 приводит к повреждению данных. coresolucoes.com.br/?p=251 Может ли быть проблема в этом? будут - person user1501147; 17.01.2013
comment
@user1501147 user1501147 - я бы подумал, что конкретная ошибка затронет только столбцы VARCHAR2, но это неясно. Вам действительно нужна поддержка Oracle, чтобы помочь определить причину и возможное исправление, только они будут иметь правильную информацию и знать правильные вопросы, чтобы задать вам. Это может быть вовсе не ошибка Oracle, даже если вы использовали imp или impdp, это может быть, например, ошибка в программе OCI - см. примечания поддержки 979657.8 или, в более общем смысле, 311346.1 (жаль, что я не нашел это раньше , хотя не уверен, что полностью согласен с их разделом обнаружения) - или JDBC (4338390.8). - person Alex Poole; 17.01.2013