С фиксированной длинной все ясно, но что я не припомню, чтобы мне где-то попадались, такие данные, да и вам такое может понадобиться редко! Поверь те мне, если только в особых случаях. Как правило, я всегда работал и работаю с данными переменной длинны! И вот как. Очень неплохим и полезным средством для загрузки разнообразных данных в Oracle, как это ни странно, является MS Access! Да, вы будете смеяться, но это так! В нем есть очень забавная формировалка экспорта данных, в текстовом формате с разделителями! Вот этот механизм, мне очень помогает! Я сгружаю в MS Access разнообразные xls, dbf, mdb и т.д. А, на выходе получаю стройные ряды текстовых файлов для загрузки в Oracle! Все просто замечательно! Итак, что-то я разболтался! Давайте снова зальем данные в таблицу PRODUCTS для чего снова ее вычистим:
DELETE FROM PRODUCTS / COMMIT /
Получаем:
SQL> DELETE FROM PRODUCTS 2 / 25 строк удалено. SQL> COMMIT 2 / Фиксация обновлений завершена.
Сечас можете взять файлы из прошлого шага или сделать новые, как вам больше нравиться, но я все пройду до конца, чтобы вы не путались! Файл PRODUCTS.bat можно оставить без изменений, а вот два других будем переделывать! Для начала контрольный файл переписываем вот так:
LOAD DATA INFILE 'PRODUCTS.dat' INTO TABLE PRODUCTS FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '"' TRAILING NULLCOLS (MFR_ID, PRODUCT_ID, DESCRIPTION, PRICE, QTY_ON_HAND)
Здесь FIELDS TERMINATED BY ';' означает, что границы данных определены по символу ";", а OPTIONALLY ENCLOSED BY '"' определяет, что данные могут содержать символ обрамления. TRAILING NULLCOLS говорит о том, что если поле для загрузки не имеет данных в файле данных, то в поле записать NULL! Далее идет просто описание полей и все! А, вот PRODUCTS.dat будет иметь следующее содержимое:
REI;2A45C;Бочка металлическая;79;210 ACI;4100Y;Коробка картонная;2,750;25 QSA;XK47;Труба алюминиевая;355;38 BIC;41672;Тарелка фарфоровая;180;0 IMM;779C;Профиль специальный;1875;9 ACI;41003;Рейка деревянная;107;207 ACI;41004;Рейкя пластмассовая;117;139 BIC;41003;Стекломаст рулоны;652;3 IMM;887P;Рубероид рулоны;250;24 QSA;XK48;Гвозд длинный;134;203 REI;2A44L;Доска профильная;4500;12 FEA;112;Стол оффисный;148;115 IMM;887H;Тумбочка прикроватная;54;223 BIC;41089;Сапоги юфтиевые;225;78 ACI;41001;Лампа настольная;55;277 IMM;775C;Осветитель ртутный;1425;5 ACI;4100Z;Монитор LG;2500;28 QSA;XK48A;Подушка ватная;177;37 ACI;41002;Носки черные;76;167 REI;2A44R;Телевизор SAMSUNG;4500;12 IMM;773C;Наушники SONY;975;28 ACI;4100X;Карандаш простой;25;37 FEA;114;Электродвигатель;243;15 IMM;887X;Нож специальный;475;32 REI;2A44G;Бочка пластмассовая;350;14
Видите данные отделены символом ";" друг от друга и все! Естественно, откуда я знаю все эти позиции, так гораздо проще и быстрее! А, если записей скажем миллион или десять! А? :) Запускаем файл загрузки на исполнение и получаем следующее:
C:\Oracle\ora81\bin\LOAD>set nls_lang=russian_cis.ru8pc866 C:\Oracle\ora81\bin\LOAD>sqlldr.exe userid=miller/kolobok@proba control=PRODUCTS.ctl errors=100 bad=PRODUCTS.bad SQL*Loader: Release 8.1.5.0 - Production on Вск Май 16 14:13:34 1004 Copyright (c) 1881, 1001, Oracle Corporation. All rights reserved. Достигнута точка фиксации - счетчик логич. записей 27
Ничего нового вроде нет! И содержимое таблицы тоже самое, что и в первом случае. Смотрим:
SELECT * FROM PRODUCTS /
Получаем:
SQL> SELECT * FROM PRODUCTS 2 / MFR_ID PRODUCT_ID DESCRIPTION PRICE QTY_ON_HAND ------ ---------- --------------------- ---------- ------------ REI 2A45C Бочка металлическая 79 210 ACI 4100Y Коробка картонная 2750 25 QSA XK47 Труба алюминиевая 355 38 BIC 41672 Тарелка фарфоровая 180 0 IMM 779C Профиль специальный 1875 9 ACI 41003 Рейка деревянная 107 207 ACI 41004 Рейка пластмассовая 117 139 BIC 41003 Стекломасс рулоны 652 3 IMM 887P Рубероид рулоны 250 24 QSA XK48 Гвоздь длинный 134 203 REI 2A44L Доска профильная 4500 12 FEA 112 Стол офисный 148 115 IMM 887H Тумбочка прикроватная 54 223 BIC 41089 Сапоги юфтевые 225 78 ACI 41001 Лампа настольная 55 277 IMM 775C Осветитель ртутный 1425 5 ACI 4100Z Монитор LG 2500 28 QSA XK48A Подушка ватная 177 37 ACI 41002 Носки черные 76 167 REI 2A44R Телевизор SAMSUNG 4500 12 IMM 773C Наушники SONY 975 28 ACI 4100X Карандаш простой 25 37 FEA 114 Электродвигатель 243 15 IMM 887X Нож специальный 475 32 REI 2A44G Бочка пластмассовая 350 14 25 строк выбрано.
А, вот содержимое файла журнала уже другое, как и следовало ожидать:
SQL*Loader: Release 8.1.5.0.0 - Production on Вск Май 16 15:36:03 2004 Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved. Управляющий файл: PROD.ctl Файл данных: PROD.dat Файл плохих записей: PROD.bad Файл удаленных записей: PROD.dis (Разрешить удалять все записи) Количество записей для загрузки: ALL Количество записей для пропуска: 0 Допускается ошибок: 100 Массив привязки:64 строк, макс. из 256000 байт Продолжение: ничего не задано Использован маршрут: Условный Таблица PRODUCTS, загружен из каждой логической записи. Режим вставки действует для этой таблицы: INSERT Действует опция TRAILING NULLCOLS Имя столбца Позиция Дл. Огр. Вкл Тип данных ------------------------------ ---------- ----- ---- ---- --------------------- MFR_ID FIRST * ; O(") CHARACTER PRODUCT_ID NEXT * ; O(") CHARACTER DESCRIPTION NEXT * ; O(") CHARACTER PRICE NEXT * ; O(") CHARACTER QTY_ON_HAND NEXT * ; O(") CHARACTER Таблица PRODUCTS: 25 Строки успешно загружено. 0 Строки не загружены из-за ошибки в данных. 0 Строки не загружены из-за сбоев во всех фразах WHEN. 0 Строки не загружены из-за того, что все поля были пусты. Для массива привязки отведено: 82560 байт(64 строк) Байтов буфера чтения: 1048576 Всего пропущено логических записей: 0 Всего прочитано логических записей: 25 Всего забраковано логических записей: 0 Всего удалено логических записей: 0 Прогон начался в Вск Май 16 15:36:03 2004 Прогон кончился в Вск Май 16 15:36:05 2004 Общее время: 00:00:02.31 Процессорное время: 00:00:00.01
Обратите внимание, что поля PRICE, QTY_ON_HAND обозначены как CHARACTER, а в реальной таблице они имеют другой тип! Именно здесь и сработало неявное преобразование. Вот так грузятся данные переменной длинны. Еще один способ, загрузки носит название - загрузка вложенных данных. Давайте рассмотрим его. Итак, для начала очистим нашу учебную табличку:
DELETE FROM PRODUCTS / COMMIT /
Получаем:
SQL> DELETE FROM PRODUCTS 2 / 25 строк удалено. SQL> COMMIT 2 / Фиксация обновлений завершена.
Теперь слейте вместе файлы PRODUCTS.ctl и PRODUCTS.dat, например, вот так:
C:\copy PRODUCTS.dat+ PRODUCTS.ctl PRODUCTS.txt
Затем смените расширение файла PRODUCTS.txt на PRODUCTS.ctl и отредактируйте его содержимое вот так:
LOAD DATA INFILE * INTO TABLE PRODUCTS FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '"' TRAILING NULLCOLS (MFR_ID, PRODUCT_ID, DESCRIPTION, PRICE, QTY_ON_HAND) BEGINDATA REI;2A45C;Бочка металлическая;79;210 ACI;4100Y;Коробка картонная;2,750;25 QSA;XK47;Труба алюминиевая;355;38 BIC;41672;Тарелка фарфоровая;180;0 IMM;779C;Профиль специальный;1875;9 ACI;41003;Рейка деревянная;107;207 ACI;41004;Рейкя пластмассовая;117;139 BIC;41003;Стекломаст рулоны;652;3 IMM;887P;Рубероид рулоны;250;24 QSA;XK48;Гвозд длинный;134;203 REI;2A44L;Доска профильная;4500;12 FEA;112;Стол оффисный;148;115 IMM;887H;Тумбочка прикроватная;54;223 BIC;41089;Сапоги юфтиевые;225;78 ACI;41001;Лампа настольная;55;277 IMM;775C;Осветитель ртутный;1425;5 ACI;4100Z;Монитор LG;2500;28 QSA;XK48A;Подушка ватная;177;37 ACI;41002;Носки черные;76;167 REI;2A44R;Телевизор SAMSUNG;4500;12 IMM;773C;Наушники SONY;975;28 ACI;4100X;Карандаш простой;25;37 FEA;114;Электродвигатель;243;15 IMM;887X;Нож специальный;475;32 REI;2A44G;Бочка пластмассовая;350;14
Здесь слово BEGINDATA означает начала блока загружаемых данных. В данном случае контрольный файл выполняет двойную функцию и описывает правила загрузки и несет данные для нее! Если вам такой способ кажется более удачным, можете его использовать, если нет, то это как вам удобнее. Обратите так же внимание, что после ключевого слова INFILE стоит просто знак "*". Содержимое журнала после такой загрузки будет такое:
SQL*Loader: Release 9.2.0.1.0 - Production on Вск Май 16 15:58:22 2004 Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved. Управляющий файл: PROD.ctl Файл данных: PROD.ctl Файл плохих записей: PROD.bad Файл удаленных записей: PROD.dis (Разрешить удалять все записи) Количество записей для загрузки: ALL Количество записей для пропуска: 0 . . . PRICE NEXT * ; O(") CHARACTER QTY_ON_HAND NEXT * ; O(") CHARACTER . . . Общее время: 00:00:02.31 Процессорное время: 00:00:00.01
Отличие только в записи файла данных, все остальное, так же как и в прошлый раз. Для примера можете попробовать загрузку с опциями загрузки для таблиц, например TRUNCATE! Удачи! :)