Базы данных Oracle - статьи

         

у вас есть уже всё,


В принципе, у вас есть уже всё, что необходимо для реализации задуманного. И написать подобную утилиту вы наверняка сможете сами. И возможно даже лучше чем то, что предложено ниже.
Собственно решением является plsql пакет fp_exp с единственной public процедурой to_excel, которая вызывается без всяких параметров, например, в пункте меню "Экспорт в Excel": BEGIN fp_exp.to_excel; END;
Перед началом использования нужно выполнить предварительную настройку пакета, установив значения константам, находящимся в спецификации пакета.
Утилита изначально разрабатывалась для использования с Forms Server, работающим под Linux. Затем была перенесена в среду Oracle Applications (та же архитектура, но под SUN Solaris). Поэтому приводится вариант пакета для web реализации. Для работы в клиент-сервер, тело процедуры to_excel нужно лишь чуть-чуть подправить, что не должно вызвать у вас затруднений. PACKAGE fp_exp /* -- fp_exp 15-JUL-2003 by pal (Pavel Luzanovv) -- НАЗНАЧЕНИЕ -- Экспорт данных текущего блока в MS Excell -- МОДИФИКАЦИЯ -- 15-JUL-2003 pal Создание */ IS -- На что заменять символ табуляции в
значении элемента формы chr9subst_pc CONSTANT VARCHAR2(3) := ' ';
-- На что заменять символ перевода строки
в значении элемента формы chr10subst_pc CONSTANT VARCHAR2(1) := ' ';
-- В каком формате выводить элементы типа даты date_format_pc CONSTANT VARCHAR2(8) := 'DD.MM.YY';
-- каталог на сервере приложения, где
будут создаваться файлы экспорта tempdir_pc CONSTANT VARCHAR2(255) := '/oraapp/tempdata/';
-- относительный путь до cgi-скрипта,
для использования -- в WEB.SHOW_DOCUMENT cgi_script_pc CONSTANT VARCHAR2(255) :=
'/cgi-bin/exp2xls';
PROCEDURE to_excel; END fp_exp;
PACKAGE BODY fp_exp IS TYPE item_rectype IS RECORD ( name VARCHAR2(30), prompt VARCHAR2(255), datatype VARCHAR2(255) ); TYPE item_tabtype IS TABLE OF item_rectype
INDEX BY BINARY_INTEGER; item_tab item_tabtype;
/* --------- LOCAL MODULES --------- */ PROCEDURE show_progress (message_in IN VARCHAR2) IS BEGIN MESSAGE(message_in, NO_ACKNOWLEDGE); SYNCHRONIZE; END show_progress;


FUNCTION tempfilename RETURN VARCHAR2 IS BEGIN RETURN (USERDBMS_RANDOM.STRING('U', 10)); END tempfilename;
FUNCTION setup_items (blk_in IN VARCHAR2)
RETURN PLS_INTEGER /* Определим находящиеся на экране
столбцы текущего блока */ IS cur_item_v VARCHAR2(30); last_item_v VARCHAR2(30); index_v PLS_INTEGER := 0; BEGIN cur_item_v := GET_BLOCK_PROPERTY (blk_in, FIRST_ITEM); last_item_v := GET_BLOCK_PROPERTY (blk_in, LAST_ITEM); item_tab.DELETE;
LOOP IF GET_ITEM_PROPERTY (blk_in'.'
cur_item_v, DISPLAYED) = 'TRUE' AND GET_ITEM_PROPERTY (blk_in'.'
cur_item_v, VISIBLE) = 'TRUE' AND GET_ITEM_PROPERTY (blk_in'.'
cur_item_v, ITEM_CANVAS) IS NOT NULL AND GET_ITEM_PROPERTY (blk_in'.'
cur_item_v, ITEM_TYPE) IN ('TEXT ITEM', 'LIST',
'DISPLAY ITEM','CHECKBOX', 'RADIO GROUP') THEN index_v := index_v + 1; item_tab(index_v).name :=
GET_ITEM_PROPERTY(blk_in'.'cur_item_v, ITEM_NAME); IF GET_ITEM_PROPERTY (blk_in
'.'cur_item_v, ITEM_TYPE) = 'CHECKBOX' THEN item_tab(index_v).prompt :=
GET_ITEM_PROPERTY(blk_in'.'cur_item_v, LABEL); ELSE item_tab(index_v).prompt :=
GET_ITEM_PROPERTY(blk_in'.'cur_item_v, PROMPT_TEXT); END IF; item_tab(index_v).datatype := GET_ITEM_PROPERTY(blk_in'.'
cur_item_v, DATATYPE); END IF;
EXIT WHEN cur_item_v = last_item_v; cur_item_v := GET_ITEM_PROPERTY (blk_in
'.'cur_item_v, NEXTITEM); END LOOP;
RETURN (index_v); END setup_items;
FUNCTION format_value ( value_in IN VARCHAR2, datatype_in IN VARCHAR2 DEFAULT NULL ) RETURN VARCHAR2 IS retval VARCHAR2(32767) := value_in; BEGIN IF datatype_in = 'DATE' THEN retval := TO_CHAR(TO_DATE(retval),
date_format_pc); ELSE retval := REPLACE (retval, CHR(9),
chr9subst_pc); retval := REPLACE (retval, CHR(10),
chr10subst_pc); IF SUBSTR(retval, 1, 1) IN
('-', '+', '=') THEN retval := ' ' retval; END IF; END IF;
RETURN (retval); END format_value; /* ---------- PUBLIC MODULES ----------- */ PROCEDURE to_excel IS cur_block_c CONSTANT VARCHAR2(30)
:= NAME_IN ('SYSTEM.CURSOR_BLOCK'); cur_item_c CONSTANT VARCHAR2(61)
:= NAME_IN ('SYSTEM.CURSOR_ITEM'); cur_record_c CONSTANT VARCHAR2(30)
:= NAME_IN ('SYSTEM.CURSOR_RECORD'); outfilename_v VARCHAR2(255); -- := 'c:\tmp\'USER'.xls';
-- test in C-S mode outfile_v TEXT_IO.FILE_TYPE; num_items_v PLS_INTEGER; line_v VARCHAR2(32767); counter_v PLS_INTEGER := 0;


uncommited_changes EXCEPTION; BEGIN IF NAME_IN('SYSTEM.FORM_STATUS') <> 'QUERY' THEN RAISE uncommited_changes; END IF;
FIRST_RECORD;
show_progress ('Формирование
списка полей для экспорта...'); num_items_v := setup_items
(cur_block_c);
show_progress ('Открытие временного файла...'); -- for C- S mode make adjustments below outfilename_v := tempfilename; outfile_v := TEXT_IO.FOPEN
(tempdir_pcoutfilename_v, 'w');
show_progress ('Формирование
строки заголовков столбцов...'); line_v := NULL; FOR i IN 1 .. num_items_v LOOP line_v := line_v format_value
(item_tab(i).prompt); IF i < num_items_v THEN line_v
:= line_v CHR(9); END IF; END LOOP; TEXT_IO.PUT_LINE(outfile_v, line_v);
LOOP IF MOD (counter_v, 100) = 0 THEN show_progress ( 'Форматирование записей блока
(' TO_CHAR(counter_v,'99990') ')...' ); END IF;
counter_v := counter_v + 1; line_v := NULL; FOR i IN 1 .. num_items_v LOOP line_v := line_v format_value ( NAME_IN (cur_block_c'.
'item_tab(i).name), item_tab(i).datatype ); IF i < num_items_v THEN line_v
:= line_v CHR(9); END IF; END LOOP; TEXT_IO.PUT_LINE(outfile_v, line_v);
EXIT WHEN NAME_IN('SYSTEM.LAST_RECORD')
= 'TRUE'; NEXT_RECORD; END LOOP; TEXT_IO.FCLOSE(outfile_v); item_tab.DELETE; GO_RECORD(TO_NUMBER(cur_record_c)); GO_ITEM (cur_item_c);
show_progress ( 'Всего экспортировано '
TO_CHAR(counter_v) ' записей' ); WEB.SHOW_DOCUMENT(cgi_script_pc
'?' outfilename_v, '_blank'); --host('cmd /C start excel '
outfilename_v); -- test in C-S mode EXCEPTION WHEN uncommited_changes THEN message('Перед выполнеием экспорта,
сохраните сделанные изменения!'); WHEN OTHERS THEN IF TEXT_IO.IS_OPEN(outfile_v)
THEN TEXT_IO.FCLOSE(outfile_v); END IF; RAISE; END to_excel; END fp_exp;
Не забудьте про cgi скрипт!

Содержание раздела