In this article, we will examine the DBMS_OUTPUT
package in some detail. DBMS_OUTPUT
package in Oracle, like other DBMS packages, is owned by the Oracle user SYS
.
The script which creates DBMS_OUTPUT
grants the EXECUTE permission on the package to the PUBLIC, and creates a public synonym for it. This means that any Oracle user can call the routines in DBMS_OUTPUT
without having to prefix the package name with SYS
.
How does DBMS_OUTPUT work in Oracle?
Two basic operations, GET
and PUT
, are implemented through procedures in the package. A PUT
operation takes its argument and places it into an internal buffer for storage.
A GET
operation reads from this buffer and returns the contents as an argument to the procedure. There is also an ENABLE
procedure that sets the size of the buffer.
Procedures in DBMS_OUTPUT Package
The PUT
routines in the package are PUT
, PUT_LINE
, and NEW_LINE
. The GET
routines are GET_LINE
and GET_LINES
. ENABLE and DISABLE control of the buffer.
PUT and PUT_LINE The syntax for the PUT and PUT_LINE calls are:
PROCEDURE PUT(a VARCHAR2); PROCEDURE PUT(a NUMBER); PROCEDURE PUT(a DATE); PROCEDURE PUT(a VARCHAR2); PROCEDURE PUT(a NUMBER); PROCEDURE PUT(a DATE);
Where a is the argument to be placed in the buffer. Note that the type of the parameter overloads these procedures. Because of the three different versions of PUT
and PUT_LINE
, the buffer can contain values of types VARCHAR2
, NUMBER
, and DATE
are stored in the buffer in their original format. However, GET_LINE
and GET_LINES
retrieve from the buffer and return Character strings only.
When a GET
operation is performed, the contents of the buffer will be converted to a Character string according to the default datatype conversion rules. If you want to specify a format for the conversion, use an explicit TO_CHAR
call on the PUT
, rather than the GET
.
The buffer is organized into lines, each of which can have a maximum of 255 bytes. PUT_LINE
appends a newline Character after its argument, signaling the end of a line. PUT
does not. PUT_LINE
is equivalent to calling PUT
and then calling NEW_LINE
.
NEW_LINE The syntax for the NEW_LINE call is:
PROCEDURE NEW_LINE;
NEW_LINE
puts a newline Character into the buffer, signaling the end of a line. There is no limit to the number of lines in the buffer. The total size of the buffer is limited to the value specified in ENABLE, however.
GET_LINE The syntax for GET_LINE is:
PROCEDURE GET_LINE(line OUT VARCHAR2, status OUT INTEGER);
Where the line is a Character string that will contain one line of the buffer, and status indicates whether the line was retrieved successfully. The maximum length of a line is 255 bytes. If the line was retrieved, the status would be 0; if there are no more lines in the buffer, it will be 1.
NOTE
Although the maximum size of a buffer line is 255 bytes, the output variable line can be more than 255 Characters. The buffer line can consist of
DATE
values, for example.These take up 7 bytes of storage in the buffer but are usually converted to Character strings with Lengths greater than 7.
GET_LINES
The GET_LINES procedure has an argument that is a PL/SQL table. The table type and the syntax are
TYPE CHARARR IS TABLE OF VERCHAR2(255) INDEX BY BINARY_INTEGER; PROCEDURE GET_LINES(lines OUT CHARARR, numlines IN OUT INTEGER);
Where lines is a PL/SQL table will contain multiple lines from the buffer, and numlines
indicates how many lines are requested. On input to GET_LINES, numlines
specifies the requested number of lines. On Output, numlines will contain the actual number of lines returned, Which will be less than or equal to the number requested. GET_LINES is designed to replace multiple calls to GET_LINES.
The CHARARR
type is also defined in the DBMS_OUTPUT
package. Therefore, if you want to call GET_LINES
explicitly in your code, you need to declare a variable of type DBMS_OUTPUT
. CHARARR
. For example:
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 and DISABLE
The syntax for the ENABLE and DISABLE calls is:
PROCEDURE ENABLE (buffer_size IN INTEGER DEFAULT 20000); PROCEDURE DISABLE;
Where buffer_size is the initial size of the internal buffer, in bytes. The default size is 20,000 bytes, and the maximum size is 1,000,000 bytes.
Later, arguments to PUT
or PUT_LINE
will be placed in this buffer. They are stored in their internal format, taking up as much space in the buffer as their structure dictates.
If DISABLE
is called, the contents of the buffer are their structure dictates. If DISABLE
is called, the contents of the buffer are purged, and subsequent calls to PUT
and PUT_LINE
do not affect.
Using DBMS_OUTPUT
The DBMS_OUTPUT
package itself does not contain any mechanism for printing. Essentially, it implements merely a first in, first out data structure.
Having said that, how can we use DBMS_OUTPUT
for printing? SQL*Plus, SQL*DBA, and Manager ll have an option known as SERVEROUTPUT
. In addition, some third-party products (SQL-Station included) have an option that allows the display of DBMS_OUTPUT
data.
With this option, SQL*Plus will automatically call DBMS_OUTPUT.GET_LINES
when a PL/SQL block concludes and prints the results, if any, to the screen.
The SQL*Plus command SET SERVEROUTPUT ON
implicitly calls, which sets up the internal buffer. Optionally, you can specify size with SET SERVEROUTPUT ON SIZE
buffer_size where beffer_size will be used as the initial size of the buffer (the argument to DBMS_OUTPUT.ENABLE
).
With SERVEROUTPUT on
, SQL*Plus will call DBMS_OUTPUT.GET_LINES
after the PL/SQL block has completed. This means that the output will be echoed to the screen when the block has finished and not during execution of the block. This usually is not a problem when DBMS_OUTPUT
is used for debugging.
CAUTION
DBMS_OUTPUT
is designed to be used primarily for debbuging. It is not meant for general reporting. If you need to customize the output from your queries, it is better to use tools such as Oracle Reports thanDBMS_OUTPUT
and 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; /
The internal buffer does have a maximum size (specified in DBMS_OUTPUT.ENABLE
), and each line has a maximum length of 255 bytes. As a result, calls to DBMS_OUTPUT.PUT
, DBMS_OUTPUT.PUT_LINE
, and DBMS_OUTPUT.NEW_LINE
can raise either
ORA-20000: ORU-10027: buffer overflow, limit of <buf_limit> bytes.
Or
ORA-20000: ORU-10028 line lenth overflow, limit of 255 bytes per line.
The message depends on which limit is exceeded.