![]() |
|
Программирование >> Oracle
Глава 9 посредственно. В руководстве Oracle Server Utilities Guide приводится пример такой загрузки. Однако мне этот подход кажется крайне сложным и непрозрачным, не говоря уже о том, что придется устанавливать триггеры для таблицы для поддержки процесса загрузки. А что если таблицы используются по ходу загрузки для других задач? Для них триггеры не должны срабатывать, но нет никакого способа создать триггер, срабатывающий только при вставке строк с помощью утилиты SQLLDR. Поэтому мне захотелось найти более простой способ. Зачастую при загрузке сложных данных, как в представленном примере, быстрее, эффективнее и проще загрузить данные в рабочую таблицу, а затем обработать их с помощью небольшой хранимой процедуры. Именно так я и поступил с представленным выше отчетом. Я использовал следующий управляющий файл: LOAD DATA INTO TABLE TEMP REPLACE (seqno RECNUM, text Position(1:1024)) для загрузки данных в таблицу, созданную оператором tkyte@TKYTE816> create table temp 2 (seqno int primary key, 3 text varchar2(4 000)) 4 organization index 5 overflow tablespace data; Table created. Конструкция RECNUM в управляющем файле требует от утилиты SQLLDR подставлять порядковый номер текущей записи для соответствующего столбца при загрузке данных. В результате первой записи будет присвоен номер 1, сотой - номер 100 и т.д. Затем я использовал маленькую хранимую процедуру для переформатирования данных в требуемый вид. Эта процедура последовательно читает каждую входную строку из таблицы. Затем она просматривает строку и: если строка содержит подстроку Detailed Report, выбирает из строки число и за- поминает его в переменной L SERIAL NO; если строка содержит подстроку Location, данные о местонахождении помещаются в переменную L LOCATION; если строка содержит подстроку Status, данные о состоянии помещаются в пере- менную L STATUS и вставляется новая запись. В этот момент мы собрали все необходимые поля записи. Имеется порядковый номер, дата и время (см. следующий пункт списка) и местонахождение. для других строк мы проверяем, может ли строка быть преобразована в дату. Если не может, мы ее вообще пропускаем. Это делается в обработчике соответствующей исключительной ситуации. Загрузка даннх Вот эта процедура: tkyte@TKYTE816> create or replace procedure reformat 2 as 3 l serial no t.serial no%type; 4 l date time t.date time%type; 5 l location t.location%type; 6 l status t.status%type; 7 l temp date date; 8 begin 9 for x in (select * from temp order by seqno) 10 loop 11 if (x.text like Detailed Report% ) then 12 l serial no := substr(x.text, 1, instr(x.text,-)-l) ; 13 elsif (x.text like Location : %) then 14 l location := substr(x.text, instr(x.text,:)+2); 15 elsif (x.text like %Status %:%) then 16 l status := substr(x.text, instr(x.text,:)+2); 17 insert into t (serial no, date time, location, status) 18 values (l serial no, l date time, l location, l status) ; 19 else 20 begin 21 l temp date := to date (ltrim(rtxim(x. text)), 22 Month dd, yyyy hh24:mi); 23 l date time := x.text; 24 exception 25 when others then null; 26 end; 27 end if; 28 end loop; 2 9 end; 30 / Procedure created. Если сравнить этот объем работы с тем, что необходимо было бы проделать для создания сложных триггеров, запоминающих состояние между вставками, и координации работы этих триггеров с другими приложениями, обращающимися к таблице, вывод очевиден. Загрузка непосредственно в целевую таблицу, может, и сэкономит пару операций ввода/вывода, но соответствующий код будет ненадежным в силу сложности и уровня применяемых приемов. Из этого примера можно сделать вывод о том, что при решении сложной задачи надо стараться максимально уменьшить ее сложность. Один из способов добиться этого - использовать соответствующие задаче средства. В данном случае мы использовали PL/ SQL для написания простой процедуры, помогающей преобразовать данные в нужный формат после загрузки. Это - самый простой способ решения задачи. Не всегда правильно делать все с помощью утилиты SQLLDR, однако во многих случаях утилита SQLLDR оказывается более подходящим средством, чем программы на PL/SQL. Используйте то, что лучше всего подходит для решения конкретной задачи. Глава 9 Загрузка файла в поля типа LONG RAW или LONG Хотя тип данных LONG RAW и не рекомендуется использовать в Oracle8i, иногда он встречается в старых приложениях, и работать с ним все равно приходится. Иногда необходимо загрузить файл или файлы, в столбец типа LONG RAW, и вместо того, чтобы писать для этого специальную программу, хотелось бы использовать утилиту SQLLDR. Хорошая новость в том, что это можно сделать, а плохая - что это не слишком просто и не совсем подходит для загрузки большого количества файлов. Чтобы загрузить данные типа LONG RAW с помощью SQLLDR, в общем случае понадобится отдельный управляющий файл для каждого загружаемого файла (для каждой строки), если только все файлы не одинакового размера. Чтобы заставить утилиту SQLLDR это сделать, необходимо прибегнуть к хитрости. Придется работать с группой буферов размером 64 Кбайт или меньше и определить, сколько записей такого размера необходимо конкатенировать при загрузке. Допустим, требуется загрузить файл длиной 1075200 байт. Соответствующий управляющий файл может выглядеть так: (Числа в скобках справа, выделенные наклонным шрифтом, не являются частью управляющего файла, они используются для ссылок на строки.) options(bindsize=1075700, rows=l) (1) Load Data (2) Infile mydata.dat fix 53760 (3) concatenate 20 (4) Preserve Blanks (5) Into Table foo (6) Append (7) (id constant l,bigdata raw(1075200)) (8) Фокус в том, что 53760* 20 = 1075200, и 53760 - самое большое число, являющееся делителем 1075200, меньшим, чем 64 Кбайт. Необходимо найти самое большое целое число, не превышающее 64 Кбайт, для использования в качестве фиксированного размера записи, а затем конкатенировать 20 таких записей для получения одной физической записи - содержимого файла. Итак, в строке (3) мы задали число 53760 как фиксированный размер входной записи. Это отключает обычную интерпретацию утилитой SQLLDR символа перевода строки как конца записи. Утилита SQLLDR теперь считает записью 53760 байт, независимо от содержащихся в них данных. Строка (4) указывает SQLLDR, что логическая запись (то, что загружается) будет состоять из 20 таких физических записей, соединенных вместе. Мы использовали параметр bindsize=1075700 в строке (1), чтобы задать буфер связывания такого размера, чтобы хватило на весь входной файл, с запасом (для других столбцов). Наконец, в строке (8) мы задаем размер буфера для этого столбца типа RAW (стандартно используется буфер размером 255 байт). Этот управляющий файл загрузит данные из файла MYDATA,DAT в таблицу FOO, помещая в столбец ID постоянное значение 1, а в столбец BIGDATA - содержимое
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |