#sql #oracle #unix #sql-loader #ctl
Вопрос:
Каждый день я получаю большой файл интерфейса и загружаю все строки, но использую только самую свежую информацию (гораздо меньше строк). Могу ли я выполнить фильтрацию по файлу .ctl, чтобы вставить только самые новые строки?
Это мой файл ctl:
LOAD DATA
INSERT INTO TABLE SCHEMA.TBL_INTERFACE
(
"ID" POSITION(001:008), --varchar2(08),
"FIRSTNAME" POSITION(009:028), --varchar2(20),
"LASTNAME" POSITION(029:048), --varchar2(20),
"DATE" POSITION(049:058), --varchar2(10) FORMAT YYYYMMDD 20211029
)
Это образец интерфейса, который я загружаю:
12345678JUAN CARLOS0 PEREZ0 20211029
23456789JUAN CARLOS1 PEREZ1 20201029
34567890JUAN CARLOS2 PEREZ2 20181029
45678901JUAN CARLOS3 PEREZ3 20171029
Комментарии:
1. Возможно, вы захотите сделать это по-другому. у вас есть этот файл, почему бы не использовать простую команду bash, чтобы избавиться от всех строк, которые вы не хотите загружать. загрузчик sql содержит предложение
when
, но оно не поможет вам отфильтровать строки, содержащие последний день
Ответ №1:
Как насчет функции внешних таблиц? Его преимущество в том, что вы можете писать запросы к нему (и просто фильтровать интересующие вас строки). Недостаток? У вас должен быть доступ к серверу базы данных; никаких проблем — с моей точки зрения, однако; просто вы не можете запускать все локально.
Вот пошаговое руководство:
Поскольку для этой функции требуется доступ к каталогу (объекту Oracle, указывающему на каталог файловой системы), нам придется сначала создать его, подключив как SYS
:
SQL> connect sys as sysdba
Enter password:
Connected.
SQL> create directory ext_dir as 'c:temp';
Directory created.
SQL> grant read, write on directory ext_dir to scott;
Grant succeeded.
Подключитесь как scott
(используйте то, что будет работать над этой проблемой):
SQL> connect scott/tiger
Connected.
Целевая таблица (я отказываюсь использовать зарезервированное слово — DATE
— для имени столбца. Это плохая практика, я советую вам избегать ее):
SQL> desc tbl_interface
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NUMBER
FIRSTNAME VARCHAR2(20)
LASTNAME VARCHAR2(20)
DATUM DATE
Данные хранятся в C:TEMPTEXT.TXT
файле; обратите внимание, что я запускаю Oracle на своем ноутбуке, который, следовательно, действует так, как если бы это был сервер базы данных. Если сервер базы данных не находится на вашем компьютере, вам придется обратиться к администратору базы данных.
12345678JUAN CARLOS0 PEREZ0 20211029
23456789JUAN CARLOS1 PEREZ1 20201029
34567890JUAN CARLOS2 PEREZ2 20181029
45678901JUAN CARLOS3 PEREZ3 20171029
Просто установите формат даты (вам не нужно этого делать).:
SQL> alter session set nls_date_format = 'dd.mm.yyyy';
Session altered.
Давайте, наконец, создадим внешнюю таблицу:
SQL> create table ext_table
2 (id number,
3 firstname varchar2(20),
4 lastname varchar2(20),
5 datum date
6 )
7 organization external
8 (type oracle_loader
9 default directory ext_dir
10 access parameters
11 (records delimited by newline
12 fields (id position(01:08) char(8),
13 firstname position(09:28) char(20),
14 lastname position(29:48) char(20),
15 datum date mask "yyyymmdd"
16 )
17 )
18 location('text.txt')
19 )
20 reject limit unlimited;
Table created.
Там что-нибудь есть?
SQL> select * From ext_table;
ID FIRSTNAME LASTNAME DATUM
---------- -------------------- -------------------- ----------
12345678 JUAN CARLOS0 PEREZ0 29.10.2021
23456789 JUAN CARLOS1 PEREZ1 29.10.2020
34567890 JUAN CARLOS2 PEREZ2 29.10.2018
45678901 JUAN CARLOS3 PEREZ3 29.10.2017
SQL>
Да, есть — все строки из text.txt
.
Поскольку мы используем SQL, нет проблем с применением любого фильтра к данным, например, того, который вы хотели — для получения самых последних данных (сегодняшних).:
SQL> select * From ext_table
2 where datum = trunc(sysdate);
ID FIRSTNAME LASTNAME DATUM
---------- -------------------- -------------------- ----------
12345678 JUAN CARLOS0 PEREZ0 29.10.2021
Очевидно, что теперь это простой вопрос вставки желаемых значений в целевую таблицу:
SQL> insert into tbl_interface (id, firstname, lastname, datum)
2 select id, firstname, lastname, datum
3 from ext_table
4 where datum = trunc(sysdate);
1 row created.
SQL> select * from tbl_interface;
ID FIRSTNAME LASTNAME DATUM
---------- -------------------- -------------------- ----------
12345678 JUAN CARLOS0 PEREZ0 29.10.2021
SQL>