Как уже указывалось ранее, в ORACLE встроено несколько служебных модулей, предлагающих ряд дополнительных возможностей, недоступных в SQL или PL/SQL. В настоящем разделе рассмотрим особенности работы с некоторыми из них. Начнем же с рассмотрения модуля серверного вывода DBMS_OUTPUT.
В PL/SQL не предусмотрены средства, обеспечивающие ввод/вывод. Это было сделано преднамеренно, так как для работы с данными, хранимыми в базе, выводить значения переменных и структуры данных не нужно. Тем не менее, при отладке программ средство ввода/вывода весьма полезно. Именно поэтому в, состав PL/SQL 2.0 был включен модуль DBMS_OUTPUT, обеспечивающий вывод информации. Здесь следует также отметить, что средства ввода данных в языке PL/SQL до сих пор не существует. Однако вводить информацию можно при помощи переменных подстановки SQL * Plus, пакетной утилиты ORACLE. В PL/SQL 2.3 и выше имеется также модуль UTL_FILE, который используется для чтения информации из файлов операционной системы и для записи информации в файлы (см. соответствующий параграф настоящего пособия).
Владельцем модуля DBMS_OUTPUT, как и других модулей DBMS (СУБД), является пользователь ОRACLE с именем SYS. В файле-сценарии создания DBMS_OUTPUT роли PUBLIC предоставляется полномочие ЕХЕСUTE на этот модуль; кроме того, в данном файле для модуля создается общий синоним. Это означает, что любой пользователь ОRACLE может, вызывать подпрограммы модуля DBMS_OUTPUT не указывая перед его именем SYS.
Принципы работы модуля DBMS_OUTPUT следующий: c помощью процедур этого модуля реализованы две базовые операции – GET и PUT. Операция PUT берет свои аргументы и помещает во внутренний буфер для хранения. Операция GET считывает этот буфер и возвращает его содержимое процедуре в качестве аргумента. Размер буфера устанавливается с помощью процедуры ENABLE.
Выполнение операции PUT обеспечивается процедурами PUT, PUT_LINE и NEW_LINE, а выполнение операции GET – процедурами GET_LINE и GET_LINES. Управляют буфером процедуры ENABLE и DISABLE.
Процедуры PUT и PUT_LINE определены в модуле следующим образом:
procedure PUT (a varchar2);
procedure PUT (a number);
procedure PUT (a date);
procedure PUT_LINE (a varchar2);
procedure PUT_LINE (a number);
procedure PUT_LINE (a date).
Как видно данные процедуры переопределяются типом параметра.
Буфер организован в виде строк, каждая из которых может состоять не более чем из 255 байт. PUT_LINE добавляет к аргументу символ новой строки, сообщая о конце строки; PUT же этого не делает. Вызов PUT_LINE аналогичен вызову PUT с последующим вызовом NEW_LINE.
Процедура GET_LINE определена в модуле следующим образом:
procedure GET_LINE (line out varchar2, status out integer);
где LINE представляет собой последовательность символов, из которых состоит одна строка буфера, а STATUS указывает на то, успешно или нет, была считана эта строка. Максимальная длина строки – 255 байт. Если строка считана, то в переменной status находится 0, если в буфере больше нет строк для считывания, то в STATUS – 1.
Аргументом процедуры GET_LINES является индексная таблица. Тип таблицы и вызов данной процедуры выглядят следующим образом:
type CHARARR is table of varchar2(255) index by binary integer;
procedure GET_LINES (lines out chararr, numlines in out integer);
где NUMLINES – число запрошенных строк, на входе (параметр IN) в GET_LINES указывается число запрошенных строк, на выходе (параметр OUT) – число фактически возвращаемых строк.
Тип CHARARR определен в модуле DBMS_OUTPUT, поэтому если GET_LINES вызывается явным образом, нужно объявлять переменную с типом DBMS_OUTPUT.CHARARR. Например:
declare
v_Data DBMS_OUTPUT.CHARARR;
v_NumLines number;
begin
DBMS_OUTPUT.ENABLE (1000000);
DBMS_OUTPUT.PUT_LINE (‘Line one’);
DBMS_OUTPUT.PUT_LINE (‘Line two’);
DBMS_OUTPUT.PUT_LINE (‘Line three’);
v_NumLines:=3;
DBMS_OUTPUT.GET_LINES( v_Data, v_NumLines);
for v_Counter in 1..3 v_NumLines loop
insert into temp_table (char_col)
values (v_Data(v_Counter));
end loop;
end;
Процедура ENABLE задает размер буфера в байтах, по умолчанию задается размер 20000 байт, а максимальный размер – 1000000 байт. Если объявлена процедура DISABLE, то содержимое буфера уничтожается и последующие вызовы PUT и PUT_LINE бесполезны.
По существу, модуль DBMS_OUTPUT реализует алгоритм “первым пришел – первым обслужен”. В утилите SQL*Plus имеется средство, называемое SERVEROUTPUT (серверный вывод), команда SQL*Plus, называемая SET SERVEROUTPUT ON, неявно вызывает процедуру DBMS_OUTPUT.ENABLE, которая устанавливает внутренний буфер серверного вывода. Если нужно, можно указать размер буфера с помощью команды:
SET SERVEROUTPUT ON SIZE размер_буфера
где размер_буфера – первоначальный размер буфера (аргумент процедуры DBMS_OUTPUT.ENABLE, вызываемой по умолчанию). Процедура DBMS_OUTPUT.GET_LINES вызывается после окончания блока PL/SQL. Это означает, что результаты будут выводиться на экран после завершения блока, а не вовремя его выполнения.