Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 SQL Loader  [new]
siner
Member

Откуда:
Сообщений: 8
Здравствуйте.
Мне надо с помощью Sql loader загрузить в таблицу информацию из файла в таблицу. Кроме того мне надо загрузить в эту же таблицу имя файла, из которого происходит загрузка. Причем при каждой новой загрузке название этого файла будет новым.
В управляющем CTL-файле INFILE определяет файл, из которого происходит загрузка.


К примеру вот CTL-файл:
LOAD DATA
INFILE *
TRUNCATE
INTO TABLE APPS.XX_MYEXAMPLE
FIELDS TERMINATED BY ';'
TRAILING NULLCOLS
( 
  VAL1,
  VAL2
)


Пусть VAL2 - столбец таблицы под имя файла, из которого происходит загрузка данных в таблицу.
Если поставить INFILE *, то что нужно прописать в блоке TRAILING NULLCOLS, чтобы имя файла, из которого происходит загрузка, записывалось в таблицу?
3 фев 19, 09:38    [21800683]     Ответить | Цитировать Сообщить модератору
 Re: SQL Loader  [new]
Elic
Member

Откуда: 1984. Выбраковка финно-угром продолжается. КЯЗ
Сообщений: 28823
siner
Если поставить INFILE *, то что нужно …, чтобы имя файла, из которого происходит загрузка, записывалось в таблицу?
Такое не поддерживается. CTL придётся генерировать. STFF
3 фев 19, 10:06    [21800690]     Ответить | Цитировать Сообщить модератору
 Re: SQL Loader  [new]
siner
Member

Откуда:
Сообщений: 8
Elic, подскажите, пожалуйста, как реализовать считывание имени файла и его запись в таблицу.
3 фев 19, 14:41    [21800781]     Ответить | Цитировать Сообщить модератору
 Re: SQL Loader  [new]
Vadim Lejnin
Member

Откуда:
Сообщений: 6613
siner,
1) Внешним скриптом (cmd,bash,perl ...) генерируете ctl в котором прописываете имя файла через const

LOAD DATA 
INFILE 'data0032.dat'
TRUNCATE
INTO TABLE APPS.XX_MYEXAMPLE
FIELDS TERMINATED BY ';'
TRAILING NULLCOLS
( 
  VAL1 CONSTANT 'data0032.dat',
  VAL2
)


2) если данные на сервере, то данные загружаются процедурой которая сканирует директорию с входными файлами, генерирует external table с полем constant имени файла как указано выше, переливает данные из external table в нужную таблицу и удаляет external table.
3 фев 19, 17:02    [21800826]     Ответить | Цитировать Сообщить модератору
 Re: SQL Loader  [new]
volodin661
Member

Откуда: Внутренняя Монголия
Сообщений: 410
Vadim Lejnin
siner,
1) Внешним скриптом (cmd,bash,perl ...) генерируете ctl


что касается пункта 1, то вызов следующего perl-скрипта с любыми аргументами отработает идентично и под bash, и под cmd, и под powershell

( загвоздка в том, что в windows ни cmd, ни powershell не поддерживают globbing )

genctl:
#!/usr/bin/env perl

while(<@ARGV>)
{
	print << "EOF";

LOAD DATA 
INFILE '$_'
TRUNCATE
INTO TABLE APPS.XX_MYEXAMPLE
FIELDS TERMINATED BY ';'
TRAILING NULLCOLS
( 
  VAL1 CONSTANT '$_',
  VAL2
)
EOF

}


chmod +x genctl

perl genctl *.dat


PS: сейчас реализован просто вывод на stdout, поэтому случай (2) множества файлов на входе ( *.dat ) нуждается в некоторой доработке
3 фев 19, 21:50    [21800920]     Ответить | Цитировать Сообщить модератору
 Re: SQL Loader  [new]
siner
Member

Откуда:
Сообщений: 8
volodin661, Спасибо, данный способ подходит только для случая когда в директории находится один файл с данными?
3 фев 19, 22:26    [21800931]     Ответить | Цитировать Сообщить модератору
 Re: SQL Loader  [new]
siner
Member

Откуда:
Сообщений: 8
Vadim Lejnin, спасибо
3 фев 19, 22:27    [21800932]     Ответить | Цитировать Сообщить модератору
 Re: SQL Loader  [new]
volodin661
Member

Откуда: Внутренняя Монголия
Сообщений: 410
siner
данный способ подходит только для случая когда в директории находится один файл с данными?


Нет, для всех случаев, но надо решить что будем делать при выводе, когда много файлов на входе ?

а) генерировать много .ctl файлов
б) запускать с помощью perl SQLLDR для каждого обработанного файла
3 фев 19, 22:42    [21800938]     Ответить | Цитировать Сообщить модератору
 Re: SQL Loader  [new]
oragraf
Member

Откуда: Moscow
Сообщений: 1189
siner,
Кусок генерилки-запускалки. Список файлов предварительно в табличку files
Prompt Шаг 3. Сгенерируем управляющий файл для загрузки файлов через SqlLoader
set feed off
set head off
set verify off
set trimspool on
spool &&_loadpath_./&&_loadlob_..ctl replace
prompt options ()
prompt    load data characterset CL8MSWIN1251
prompt    infile      '&&_loadpath_./&&_loadlob_..dat'
prompt    badfile     '&&_loadpath_./&&_loadlob_..bad' 
prompt    discardfile '&&_loadpath_./&&_loadlob_..dis'
prompt    append
prompt    into table &&_O_OWNER_..file_data
prompt    fields terminated by ';' optionally enclosed by '"'
prompt    TRAILING NULLCOLS
prompt    (  
prompt     id,	
prompt     blob_filename boundfiller,
prompt     blob_data     LOBFILE(blob_filename) TERMINATED BY EOF	
prompt    )
spool off
spool &&_loadpath_./&&_loadlob_..dat replace

select to_char(id)|| ';"&&_loadpath_./'||filename||'"' 
  from &&_O_OWNER_..files f;
  
spool off

spool &&_SPOOL_FILE_. append

Prompt Шаг 4. Вызываем загрузчик SQL*Loader для загрузки файлов

host sqlldr userid=&&_O_OWNER_./&&_O_PASS_.@&&_CONNECT_IDENTIFIER. control=&&_loadpath_./&&_loadlob_..ctl log=&&_loadlob_..log
4 фев 19, 14:00    [21801274]     Ответить | Цитировать Сообщить модератору
 Re: SQL Loader  [new]
MazoHist
Member

Откуда:
Сообщений: 83
Необязательно использовать базу. Вариант с поочередной загрузкой каждого файла.

L.cmd
rem грузим все найденные CSV
forfiles /S /M *.csv /C "cmd /C LD @file" 


LD.cmd
@echo off
set fl=%1
echo OPTIONS (SKIP=1) > tmp.ctl
echo load data >> tmp.ctl
echo append >> tmp.ctl
echo into table tab1 >> tmp.ctl
echo fields terminated by ';' >> tmp.ctl
echo TRAILING NULLCOLS  >> tmp.ctl
echo ( F1 CHAR(4000)  >> tmp.ctl
echo , F2 CHAR(4000)  >> tmp.ctl
echo , FNAME CONSTANT '%fl' >> tmp.ctl
echo ) >> tmp.ctl

sqlldr user/pass@db control=tmp.ctl data=%1


ps: forfiles и findstr в винде - аналоги find и grep в *nix, их использование порой бывает очень удобно.
4 фев 19, 14:30    [21801306]     Ответить | Цитировать Сообщить модератору
 Re: SQL Loader  [new]
andrey_anonymous
Member

Откуда: Москва
Сообщений: 17182
MazoHist
forfiles и findstr в винде

Во блин я динозавр, до сих пор обычными for и find пользуюсь :)
4 фев 19, 14:58    [21801349]     Ответить | Цитировать Сообщить модератору
 Re: SQL Loader  [new]
Vadim Lejnin
Member

Откуда:
Сообщений: 6613
andrey_anonymous
MazoHist
forfiles и findstr в винде

Во блин я динозавр, до сих пор обычными for и find пользуюсь :)

Аналогично... :(
Максимум нашел как подстроку вырезать
4 фев 19, 15:13    [21801374]     Ответить | Цитировать Сообщить модератору
 Re: SQL Loader  [new]
siner
Member

Откуда:
Сообщений: 8
MazoHist,

Спасибо. Файл L.cmd в *nix как будет выглядеть?
5 фев 19, 09:00    [21801699]     Ответить | Цитировать Сообщить модератору
 Re: SQL Loader  [new]
MazoHist
Member

Откуда:
Сообщений: 83
siner
MazoHist,

Спасибо. Файл L.cmd в *nix как будет выглядеть?


 find . -type f -name *.csv -exec ld.sh {} \;
5 фев 19, 09:43    [21801714]     Ответить | Цитировать Сообщить модератору
 Re: SQL Loader  [new]
siner
Member

Откуда:
Сообщений: 8
MazoHist,

Был бы очень благодарен, если бы вы изменили и второй скрипт под *nix.
5 фев 19, 10:23    [21801753]     Ответить | Цитировать Сообщить модератору
 Re: SQL Loader  [new]
MazoHist
Member

Откуда:
Сообщений: 83
siner,

ld.sh
#!/bin/sh
echo "OPTIONS (SKIP=1)" > tmp.ctl
echo "load data" >> tmp.ctl
echo "append" >> tmp.ctl
echo "into table tab1" >> tmp.ctl
echo "fields terminated by ';'" >> tmp.ctl
echo "TRAILING NULLCOLS"  >> tmp.ctl
echo "( F1 CHAR(4000)"  >> tmp.ctl
echo ", F2 CHAR(4000)"  >> tmp.ctl
echo ", FNAME CONSTANT '$1'" >> tmp.ctl
echo ")" >> tmp.ctl

sqlldr user/pass@db control=tmp.ctl data=$1
5 фев 19, 10:32    [21801758]     Ответить | Цитировать Сообщить модератору
 Re: SQL Loader  [new]
siner
Member

Откуда:
Сообщений: 8
MazoHist,

В первом файле нужен аргумент после
find . -type f -name *.csv -exec ld.sh {} \; ?

Дело в том что имя найденного файла не передается во второй скрипт, по крайней мере его нет в ctl-файле
5 фев 19, 10:42    [21801771]     Ответить | Цитировать Сообщить модератору
 Re: SQL Loader  [new]
Vadim Lejnin
Member

Откуда:
Сообщений: 6613
siner
MazoHist,

В первом файле нужен аргумент после
find . -type f -name *.csv -exec ld.sh {} \; ?

Дело в том что имя найденного файла не передается во второй скрипт, по крайней мере его нет в ctl-файле


Проверка что передается:
find . -type f -name *.csv -exec echo ld.sh {} \;



Для отладки shell

#!/bin/sh
set -vx
echo "OPTIONS (SKIP=1)" > tmp.ctl
...
5 фев 19, 10:46    [21801775]     Ответить | Цитировать Сообщить модератору
 Re: SQL Loader  [new]
MazoHist
Member

Откуда:
Сообщений: 83
siner,
в моем примере ld.sh должен быть исполняемым. Либо chmod +x ld.sh либо поменять строку на -exec sh ld.sh {} \;
5 фев 19, 11:18    [21801799]     Ответить | Цитировать Сообщить модератору
 Re: SQL Loader  [new]
siner
Member

Откуда:
Сообщений: 8
MazoHist,

Большое спасибо
5 фев 19, 13:24    [21801902]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить