Большинство программ PL/SQL
работает только с базой данных Oracle
через SQL
. Однако время от времени возникает необходимость в передаче информации из PL/ SQL
во внешнюю среду или чтении информации из внешнего источника (экран, файл и т. д.) в PL/SQL
.
Пакет DBMS_OUTPUT
предоставляет средства вывода информации из программ в буфер. Далее содержимое буфера читается и обрабатывается другой программой PL/SQL
или управляющей средой. Пакет DBMS_OUTPUT
чаще всего используется для простого вывода информации на экран.
Каждому пользовательскому сеансу выделяется буфер DBMS_OUTPUT
заранее определенного размера. В OraclelOg Release 2
действовало ограничение в один миллион байтов. Когда буфер будет заполнен, его необходимо очистить перед дальнейшим использованием; это можно сделать на программном уровне, но чаще для очистки и вывода содержимого буфера используется управляющая среда (например, SQL*Plus
). Это происходит только после завершения внешнего блока PL/SQL
; пакет DBMS_OUTPUT
не может использоваться для передачи сообщений из программы в реальном времени.
Запись информации в буфер выполняется при помощи программ DBMS_OUTPUT.PUT
и DBMS_0UTPUT.PUT_LINE
, а чтение на программном уровне — при помощи программ DBMS
OUTPUT.GET LINE
или DBMS OUTPUT.GET LINES
.
Включение DBMS_OUTPUT
По умолчанию пакет DBMS_OUTPUT
отключен, поэтому вызовы программ PUT_LINE
и PUT
игнорируются, а буфер остается пустым. Обычно включение DBMS_OUTPUT
осуществляется специальной командой в управляющей среде. Например, в программе SQL*Plus
выполняется следующая команда:
SET SERVEROUTPUT ON SIZE UNLIMITED
Кроме включения вывода на консоль, эта команда передает серверу базы данных следующую команду:
BEGIN DBMS_OUTPUT.ENABLE (buffer_size => NULL); END;
(Параметр buffer_size
со значением NULL
означает неограниченный буфер; также может передаваться конкретное значение размера в байтах.) SQL*Plus
поддерживает ряд дополнительных параметров команды SERVEROUTPUT
; за дополнительной информацией обращайтесь к документации своей версии.
Среды разработки (например, Oracle SQL Developer
или Quest Toad
) обычно выводят результаты DBMS_OUTPUT
в специально назначенной части экрана — конечно, для этого вывод должен быть предварительно включен.
Запись в буфер
Запись информации в буфер осуществляется двумя встроенными процедурами: PUT_ LINE
присоединяет маркер новой строки после текста, а PUT
помещает текст в буфер без маркера новой строки. Информация, выведенная PUT
, останется в буфере даже при завершении вызова. В этом случае следует вывести ее с очисткой буфера вызовом
DBMS_OUTPUT.NEW_LINE.
Если Oracle
знает, как неявно преобразовать ваши данные в строку VARCHAR2
, то эти данные можно передать при вызове программ PUT
и PUT_LINE
. Примеры:
BEGIN
DBMS_OUTPUT.put_line ('Steven');
DBMS_OUTPUT.put_line (100);
DBMS_OUTPUT.put_line (SYSDATE);
END;
/
К сожалению, DBMS_OUTPUT
не умеет выполнять такое преобразование для многих распространенных типов PL/SQL
, прежде всего для BOOLEAN
. В таких случаях стоит написать небольшую утилиту, упрощающую вывод логических значений:
/* Файл в Сети: bpl.sp */
PROCEDURE bpl (boolean_in IN BOOLEAN)
IS
BEGIN
DBMS_OUTPUT.PUT_LINE(
CASE boolean_in
WHEN TRUE THEN 'TRUE'
WHEN FALSE THEN 'FALSE'
ELSE 'NULL'
END
);
END bpl;
/
Максимальная длина строки, которая может передаваться за один вызов DBMS_OUTPUT. PUT_LINE
, в последних версиях Oracle составляет 32 767 байт. В Oracle10g
Release 1 и ранее действовало ограничение в 255 байт. В любой версии при передаче строки с длиной более допустимого максимума происходит исключение (VALUE_ERROR
или ORU-10028
). Чтобы избавиться от этой проблемы, используйте инкапсуляцию DBMS_OUTPUT. PUT_LINE
, которая автоматически разрывает длинные строки. В следующих файлах, доступных на сайте книги, представлены вариации на эту тему:
pl.sp
— автономная процедура позволяет указать длину разрыва строки.p.pks/pkb
— пакет p представляет собой масштабную инкапсуляциюDBMS_OUTPUT. PUT_LINE
с множеством разных перегрузок (например, вызовом процедурыp.l
можно вывести документ XML или файл операционной системы), а также с возможностью разрыва длинного текста.
Чтение содержимого буфера
Типичный случай использования DBMS_OUTPUT
весьма тривиален: разработчик вызывает DBMS_0UTPUT.PUT_LINE
и просматривает результаты на экране. Клиентская среда (например, SQI*Plus
) «за кулисами» вызывает соответствующие программы пакета DBMS_OUTPUT
для чтения и вывода содержимого буфера.
Для получения содержимого буфера DBMS_OUTPUT
используются процедуры GET_LINE
и/или GET_LINES
.
Процедура GET_LINE
читает одну строку из буфера по принципу «первым пришел, первым вышел» и в случае успешного завершения возвращает код 0. Пример использования программы для чтения следующей строки из буфера в локальную переменную PL/SQL
:
FUNCTION next_line RETURN VARCHAR2
IS
return_value VARCHAR2(32767);
status INTEGER;
BEGIN
DBMS_OUTPUT.GET_LINE (return_value, status);
IF status = 0
THEN
RETURN return_value;
ELSE
RETURN NULL;
END IF;
END;
Процедура GET_LINES
читает несколько строк из буфера за один вызов. Данные загружаются в коллекцию строк PL/SQL
(максимальная длина от 255 до 32 767 в зависимости от версии Oracle
). Вы указываете количество читаемых строк, а процедура возвращает их. Следующая программа записывает содержимое буфера DBMS_OUTPUT
в журнальную таблицу базы данных:
/* Файл в Сети: move_buffer_to_log.sp */
PROCEDURE move_buffer_to_log
IS
l_buffer DBMS_OUTPUT.chararr;
l_num_lines PLS_INTEGER;
BEGIN
LOOP
l_num_lines := 100;
DBMS_OUTPUT.get_lines (l_buffer, l_num_lines);
EXIT WHEN l_buffer.COUNT = 0;
FORALL indx IN l_buffer.FIRST .. l_buffer.LAST
INSERT INTO logtab (text) VALUES (l_buffer (indx));
END LOOP;
END;