Как вы переводите из научной нотации в Oracle SQL? - PullRequest
4 голосов
/ 29 февраля 2012

Мы пытаемся загрузить файл, созданный FastExport, в базу данных Oracle.
Однако столбец Float экспортируется следующим образом: 1.47654345670000000000 E010.

Как настроить SQL * Loader для его импорта таким образом.

Ожидается, что скрипт управления будет выглядеть так:

OPTIONS(DIRECT=TRUE, ROWS=20000, BINDSIZE=8388608, READSIZE=8388608)
UNRECOVERABLE LOAD DATA 
infile 'data/SOME_FILE.csv'
append
INTO TABLE SOME_TABLE
fields terminated by ','
OPTIONALLY ENCLOSED BY '"' AND '"'
trailing nullcols (
    FLOAT_VALUE             CHAR(38)       "???????????????????",
    FILED02                 CHAR(5)        "TRIM(:FILED02)",
    FILED03                 TIMESTAMP      "YYYY-MM-DD HH24:MI:SS.FF6",
    FILED04                 CHAR(38)
)


Я пытался to_number('1.47654345670000000000 E010', '9.99999999999999999999 EEEE')

Ошибка: ORA-01481: invalid number format model ошибка.


Я пытался to_number('1.47654345670000000000 E010', '9.99999999999999999999EEEE')

Ошибка: ORA-01722: invalid number


Вот решения, которые я придумал в порядке предпочтения:

  1. to_number(replace('1.47654345670000000000 E010', ' ', ''))
  2. to_number(TRANSLATE('1.47654345670000000000 E010', '1 ', '1'))

Я хотел бы знать, есть ли более эффективные решения.

Ответы [ 4 ]

7 голосов
/ 01 марта 2012

Насколько я знаю, to_number не может игнорировать пробел, и вы ничего не можете сделать в SQL * Loader, чтобы подготовить его.Если вы не можете удалить его, предварительно обработав файл, который, как вы предлагаете, не являются опцией, вам придется использовать строковую функцию в какой-то момент.Я бы не ожидал, что это добавит огромное количество обработки, сверх того, что to_number будет делать в любом случае, но я всегда пробовал бы это и видел, а не предполагал что-либо - избегание строковых функций звучит немного как преждевременная оптимизация.В любом случае, самое простое - это, возможно, replace:

select to_number(replace('1.47654345670000000000 E010',' ',''),
    '9.99999999999999999999EEEE') from dual;

или просто для отображения:

column num format 99999999999
select to_number(replace('1.47654345670000000000 E010',' ',''),
    '9.99999999999999999999EEEE') as num from dual


         NUM
------------
 14765434567

Вы можете определить свою собственную функцию, чтобы немного упростить файл управления, но не увереныэто стоило бы того.

На ум приходят два других варианта.(a) Загрузите во временную таблицу как varchar, а затем заполните реальную таблицу, используя to_number(replace());но я сомневаюсь, что это приведет к улучшению производительности и может быть значительно хуже.Или (b) если вы используете 11g, загрузите в столбец varchar в реальной таблице и сделайте ваш числовой столбец виртуальный столбец , который применяет функции.

На самом деле,Третий вариант ... вообще не использовать SQL Loader, а использовать CSV-файл как внешнюю таблицу и заполнить ее реальной таблицей.Вам все равно придется выполнить to_number(replace()), но вы можете увидеть разницу в производительности по сравнению с этим в SQL Loader.Разница может быть в том, что, конечно, хуже, но стоит попробовать.

3 голосов
/ 29 октября 2015

Изменение ширины номера с помощью «set numw»


выберите номер из блабла>

результат >> 1,0293E + 15


установить номер 20;

выберите номер из блабла>

результат >> 1029301200000021

1 голос
/ 18 августа 2014

В Oracle 11g нет необходимости специально конвертировать числа.

Просто используйте integer external в .ctl -файле:

Я попробовал следующее в моей БД Oracle:

field MYNUMBER has type NUMBER.

Внутри .ctl -файла я использовал следующее определение:

MYNUMBER integer external

В файле данных значение: MYNUMBER: -1.61290E-03

Что касается результата: sqlldr правильно загрузил нотацию: MYNUMBER field: -0.00161290

Я не уверен, что это ошибка или особенность; но работает в Oracle 11g.

1 голос
/ 01 марта 2012

Вот решение, которое я выбрал:

OPTIONS(DIRECT=TRUE, ROWS=20000, BINDSIZE=8388608, READSIZE=8388608)
UNRECOVERABLE LOAD DATA 
infile 'data/SOME_FILE.csv'
append
INTO TABLE SOME_TABLE
fields terminated by ','
OPTIONALLY ENCLOSED BY '"' AND '"'
trailing nullcols (
    FLOAT_VALUE             CHAR(38)       "REPLACE(:FLOAT_VALUE,' ','')",
    FILED02                 CHAR(5)        "TRIM(:FILED02)",
    FILED03                 TIMESTAMP      "YYYY-MM-DD HH24:MI:SS.FF6",
    FILED04                 CHAR(38)
)

В моем решении преобразование в число подразумевается: "REPLACE(:FLOAT_VALUE,' ','')"

...