В тази статия ще разгледаме DBMS_OUTPUT
пакет малко подробно. DBMS_OUTPUT
пакетът в Oracle, подобно на други пакети за СУБД, е собственост на потребителя на Oracle SYS
.
Скриптът, който създава DBMS_OUTPUT
предоставя разрешението EXECUTE върху пакета на PUBLIC и създава публичен синоним за него. Това означава, че всеки потребител на Oracle може да извика подпрограмите в DBMS_OUTPUT
без да се налага да поставяте префикс в името на пакета с SYS
.
Как работи DBMS_OUTPUT в Oracle?
Две основни операции, GET
и PUT
, се реализират чрез процедури в пакета. A PUT
Операцията взема аргумента си и го поставя във вътрешен буфер за съхранение.
A GET
операцията чете от този буфер и връща съдържанието като аргумент на процедурата. Има и ENABLE
процедура, която задава размера на буфера.
Процедури в пакета DBMS_OUTPUT
PUT
подпрограмите в пакета са PUT
, PUT_LINE
и NEW_LINE
. GET
рутините са GET_LINE
и GET_LINES
. ВКЛЮЧВАНЕ и ИЗКЛЮЧВАНЕ на контрола на буфера.
PUT и PUT_LINE Синтаксисът за извикванията PUT и PUT_LINE е:
PROCEDURE PUT(a VARCHAR2); PROCEDURE PUT(a NUMBER); PROCEDURE PUT(a DATE); PROCEDURE PUT(a VARCHAR2); PROCEDURE PUT(a NUMBER); PROCEDURE PUT(a DATE);
Където a е аргументът, който трябва да бъде поставен в буфера. Имайте предвид, че типът на параметъра претоварва тези процедури. Поради трите различни версии на PUT
и PUT_LINE
, буферът може да съдържа стойности от типове VARCHAR2
, NUMBER
и DATE
се съхраняват в буфера в оригиналния им формат. Въпреки това, GET_LINE
и GET_LINES
извличане от буфера и връщане само на символни низове.
Когато GET
се извършва, съдържанието на буфера ще бъде преобразувано в символен низ според правилата за преобразуване на тип данни по подразбиране. Ако искате да посочите формат за преобразуването, използвайте изричен TO_CHAR
обадете се на PUT
, а не GET
.
Буферът е организиран в редове, всеки от които може да има максимум 255 байта. PUT_LINE
добавя символ за нов ред след неговия аргумент, като сигнализира за края на реда. PUT
не. PUT_LINE
е еквивалентно на извикване на PUT
и след това извикване на NEW_LINE
.
NEW_LINE Синтаксисът на извикването NEW_LINE е:
PROCEDURE NEW_LINE;
NEW_LINE
поставя символ за нов ред в буфера, сигнализирайки за края на реда. Няма ограничение за броя на редовете в буфера. Общият размер на буфера обаче е ограничен до стойността, посочена в ENABLE.
GET_LINE Синтаксисът за GET_LINE е:
PROCEDURE GET_LINE(line OUT VARCHAR2, status OUT INTEGER);
Където редът е символен низ, който ще съдържа един ред от буфера, а състоянието показва дали редът е извлечен успешно. Максималната дължина на ред е 255 байта. Ако линията е извлечена, състоянието ще бъде 0; ако няма повече редове в буфера, той ще бъде 1.
ЗАБЕЛЕЖКА
Въпреки че максималният размер на буферния ред е 255 байта, изходният ред с променлива може да бъде повече от 255 знака. Буферният ред може да се състои от
DATE
стойности, например.Те заемат 7 байта място за съхранение в буфера, но обикновено се преобразуват в символни низове с дължина по-голяма от 7.
GET_LINES
Процедурата GET_LINES има аргумент, който е PL/SQL таблица. Типът на таблицата и синтаксисът са
TYPE CHARARR IS TABLE OF VERCHAR2(255) INDEX BY BINARY_INTEGER; PROCEDURE GET_LINES(lines OUT CHARARR, numlines IN OUT INTEGER);
Където редовете са PL/SQL таблица, ще съдържа няколко реда от буфера и numlines
показва колко реда са поискани. При въвеждане в GET_LINES, numlines
определя искания брой редове. При изход, numlines ще съдържа действителния брой върнати редове, който ще бъде по-малък или равен на искания брой. GET_LINES е предназначен да замени множество повиквания към GET_LINES.
CHARARR
типът също е дефиниран в DBMS_OUTPUT
пакет. Следователно, ако искате да се обадите на GET_LINES
изрично във вашия код, трябва да декларирате променлива от тип DBMS_OUTPUT
. CHARARR
. Например:
Create Table temp_table (char_col varchar2(4000)) / DECLARE /* Demonstrates using PUT_LINE and GET_LINE. */ v_Data DBMS_OUTPUT.CHARARR; v_NumLines NUMBER; BEGIN -- Enable the buffer first. DBMS_OUTPUT.ENABLE(1000000); -- Put some data in the buffer first, so GET_LINES will -- retrieve something. DBMS_OUTPUT.PUT_LINE( 'Line' ); DBMS_OUTPUT.PUT_LINE( 'Line Two' ); DBMS_OUTPUT.PUT_LINE( 'Line Three' ); --Set the maximum number of lines that we want to retrieve. v_NumLines := 3 ; /* Get the contents of the buffer back. Note that v_DATA is declared of type DBMS_OUTPUT. CHARARR, so that it matches the declaration of DBMS_OUTPUT. GET_LINES. */ DBMS_OUTPUT.GET_LINES(v_DATA, v_NumLines); /* Loop through the returned buffer, and insert the contents into tem_table. */ For v_Counter IN 1.. v_NumLines Loop INSERT INTO temp_table ( char_col ) VALUES ( v_Data ( v_Counter )); END LOOP; END; /
АКТИВИРАНЕ и ИЗКЛЮЧВАНЕ
Синтаксисът за повикванията ENABLE и DISABLE е:
PROCEDURE ENABLE (buffer_size IN INTEGER DEFAULT 20000); PROCEDURE DISABLE;
Където buffer_size е първоначалният размер на вътрешния буфер, в байтове. Размерът по подразбиране е 20 000 байта, а максималният размер е 1 000 000 байта.
По-късно аргументи за PUT
или PUT_LINE
ще бъде поставен в този буфер. Те се съхраняват във вътрешния си формат, като заемат толкова място в буфера, колкото структурата им диктува.
Ако DISABLE
се извиква, съдържанието на буфера е диктувано от тяхната структура. Ако DISABLE
се извиква, съдържанието на буфера се изчиства и последващи извиквания към PUT
и PUT_LINE
не влияят.
Използване на DBMS_OUTPUT
DBMS_OUTPUT
Самият пакет не съдържа никакъв механизъм за печат. По същество той внедрява просто структура от данни „първи дошъл, първи излязъл“.
След като казахме това, как можем да използваме DBMS_OUTPUT
за печат? SQL*Plus, SQL*DBA и Manager ще имат опция, известна като SERVEROUTPUT on
. В допълнение, някои продукти на трети страни (включена SQL-станция) имат опция, която позволява показването на DBMS_OUTPUT
данни.
С тази опция SQL*Plus автоматично ще извика DBMS_OUTPUT.GET_LINES
когато PL/SQL блок приключи и отпечата резултатите, ако има такива, на екрана.
Командата SQL*Plus SET SERVEROUTPUT ON
имплицитно извиква, което настройва вътрешния буфер. По избор можете да посочите размер с SET SERVEROUTPUT ON SIZE
buffer_size където beffer_size ще се използва като първоначален размер на буфера (аргументът на DBMS_OUTPUT.ENABLE
).
С включен SERVEROUTPUT on
, SQL*Plus ще извика DBMS_OUTPUT.GET_LINES
след PL/SQL блокът е завършен. Това означава, че изходът ще бъде отразен на екрана, когато блокът приключи и не по време на изпълнение на блока. Това обикновено не е проблем, когато DBMS_OUTPUT
се използва за отстраняване на грешки.
ВНИМАНИЕ
DBMS_OUTPUT
е проектиран да се използва предимно за отстраняване на грешки. Не е предназначен за общо отчитане. Ако трябва да персонализирате изхода от вашите заявки, по-добре е да използвате инструменти като Oracle Reports, отколкотоDBMS_OUTPUT
и SQL*Plus.
SET serveroutput on SIZE 1000000 BEGIN DBMS_OUTPUT.PUT_LINE('Before loop'); FOR v_Counter IN 1..10 LOOP DBMS_OUTPUT.PUT_LINE('Inside loop, couter = ' || v_Counter); END LOOP; DBMS_OUPUT.PUT_LINE( 'After loop'); END; /
Вътрешният буфер има максимален размер (определен в DBMS_OUTPUT.ENABLE
) и всеки ред има максимална дължина от 255 байта. В резултат на това извиквания към DBMS_OUTPUT.PUT
, DBMS_OUTPUT.PUT_LINE
и DBMS_OUTPUT.NEW_LINE
може да повиши едно от двете
ORA-20000: ORU-10027: buffer overflow, limit of <buf_limit> bytes.
Или
ORA-20000: ORU-10028 line lenth overflow, limit of 255 bytes per line.
Съобщението зависи от това кое ограничение е надвишено.
Вижте също:
- Как да активирам DBMS_OUTPUT в Toad за Oracle?
- Регистрирайте изхода на DBMS_OUTPUT.Put_Line в таблица в Oracle с DBMS_OUTPUT.Get_Lines