#sql #oracle #sql-loader
#sql #Oracle #sql-загрузчик
Вопрос:
Я пытаюсь перенести таблицу из базы данных sybase в базу данных Oracle. Ниже приведена структура моей базы данных sybase.
Я использовал bcp для извлечения всех записей. Мои извлеченные записи, как показано ниже —
1|0.1|1/7/2010 12:00:00 AM|<exm><id>1</id></exm>
2|0.2|1/8/2010 12:00:00 AM|<exm><id>1</id></exm>
Я использую следующую команду sqlldr для вставки записей в базу данных oracle.
sqlldr 'username/passwd@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=myhost.com)(PORT=1111)))(CONNECT_DATA=(SID=MYSIDE)(SERVER=DEDICATED)))' control=loader.ctl log=mylog.log
Это мой файл загрузчика (loader.ctl)
LOAD DATA
INLINE '/tmp/bcp_out.txt'
INTO TABLE MY_TABLE
FIELDS TERMINATED BY '|'
TRAILING NULLCOLS
(ID,
VERSION,
DATE,
STATEMENT CHAR(10000))
Итак, из приведенной выше таблицы мы хотим, чтобы дата, поступающая из sybase, была преобразована в oracle timestamp, а оператор был преобразован в Oracle CLOB.
Не могли бы вы подсказать, какие изменения я должен внести в файл загрузчика для достижения моей цели?
Ответ №1:
Целевая таблица (в Oracle; обратите внимание, что date
это недопустимое имя столбца (если оно не заключено в двойные кавычки, но я бы не рекомендовал этого)):
SQL> desc test
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NUMBER
VERSION VARCHAR2(5)
DATUM TIMESTAMP(6)
STATEMENT CLOB
SQL>
Управляющий файл (включены образцы данных; вероятно, они будут у вас в отдельном файле; кроме того, я не знаю, что на самом деле представляет 1/7/2010 — это 1 июля или 7 января — формат даты, возможно, потребуется изменить):
load data
infile *
replace
into table test
fields terminated by '|'
trailing nullcols
(
id,
version,
datum "to_date(:datum, 'dd/mm/yyyy hh:mi:ss am')",
statement
)
begindata
1|0.1|1/7/2010 12:00:00 AM|<exm><id>1</id></exm>
2|0.2|1/8/2010 12:00:00 AM|<exm><id>1</id></exm>
Сеанс загрузки и результат:
SQL> $sqlldr scott/tiger control=test22.ctl log=test22.log
SQL*Loader: Release 11.2.0.2.0 - Production on Uto Lis 13 18:16:41 2020
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Commit point reached - logical record count 1
Commit point reached - logical record count 2
SQL> -- you don't have to do that; I'm just showing *what is what* in the timestamp
SQL> alter session set nls_timestamp_format = 'dd.mm.yyyy hh:mi:ss.ff6';
Session altered.
SQL> select * from test;
ID VERSION DATUM STATEMENT
---------- ------- ------------------------------ ------------------------------
1 0.1 01.07.2010 12:00:00.000000 AM <exm><id>1</id></exm>
2 0.2 01.08.2010 12:00:00.000000 AM <exm><id>1</id></exm>
SQL>
Как в другом формате даты:
SQL> select to_timestamp('1 Mon 2020 12:00:00:000 am', 'dd Mon yyyy hh:mi:ss:ff am') from dual;
TO_TIMESTAMP('1SIJ202012:00:00:000AM','DDMONYYYYHH:MI:SS:FFAM')
---------------------------------------------------------------------------
01.01.20 00:00:00,000000000
SQL>
Комментарии:
1. Я создал управляющий файл как ваш, но получаю следующую ошибку в файле журнала — ORA-01950: нет привилегий в табличном пространстве «PORTDATA’
2. Администратор базы данных должен предоставить вам квоту для этого табличного пространства,
3. Извините за это.. С этим разобрались. Также мне интересно узнать, каким должен быть формат даты, если дата наступает как — 1 января 2010 года 12:00:00:000AM
4. Вы бы использовали соответствующую маску формата:
dd Mon yyyy hh:mi:ss:ff am
5. Он говорит, что формат даты не распознан. Попробовал MMM вместо Mon и получил ту же ошибку. Есть ли какой-либо другой аспект, на который я могу обратить внимание?
Ответ №2:
Вам действительно нужно, чтобы тип данных oracle был ВРЕМЕННОЙ МЕТКОЙ? Из того, что я вижу, ДАТЫ будет достаточно. В oracle, в отличие от некоторых других СУБД, тип данных ДАТЫ включает время, вплоть до секунды. В oracle ВРЕМЕННАЯ МЕТКА включает дату и время с точностью до наносекунды, а также может иметь варианты часовых поясов.
В документации приведен очень хороший пример работы с датами во входном файле csv. Адаптируя это к вашей ситуации:
LOAD DATA
INLINE '/tmp/bcp_out.txt'
INTO TABLE MY_TABLE
FIELDS TERMINATED BY '|'
DATE FORMAT "mm/dd/yyyy hh12:mi:ss AM"
TRAILING NULLCOLS
(ID,
VERSION,
DATE,
STATEMENT CHAR(10000))
Дополнительные пояснения к модели формата даты здесь.
Что касается clob, я не могу здесь помочь. Никогда не делал этого сам, но я бы начал с просмотра документов для sqlldr.