Программирование >>  Oracle 

1 ... 418 419 420 [ 421 ] 422 423 424 ... 469


Пакет DBMS OUTPUT

Пакет DBMS OUTPUT пользователи часто понимают неправильно. Они не понимают, что и как он делает и с какими ограничениями связано его использование. В этом разделе я попытаюсь объяснить все это. Я также предложу альтернативные пакета: с возможностями, аналогичными тем, что предоставляются пакетом DBMS OUTPUT, но без упомянутых ограничений.

Пакет DBMS OUTPUT предназначен для эмуляции прост1х действий в1вода на экран в языке PL/SQL. Он позволяет эмулировать в]дачу на экран строки Hello World из PL/SQL-кода. Вы уже видели сотни примеров использования этого пакета. Вот типичный пример:

ops$tkyte@DEV816> exec dbms output.put line(Hello World); Hello World

PL/SQL procedure successfully completed.

Однако вы не видите команды SQL*Plus (или SVRMGRL), которая необходима, чтобы этот пример сработал. Вывод на экран можно включать и отключать следующим образом:

ops$tkyte@DEV816> set serveroutput off

ops$tkyte@DEV816> exec dbms output.put line(Hello World) ; PL/SQL procedure successfully completed. ops$tkyte@DEV816> set serveroutput on

ops$tkyte@DEV816> exec dbms output.put line(Hello World) ;

Hello World

PL/SQL procedure successfully completed.



Пакет DBMS OUTPUT

1687

На самом деле язык PL/SQL не позволяет выполнять ввод-вывод на экран (вот почему я написал, что пакет предназначен для эмуляции такой возможности). На самом деле ввод-вывод на экран выполняет утилита SQL*Plus - из языка PL/SQL ничего нельзя в]дать на терминал. PL/SQL-код выполняется другим процессом, обычно работающим на другой машине в сети. Утилиты SQL*Plus, SVRMGRL и другие инструментальные средства, однако, могут выдавать результаты на экран весьма просто. Это легко обнаружить при использовании пакета DBMS OUTPUT в Java-коде или в программе на Pro*C (или в любой другой программе) - выданные пакетом DBMS OUTPUT результаты никогда не выдаются на экран. Дело в том, что приложение само отвечает за выдачу этих результатов.

Как работает пакет DBMS OUTPUT

В пакете DBMSOUTPUT подпрограмм немного. Чаще всего используются следующие.

PUT. Выдает строку, данные типа NUMBER или DATE в буфер вывода, не добавляя символ новой строки.

PUT LINE. Выдает строку, данные типа NUMBER или DATE в буфер вывода и добавляет символ новой строки.

NEW LINE. Выдает в буфер вывода символ новой строки.

ENABLE/DISABLE. Включает и отключает выдачу в буфер, используя

DBMS OUTPUT.

Эти процедуры в]дают данные во внутренний буфер; PL/SQL-таблицу в теле пакета DBMS OUTPUT. Общая длина выдаваемой строки (сумма всех байтов, помещенных в буфер пользователем до вызова процедуры PUT LINE или NEW LINE, завершающей эту строку) должна быть не более 255 байт. Выданные результаты буферизуются в этой таблице и не будут видны в среде SQL*Plus, пока не завершится выполнение соответствующего PL/SQL-кода. Язык PL/SQL не позволяет ничего в]давать на терминал, данные просто помещаются в PL/SQL-таблицу.

При вызове процедуры DBMS OUTPUT.PUT LINE пакет DBMS OUTPUT сохраняет соответствующие данные в массиве (PL/SQL-таблице) и возвращает управление. Пока работа вызывающей процедуры не завершится, результаты на экран не выдаются. Даже после этого результаты можно увидеть, только если используемый клиент знает о пакете DBMS OUTPUT и сам позаботится о выдаче накопленных результатов. Утилита SQL*Plus, например, вызывает DBMS OUTPUT.GET LINES для получения части содержимого буфера пакета DBMS OUTPUT и выдачи его на экран. Если вызвать хранимую процедуру из приложения на языке Java/JDBC, предположение о том, что результаты DBMS OUTPUT окажутся там же, где и данные, выданные с помощью функции System.out.println, не оправдается. Если клиентское приложение не позаботится о выборке и выдаче данных, они просто исчезнут. Как сделать это в программе на языке Java/JDBC будет продемонстрировано в этом разделе.

При использовании пакета DBMS OUTPUT больше всего сбивает с толку то, что результат буферизуется и не выдается до завершения процедуры. Пользователи зна-



1688

Приложение А

ют о пакете DBMS OUTPUT и пытаются использовать его для контроля продолжительного процесса. Другими словами, они повсеместно вставляют в код вызовы

DBMS OUTPUT.PUT LINE и запускают процедуру в среде SQL*Plus. Они ждут, что

результаты начнут выдаваться на экран, и очень расстраиваются, когда этого не происходит (потому что и не может произойти). Не зная особенностей реализации, трудно понять, почему результаты не выдаются сразу. Если понять, что процедуры на яз1ке PL/SQL (а также внешние процедуры на языках Java и С), работающие на сервере, не выполняют ввод-вывод на экран и что пакет DBMS OUTPUT просто накапливает данные в большом массиве, ситуация проясняется. Вот когда имеет смысл вернуться к разделу, посвященному пакету DBMS APPLICATION INFO, и почитать о способе контроля работы продолжительных действий. Для контроля продолжительно работающих процессов надо использовать пакет DBMS APPLICATION INFO, а не

DBMS OUTPUT.

Для чего же тогда пакет DBMS OUTPUT? Он прекрасно подходит для в]дачи простых отчетов и создания утилит. В главе 23 б]ла представлена процедура PRINT TABLE, использующая средства пакета DBMS OUTPUT для генерации результатов следующего вида:

SQL> exec print table(select * from all users where username = user ) ; USERNAME : OPS$TKYTE

USER ID : 3 34

CREATED : 02-oct-2000 10:02:12

PL/SQL procedure successfully completed.

Она выдает данные по одному столбцу в строке, а не одной, разбитой на части, строкой. Прекрасно подходит для выдачи длинных строк таблиц, которые переносятся по границе экрана, что затрудняет чтение.

Теперь, зная, что пакет DBMS OUTPUT работает путем помещения данных в PL/ SQL-таблицу, можно изучать его реализацию. При включении DBMS OUTPUT (в]зо-

вом DBMS OUTPUT.ENABLE либо с помощью команды SET SERVEROUTPUT ON)

мы не только позволяем накапливать данные, но и задаем максимальный объем данных, которые сможем накопить. По умолчанию, если выполнить:

SQL> set serveroutput on

создается буфер DBMS OUTPUT размером 20000 байт. При достижении этого предела будет выдано:

begin *

ERROR at line 1:

ORA-20000: ORU-10027: buffer overflow, limit of 20000 bytes ORA-06512: at SYS.DBMS OUTPUT , line 106 ORA-06512: at SYS.DBMS OUTPUT , line 65 ORA-06512: at line 3

Этот предел можно увеличить, выполнив команду SET SERVEROUTPUT (или вызвав процедуру DBMS OUTPUT.ENABLE):



1 ... 418 419 420 [ 421 ] 422 423 424 ... 469

© 2006 - 2025 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика