Рассмотрим еще один интересный аспект при загрузке данных. Это загрузка в разделы таблицы. Для начала скажу, что таблица в которой применяется секционирование, имеет несколько разделов данных, которые могут быть расположены в различных табличных пространствах. Мы с вами такие таблицы еще не рассматривали. До них мы доберемся чуть позже, а пока может быть кому-нибудь пригодиться, то как это выполняется! Рассмотрим пример, который я нашел в одной очень интересной книге и практически без изменений переложил для нашего с вами рассмотрения. Итак, создадим таблицу с разделами, но в одном табличном пространстве USERS с именем partition_xact:
create table MILLER.partition_xact( acct_nbr number not null, xact_amt number not null, xact_flag char not null, xact_date date not null) PARTITION BY RANGE (xact_date) (PARTITION P1 VALUES LESS THAN (to_date('01-04-1999','DD-MM-YYYY')), PARTITION P2 VALUES LESS THAN (to_date('01-07-1999','DD-MM-YYYY')), PARTITION P3 VALUES LESS THAN (to_date('01-11-1999','DD-MM-YYYY')), PARTITION P4 VALUES LESS THAN (MAXVALUE)) /
Получаем:
SQL> create table MILLER.partition_xact( 2 acct_nbr number not null, 3 xact_amt number not null, 4 xact_flag char not null, 5 xact_date date not null) 6 PARTITION BY RANGE (xact_date) 7 (PARTITION P1 VALUES LESS THAN (to_date('01-04-1999','DD-MM-YYYY')), 8 PARTITION P2 VALUES LESS THAN (to_date('01-07-1999','DD-MM-YYYY')), 9 PARTITION P3 VALUES LESS THAN (to_date('01-11-1999','DD-MM-YYYY')), 10 PARTITION P4 VALUES LESS THAN (MAXVALUE)) 11 / Таблица создана.
Мы с вами получили таблицу с четырьмя разделами по полю xact_date. В данном случае это и есть секционированная таблица. Далее создадим контрольный файл с именем PART.CTL следующего содержания:
LOAD DATA INFILE 'xact.dat' INTO TABLE partition_xact PARTITION (P1) WHEN xact_flag = 'D' (acct_nbr POSITION(01:10) INTEGER EXTERNAL, xact_amt POSITION(11:20) INTEGER EXTERNAL ":xact_amt * -1", xact_flag POSITION(21:21) CHAR, xact_date POSITION(22:31) DATE "DD-MM-YY" NULLIF xact_date=BLANKS) INTO TABLE partition_xact PARTITION (P1) WHEN xact_flag = 'C' (acct_nbr POSITION(01:10) INTEGER EXTERNAL, xact_amt POSITION(11:20) INTEGER EXTERNAL, xact_flag POSITION(21:21) CHAR, xact_date POSITION(22:31) DATE "DD-MM-YY" NULLIF xact_date=BLANKS)
Здесь применяется та же загрузка по условию с данными переменной длинны, еще и в два захода! Для начала, мы пробуем произвести загрузку в раздел P1. Далее создадим файл с исходными данными для загрузки с именем xact.dat и следующим содержимым:
0000459023 123D01-02-98 0000459023 1233C01-03-99 0000459023 987P01-13-98 0000459024 1000C03-06-99 0000211108 875D23-07-98 0000211123 20987C30-12-99 0000211123 12500D10-01-98 0000023388 1C19-05-99 0000043992 350C12-03-97 0050699390 2899D01-09-97 0000023330 100D26-06-97 0000433020 60C20-11-97 0000004566 230C20-08-97 0000004599 14D05-06-97 0000004599 14D07-06-97 0008887544 9999D11-7-
Далее и последнее создадим исполняемый файл для загрузки данных с именем PART.bat и следующим содержимым:
@echo off set nls_lang=russian_cis.ru8pc866 sqlldr.exe userid=miller/kolobok control=PART.ctl errors=100 bad=PART.bad discard=PART.dis
Итак, все готово, запустим файл PART.bat на исполнение и посмотрим, что получится после его работы! Уу-пс! Возник PART.bad, в котором все записи отправленные нами на загрузку! А вот и log файл:
SQL*Loader: Release 9.2.0.1.0 - Production on Вск Май 30 13:04:52 2004 Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved. Управляющий файл: PART.ctl Файл данных: xact.dat Файл плохих записей: PART.bad Файл удаленных записей: PART.dis (Разрешить удалять все записи) Количество записей для загрузки: ALL Количество записей для пропуска: 0 Допускается ошибок: 100 Массив привязки:64 строк, макс. из 256000 байт Продолжение: ничего не задано Использован маршрут: Условный Таблица PARTITION_XACT, раздел P1, загружен когда XACT_FLAG = 0X44(символ 'D') Для раздела INSERT включен параметр Insert Имя столбца Позиция Дл. Огр. Вкл Тип данных ------------------------------ ---------- ----- ---- ---- --------------------- ACCT_NBR 1:10 10 CHARACTER XACT_AMT 11:20 10 CHARACTER Строка SQL для столбца : ":xact_amt * -1" XACT_FLAG 21:21 1 CHARACTER XACT_DATE 22:31 10 DATE DD-MM-YY NULL, если XACT_DATE = BLANKS Таблица PARTITION_XACT, раздел P1, загружен когда XACT_FLAG = 0X43(символ 'C') Для раздела INSERT включен параметр Insert Имя столбца Позиция Дл. Огр. Вкл Тип данных ------------------------------ ---------- ----- ---- ---- --------------------- ACCT_NBR 1:10 10 CHARACTER XACT_AMT 11:20 10 CHARACTER XACT_FLAG 21:21 1 CHARACTER XACT_DATE 22:31 10 DATE DD-MM-YY NULL, если XACT_DATE = BLANKS Запись 3: Удалена - сбой во всех фразах WHEN. Запись 1: отвергнута - Ошибка в таблице PARTITION_XACT, раздела P1. ORA-14401: ключ вставляемой секции вне указанной секции Запись 5: отвергнута - Ошибка в таблице PARTITION_XACT, раздела P1. ORA-14401: ключ вставляемой секции вне указанной секции Запись 7: отвергнута - Ошибка в таблице PARTITION_XACT, раздела P1. ORA-14401: ключ вставляемой секции вне указанной секции Запись 10: отвергнута - Ошибка в таблице PARTITION_XACT, раздела P1. ORA-14401: ключ вставляемой секции вне указанной секции Запись 11: отвергнута - Ошибка в таблице PARTITION_XACT, раздела P1. ORA-14401: ключ вставляемой секции вне указанной секции Запись 14: отвергнута - Ошибка в таблице PARTITION_XACT, раздела P1. ORA-14401: ключ вставляемой секции вне указанной секции Запись 15: отвергнута - Ошибка в таблице PARTITION_XACT, раздела P1. ORA-14401: ключ вставляемой секции вне указанной секции Запись 16: Забракована - Ошибка в таблице PARTITION_XACT, столбце XACT_DATE. ORA-01840: вводимое значение недостаточно длинное для формата даты Запись 2: отвергнута - Ошибка в таблице PARTITION_XACT, раздела P1. ORA-14401: ключ вставляемой секции вне указанной секции Запись 4: отвергнута - Ошибка в таблице PARTITION_XACT, раздела P1. ORA-14401: ключ вставляемой секции вне указанной секции Запись 6: отвергнута - Ошибка в таблице PARTITION_XACT, раздела P1. ORA-14401: ключ вставляемой секции вне указанной секции Запись 8: отвергнута - Ошибка в таблице PARTITION_XACT, раздела P1. ORA-14401: ключ вставляемой секции вне указанной секции Запись 9: отвергнута - Ошибка в таблице PARTITION_XACT, раздела P1. ORA-14401: ключ вставляемой секции вне указанной секции Запись 12: отвергнута - Ошибка в таблице PARTITION_XACT, раздела P1. ORA-14401: ключ вставляемой секции вне указанной секции Запись 13: отвергнута - Ошибка в таблице PARTITION_XACT, раздела P1. ORA-14401: ключ вставляемой секции вне указанной секции Таблица PARTITION_XACT, раздел P1: 0 Строки успешно загружено. 8 Строки не загружены из-за ошибки в данных. 8 Строки не загружены из-за сбоев во всех фразах WHEN. 0 Строки не загружены из-за того, что все поля были пусты. Таблица PARTITION_XACT, раздел P1: 0 Строки успешно загружено. 7 Строки не загружены из-за ошибки в данных. 9 Строки не загружены из-за сбоев во всех фразах WHEN. 0 Строки не загружены из-за того, что все поля были пусты. Для массива привязки отведено: 5120 байт(64 строк) Байтов буфера чтения: 1048576 Всего пропущено логических записей: 0 Всего прочитано логических записей: 16 Всего забраковано логических записей: 15 Всего удалено логических записей: 1 Прогон начался в Вск Май 30 13:04:52 2004 Прогон кончился в Вск Май 30 13:04:54 2004 Общее время: 00:00:02.47 Процессорное время: 00:00:00.05
Как видим, все записи отвергнуты, так как "ключ вставляемой секции вне указанной секции"! Что-ж в данном случае это соответствует действительности, изменим запись в контролфайле вот так:
LOAD DATA INFILE 'xact.dat' INTO TABLE partition_xact PARTITION (P4) WHEN xact_flag = 'D' (acct_nbr POSITION(01:10) INTEGER EXTERNAL, xact_amt POSITION(11:20) INTEGER EXTERNAL ":xact_amt * -1", xact_flag POSITION(21:21) CHAR, xact_date POSITION(22:31) DATE "DD-MM-YY" NULLIF xact_date=BLANKS) INTO TABLE partition_xact PARTITION (P4) WHEN xact_flag = 'C' (acct_nbr POSITION(01:10) INTEGER EXTERNAL, xact_amt POSITION(11:20) INTEGER EXTERNAL, xact_flag POSITION(21:21) CHAR, xact_date POSITION(22:31) DATE "DD-MM-YY" NULLIF xact_date=BLANKS)
И снова запустим загрузку! После этого снова заглянем в log файл:
SQL*Loader: Release 9.2.0.1.0 - Production on Вск Май 30 13:08:14 2004 Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved. Управляющий файл: PART.ctl Файл данных: xact.dat Файл плохих записей: PART.bad Файл удаленных записей: PART.dis (Разрешить удалять все записи) Количество записей для загрузки: ALL Количество записей для пропуска: 0 Допускается ошибок: 100 Массив привязки:64 строк, макс. из 256000 байт Продолжение: ничего не задано Использован маршрут: Условный Таблица PARTITION_XACT, раздел P4, загружен когда XACT_FLAG = 0X44(символ 'D') Для раздела INSERT включен параметр Insert Имя столбца Позиция Дл. Огр. Вкл Тип данных ------------------------------ ---------- ----- ---- ---- --------------------- ACCT_NBR 1:10 10 CHARACTER XACT_AMT 11:20 10 CHARACTER Строка SQL для столбца : ":xact_amt * -1" XACT_FLAG 21:21 1 CHARACTER XACT_DATE 22:31 10 DATE DD-MM-YY NULL, если XACT_DATE = BLANKS Таблица PARTITION_XACT, раздел P4, загружен когда XACT_FLAG = 0X43(символ 'C') Для раздела INSERT включен параметр Insert Имя столбца Позиция Дл. Огр. Вкл Тип данных ------------------------------ ---------- ----- ---- ---- --------------------- ACCT_NBR 1:10 10 CHARACTER XACT_AMT 11:20 10 CHARACTER XACT_FLAG 21:21 1 CHARACTER XACT_DATE 22:31 10 DATE DD-MM-YY NULL, если XACT_DATE = BLANKS Запись 3: Удалена - сбой во всех фразах WHEN. Запись 16: Забракована - Ошибка в таблице PARTITION_XACT, столбце XACT_DATE. ORA-01840: вводимое значение недостаточно длинное для формата даты Таблица PARTITION_XACT, раздел P4: 7 Строки успешно загружено. 1 Строка не загружены из-за ошибки в данных. 8 Строки не загружены из-за сбоев во всех фразах WHEN. 0 Строки не загружены из-за того, что все поля были пусты. Таблица PARTITION_XACT, раздел P4: 7 Строки успешно загружено. 0 Строки не загружены из-за ошибки в данных. 9 Строки не загружены из-за сбоев во всех фразах WHEN. 0 Строки не загружены из-за того, что все поля были пусты. Для массива привязки отведено: 5120 байт(64 строк) Байтов буфера чтения: 1048576 Всего пропущено логических записей: 0 Всего прочитано логических записей: 16 Всего забраковано логических записей: 1 Всего удалено логических записей: 1 Прогон начался в Вск Май 30 13:08:14 2004 Прогон кончился в Вск Май 30 13:08:16 2004 Общее время: 00:00:02.34 Процессорное время: 00:00:00.03
Теперь только две записи были отброшены, а все остальное ушло в таблицу PARTITION_XACT и данные в ее разделе P4 были успешно получены. Все это несколько мутновато, но может кому-нибудь будет полезно! Я в своей практике сталкивался раза два с такими таблицами, но сам я их не использовал, по этому можете сами придумать что-то подобное и произвести загрузку данных в такую табличку! Думаю у вас это должно получится! :)