Могу ли я фильтровать строки по дате в Oracle SQL Loader?

#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>