Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Sameer.

Asked: November 14, 2001 - 9:15 am UTC

Last updated: August 29, 2012 - 1:20 pm UTC

Version: 8.1.7

Viewed 100K+ times! This question is

You Asked

Hi Tom,

I have dbms_output.enable(1000000) in my procedure but to see all the messages thrown by dbms_output.put_line I still have to issue the command "set serveroutput on" at the sql plus.

Isnt it true that dbms_output.enable is the alternative to this command ?

Thanks !


and Tom said...

It is not true.

set serveroutput on

does 2 things:

1) is tells SQLPLUS to dump the output after each statement
2) it makes sqlplus issue the dbms_output.enable


You must use set serveroutput on if you want sqlplus to automagically dump the output. Else, if you just use dbms_output.enable, you would have to call dbms_output.getlines yourself to get the result.

Rating

  (35 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Sameer, November 14, 2001 - 1:11 pm UTC

So isnt there a way to display the messages from a procedure in SQL Plus, without issuing any commands at the sql prompt ?

Tom Kyte
November 14, 2001 - 1:27 pm UTC

correct, you must tell sqlplus to dump the output.

news to me...

Andrew, November 14, 2001 - 1:13 pm UTC


Tom Kyte
November 14, 2001 - 1:29 pm UTC

try it.  login to sqlplus (without having set serveroutput on) and try to get dbms_output to work.  It won't. (make sure you don't have set serveroutput on in your login.sql file)

ops$tkyte@ORA817DEV.US.ORACLE.COM> exec dbms_output.enable(10000);

PL/SQL procedure successfully completed.

ops$tkyte@ORA817DEV.US.ORACLE.COM> exec dbms_output.put_line( 'x' );

PL/SQL procedure successfully completed.

ops$tkyte@ORA817DEV.US.ORACLE.COM> set serveroutput on
ops$tkyte@ORA817DEV.US.ORACLE.COM> exec dbms_output.put_line( 'x' );
x
x

PL/SQL procedure successfully completed.

See the second one did 2 x's -- the first and second, since plus didn't DUMP the output the first time. 

A reader, November 14, 2001 - 2:59 pm UTC

So if I must tell sqlplus to dump the output, what is the command dbms_output.enable for ? By using "set serveroutput on" it still displays the messages, then why & where use dbms_output.enable ?

Tom Kyte
November 14, 2001 - 5:09 pm UTC

(you know, i always wonder how people rate questions, how they come up with 1..5 stars. here, we have accurate - detailed information that tells you exactly how to use something, yet because they don't LIKE the answer, its only worth 1. I guess people rate by what they WANTED to hear, not what is said. Oh well)....

DBMS_OUTPUT is a package to allow you to buffer "lines of text" that a client might retrieve and do something with.

In this package there are a couple of procedures/functions. One of which is ENABLE.

A client (any client) can call enable. If you call enable all this does is lets the package BUFFER output. If enable is not called or you call disable -- buffering of this output is disabled, does not happen.

Now, any client -- your C program, your java application, your WHATEVER, can call dbms_output.enable to get this buffering to take place. they can later call dbms_output.get_line/get_lines to get this buffered data and do SOMETHING (whatever they want) with it.

Now, sqlplus sees this functionality and says "hey, would not it be nice for me to dump this buffer to screen for the user?". So, they added the SQLPlus command "set serveroutput on" which does two things

1) it tells SQLPLUS you would like it to execute dbms_output.get_lines after each and every statement. You would like it to do this network rounding after each call. You would like this extra overhead to take place (think of an install script with hundreds/thousands of statements to be executed -- perhaps, just perhaps you don't want this extra call after every call)

2) SQLPLUS automatically calls the dbms_output API "enable" to turn on the buffering that happens in the package.


Since SQLPlus has NO WAY to know if you called dbms_output.enable (it could be buried in a stored procedure call, in a trigger, where ever) -- it would have to call dbms_output.get_lines after each ever call -- adding unnecessary overhead.

I guess the implementors of sqlplus looked at this problem and said "set serveroutput on" isn't any harder then exec dbms_output.enable -- in fact it would be easier so we'll do it that way. In this fashion, sqlplus won't make this extra call after each call -- unless the user asks us to.

Given that you can have a login.sql with

set serveroutput on size 1000000

to have this setup for you transparently, its just not really a big deal at all.

How about Huge data which buffer can not hold all That data

Mohammed Al-moayed, November 15, 2001 - 5:06 am UTC

Hi, tom I have tried this package before but, I really get
Probelm with spooling more than max buffer can hold .
Is thire any solution for this probelm .
Beacouse I am running SQLs every day with about 20,000 Records to be retrive for some SQLs ,
I was Planning to sechuling all sql by using Pl/sql and using dbms_output.Put_line but i get buffer Error.

are thire any soultion for this

Tom Kyte
November 15, 2001 - 6:45 am UTC

did you:

set serveroutput on size 1000000

??

(if yes, I can show you methods to get around this limit as well, all is not lost, search for my_dbms_output on this site for some ideas)

The star rating system

Connor McDonald, November 15, 2001 - 7:41 am UTC

It absolutely definitively irrefutably continues to amaze me that you're providing a resource that is:
- timely!
- free!
- packed with examples!
- well researched!
- full of quality
- done by a single guy
and people have the nerve to rate ANY response less than 4 or 5 stars. If they don't like the response, then they should be doing one or more of:
- RTFM
- pay up for metalink support contract
- shutup and stop complaining...

Just my 2c worth.

RE: Star Rating

Mark A. Williams, November 15, 2001 - 8:19 am UTC

Preach on Brother Connor!

I notice that most of the "1 star'ers" also happen to be named "A reader". Funny that.

Anyway, the next time I see someone posting a question like "I keep getting the error that says cannot extend segment abc by 123 in tablespace xyz... what do I do?" I'm going to ask for a raise - obviously I'm at the 'senior' level, right? :)

What is so hard (apparently) about looking something up in the documentation after all???? Or, even harder, trying it out first? Oh, well, don't mean to use 'AskTom' as a personal soap box...

BTW, when did deepest darkest Scotland start using 2c??? :)

- Mark

A wonderful (and free!) resource

Paul Rees, November 15, 2001 - 8:25 am UTC

Here, Here (to Connor's previous remarks)

And long may it continue...

Sameer, November 15, 2001 - 10:35 am UTC

Thanks Tom ! that explaination was excellent ! i guess, no one will get confused with "set serveroutput on" and "dbms_output.enable" ever again ! I checked the metalink also and found few folks confused with the above 2 commands (like me) !!!

Rating - maybe a bit confusing names for rating

Dushan, November 15, 2001 - 10:42 am UTC

1-Not usefull
2-Of some use
3-Useful
4-Very useful
5-most useful

Well, maybe somebody asked something, the Tom's answer was excellent, but for the issuer it meant 'Hey, wrong way!'
What the rating should be? 5 or 1?
1 - means 'Not useful, it did not solve my problem' but on the other hand 5 - 'Most useful, thanks for answer, I am not going waste my time in wrong way'



What did you try here, Mr Dushan from MA?

A reader, November 15, 2001 - 9:47 pm UTC


Reader

Reader, November 15, 2001 - 10:24 pm UTC

Excellent information and explanation
of concept behind the design of Oracle code is great !

dbms_output implementation question

Igor, November 16, 2001 - 4:58 am UTC

Could you explain why there is not possibility to get results as they come and not at the end
of procedure execution?
(for someone who is ready to pay extra performance cost)
What were problem during design of this package in Oracle architecture?

Igor

Tom Kyte
November 16, 2001 - 8:17 am UTC

It is because prior to 9i -- a stored procedure call would goto the database, run the procedure from start to finish and then return to the client.  The client has no ability to get results from the stored procedure until its totally done. It is one message over, one message back.  The stored procedure runs in the server, not on the client so the stored procedure cannot really do any I/O on the client screen (and think of all of the interfaces - gui's, command line, etc -- there would be no way for the stored proc to do I/O to the screen)

Now, in 9i, we can actually get interactive results from a stored procedure using pipe lining (a cool feature that wasn't really designed to do exactly what I'm about to do -- rather this is a nice side effect).  Consider this small example:

ops$tkyte@ORA9I.WORLD> create or replace type messageTabType
  2  as table of varchar2(4000)
  3  /

Type created.

ops$tkyte@ORA9I.WORLD> 
ops$tkyte@ORA9I.WORLD> create or replace function my_stored_proc( p_inputs in varchar2 )
  2  return messageTabType
  3  PIPELINED
  4  as
  5  begin
  6      for i in 1 .. 10
  7      loop
  8          pipe row( 'processing iteration      ' ||
  9                      i || ' ' || systimestamp );
 10          dbms_lock.sleep(1);
 11          pipe row( 'done processing iteration ' ||
 12                      i || ' ' || systimestamp );
 13      end loop;
 14      pipe row( 'All done, success' );
 15  
 16      return;
 17  end;
 18  /

Function created.

ops$tkyte@ORA9I.WORLD> 
ops$tkyte@ORA9I.WORLD> set arraysize 1
ops$tkyte@ORA9I.WORLD> select * from table( my_stored_proc( 'foobar' ) );

COLUMN_VALUE
--------------------------------------------------------------------------------
processing iteration      1 16-NOV-01 08.14.38.335479000 AM -05:00
done processing iteration 1 16-NOV-01 08.14.39.360806000 AM -05:00
processing iteration      2 16-NOV-01 08.14.39.361372000 AM -05:00
done processing iteration 2 16-NOV-01 08.14.40.390780000 AM -05:00
processing iteration      3 16-NOV-01 08.14.40.391328000 AM -05:00
done processing iteration 3 16-NOV-01 08.14.41.420795000 AM -05:00
processing iteration      4 16-NOV-01 08.14.41.421341000 AM -05:00
done processing iteration 4 16-NOV-01 08.14.42.450819000 AM -05:00
processing iteration      5 16-NOV-01 08.14.42.451383000 AM -05:00
done processing iteration 5 16-NOV-01 08.14.43.480794000 AM -05:00
processing iteration      6 16-NOV-01 08.14.43.481343000 AM -05:00
done processing iteration 6 16-NOV-01 08.14.44.511147000 AM -05:00
processing iteration      7 16-NOV-01 08.14.44.511987000 AM -05:00
done processing iteration 7 16-NOV-01 08.14.45.540863000 AM -05:00
processing iteration      8 16-NOV-01 08.14.45.541468000 AM -05:00
done processing iteration 8 16-NOV-01 08.14.46.571104000 AM -05:00
processing iteration      9 16-NOV-01 08.14.46.571923000 AM -05:00
done processing iteration 9 16-NOV-01 08.14.47.600860000 AM -05:00
processing iteration      10 16-NOV-01 08.14.47.601463000 AM -05:00
done processing iteration 10 16-NOV-01 08.14.48.630873000 AM -05:00
All done, success

21 rows selected.

It is not obvious here but -- each pair of outputs from the procedure appeared in sqlplus -- in real time -- every second (setting the arraysize was important here, else plus would have waited for 15 rows to be generated).  

So, in 9i, if you want "real time" output from the procedure, you would simply use PIPE ROW instead of dbms_output and you would "select * from your_procedure" instead of execute your_procedure.

If your procedure modifies the database, you would have to code it as an autonomous transaction:

ops$tkyte@ORA9I.WORLD> create or replace function my_stored_proc( p_inputs in varchar2 )
  2  return messageTabType
  3  PIPELINED
  4  as<b>
  5          pragma autonomous_transaction;</b>
  6  begin
  7      for i in 1 .. 10
  8      loop
  9          pipe row( 'processing iteration      ' ||
 10                      i || ' ' || systimestamp );
 11          dbms_lock.sleep(1);<b>
 12          insert into t values ( i );</b>
 13          pipe row( 'done processing iteration ' ||
 14                      i || ' ' || systimestamp );
 15      end loop;
 16      pipe row( 'All done, success' );<b>
 17      commit;</b>
 18      return;
 19  end;
 20  /

Function created.

to avoid:

ORA-14551: cannot perform a DML operation inside a query
ORA-06512: at "OPS$TKYTE.MY_STORED_PROC", line 11
ORA-06512: at line 1

but otherwise it will work just fine. 

How about Huge data which buffer can not hold all That data

Mohammed Al-moayed, November 17, 2001 - 1:39 am UTC

Hi, tom I have tried this package before but, I really get
Probelm with spooling more than max buffer can hold .
Is thire any solution for this probelm .
Beacouse I am running SQLs every day with about 20,000 Records to be retrive for some SQLs ,
I was Planning to sechuling all sql by using Pl/sql and using dbms_output.Put_line but i get buffer Error.

are thire any soultion for this

Tom Kyte
November 17, 2001 - 10:07 am UTC

As I said in the other followup:

I can show you methods to get around this limit as well, all is not
lost, search for my_dbms_output on this site for some ideas

(or if you have my book, look at the dbms_output section. There i explain in gory detail how dbms_output works, how it packs data, why the 1,000,000 limit is there and how to get around it when you need)

The limit on dbms_output is hard and fast. We will have to use something else. MY_DBMS_OUTPUT is a method of doing this, search for it and the code is all there.



set serveroutput off

Andrew, November 21, 2001 - 3:05 pm UTC

I gather that "set serveroutput off" issues a dbms_output.disable too.
SQL> -- buffer enabled (and too small)
SQL> set serveroutput on size 2000
SQL> begin
  2  for i in 1..100 loop
  3  dbms_output.put_line(lpad('>', 80, '~'));
  4  end loop;
  5  end;
  6  /
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
.
.
.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
begin
*
ERROR at line 1:
ORA-20000: ORU-10027: buffer overflow, limit of 2000 bytes 
ORA-06512: at "SYS.DBMS_OUTPUT", line 91 
ORA-06512: at "SYS.DBMS_OUTPUT", line 58 
ORA-06512: at line 3 



SQL> --wont bomb out because an implicit dbms_output.disable occurs
SQL> set serveroutput off
SQL> /

PL/SQL procedure successfully completed.



SQL> -- app re-enables buffer but serveroutout still off
SQL> set serveroutput off
SQL> begin
  2  dbms_output.enable(2000);
  3  for i in 1..100 loop
  4  dbms_output.put_line(lpad('>', 80, '~'));
  5  end loop;
  6  end;
  7  /
begin
*
ERROR at line 1:
ORA-20000: ORU-10027: buffer overflow, limit of 2000 bytes 
ORA-06512: at "SYS.DBMS_OUTPUT", line 91 
ORA-06512: at "SYS.DBMS_OUTPUT", line 58 
ORA-06512: at line 4 

Tom Kyte
November 21, 2001 - 3:43 pm UTC

yes, we can see this 100% with SQL_TRACE:

C:\Documents and Settings\Thomas Kyte\Desktop>sqlplus tkyte/tkyte
SQL*Plus: Release 8.1.6.0.0 - Production on Wed Nov 21 15:45:48 2001
(c) Copyright 1999 Oracle Corporation. All rights reserved.

Connected to:
Oracle8i Enterprise Edition Release 8.1.6.0.0 - Production
With the Partitioning option
JServer Release 8.1.6.0.0 - Production

tkyte@TKYTE816> alter session set sql_trace=true;
Session altered.

tkyte@TKYTE816> set serveroutput on
tkyte@TKYTE816> set serveroutput off
tkyte@TKYTE816> alter session set sql_trace=false;
Session altered.

tkyte@TKYTE816> @gettrace

C.VALUE||'\ORA'||TO_CHAR(A.SPID,'FM00000')||'.TRC'
----------------------------------------------------------------------------------------------------

C:\oracle\admin\tkyte816\udump\ORA01252.trc

tkyte@TKYTE816> host type C:\oracle\admin\tkyte816\udump\ORA01252.trc

Dump file C:\oracle\admin\tkyte816\udump\ORA01252.TRC
Wed Nov 21 15:45:56 2001
ORACLE V8.1.6.0.0 - Production vsnsta=0
vsnsql=e vsnxtr=3
Windows 2000 Version 5.0 , CPU type 586
Oracle8i Enterprise Edition Release 8.1.6.0.0 - Production
With the Partitioning option
JServer Release 8.1.6.0.0 - Production
Windows 2000 Version 5.0 , CPU type 586
Instance name: tkyte816

Redo thread mounted by this instance: 1

Oracle process number: 12

Windows thread id: 1252, image: ORACLE.EXE


*** SESSION ID:(8.99) 2001-11-21 15:45:56.241
APPNAME mod='SQL*Plus' mh=3669949024 act='' ah=4029777240
=====================
PARSING IN CURSOR #1 len=33 dep=0 uid=427 oct=42 lid=427 tim=10030494 hv=3732290820 ad='2f6f128'
alter session set sql_trace=true
END OF STMT
EXEC #1:c=5,e=5,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=4,tim=10030495
=====================
PARSING IN CURSOR #1 len=39 dep=0 uid=427 oct=47 lid=427 tim=10030728 hv=1585371720 ad='3fff3d4'
BEGIN DBMS_OUTPUT.ENABLE(1000000); END;

END OF STMT
PARSE #1:c=1,e=1,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=4,tim=10030728
EXEC #1:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=1,dep=0,og=4,tim=10030729
=====================
PARSING IN CURSOR #1 len=31 dep=0 uid=427 oct=47 lid=427 tim=10031043 hv=607327990 ad='401e258'
BEGIN DBMS_OUTPUT.DISABLE; END;

END OF STMT
PARSE #1:c=1,e=1,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=4,tim=10031043
EXEC #1:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=1,dep=0,og=4,tim=10031044
=====================
PARSING IN CURSOR #1 len=34 dep=0 uid=427 oct=42 lid=427 tim=10031515 hv=1582735206 ad='2f6c2f8'
alter session set sql_trace=false
END OF STMT
PARSE #1:c=1,e=1,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=4,tim=10031516
EXEC #1:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=10031517


MG, March 27, 2003 - 3:56 am UTC

Hi Tom,

I wants to redirect the output of procedure "P1" to "MyFile.sql", for further execution. So I did that as following ( in Perl).

print ORA "set serveroutput on for wra \n";
print ORA "set feedback off \n";
print ORA "spool MyFile.sql \n";
print ORA "exec p1; \n";

In one of the entry in MyFile.sql I have :
host copy location1\file1.ora Location2\file2.ora

So my problem is this line will be break, some times. (Some Computers, this will give correctly, some of them not)

ex: host copy location1\file1.ora Location2\file2.o
ra

So, When I execute the file MyFile.sql, this command execution will be failed.

So why this "print ORA "set serveroutput on for wra \n";
", will be not working as I expect? Is there any thing wrong, the way I have applied?

Could you please give me suggestion?

Thanks in Advance



Tom Kyte
March 27, 2003 - 7:51 am UTC

ops$tkyte@ORA920> set serveroutput on format wrapped
ops$tkyte@ORA920> exec dbms_output.put_line( 'how now brown cow, the fox ran away with the spoon' )
how now brown cow, the fox ran away with the spoon

PL/SQL procedure successfully completed.

ops$tkyte@ORA920> set linesize 30
ops$tkyte@ORA920> exec dbms_output.put_line( 'how now brown cow, the fox ran away with the spoon' )
how now brown cow, the fox ran
 away with the spoon

PL/SQL procedure successfully completed.

ops$tkyte@ORA920>


<b>set linesize 100</b>

you are missing something like that.  Suggestion -- it is probably cause you write in perl ;) -- but I think most people would find:

set serveroutput on format wrapped

lots less obscure then ... on for wra.  I know I did a double take trying to remember what exactly that meant. 

MG, March 27, 2003 - 8:29 am UTC

Thank you very much. Problem solved.

STORED SET filename................suppress output

Denise, August 07, 2003 - 4:21 pm UTC

the explanation regarding the differences between
dbms_output.enable and set serveroutput on was very helpful.

now my dilemma:

I have a sql plus Menu screen I developed for users to
perform some batch verification procedures.(see code/output)

How do I suppress the output 'Wrote file saved_settings' from the screen everytime the STORED SET filename REPLACE
command is executed??

I have tried everything under the sun with no results..
I even created a PL/SQL block stored in a query:
begin
 dbms_output.put_line('                  ');
end;
nothing works!!!!(gasp!!)

thanks for any tips...if there is a work around to this.
=========================================================
output:
***************************************************
* Select batch verification processing option:
* 1. Verify Client
* 2. Verify Appealcode
* 3. Verify Dollars and Count
* 4. Update Batch Status
* 5. Verify Batch Flags
* 6. Exit
***************************************************
>6
Wrote file saved_settings

prompt

SQL> 

CODE:
set serveroutput on size 1000000 
set echo off verify off trimspool on linesize 1000
cl screen
prompt ***************************************************
prompt * Select batch verification processing option:
prompt * 1. Verify Client
prompt * 2. Verify Appealcode
prompt * 3. Verify Dollars and Count
prompt * 4. Update Batch Status
prompt * 5. Verify Batch Flags
prompt * 6. Exit
prompt ***************************************************
accept process prompt ">"
STORE SET saved_settings REPLACE 
SET FEEDBACK OFF HEADING OFF 
SPOOL query.sql
select decode(&process,1,'START checkClient',2,'START checkAppealcode',
3,'START checkDollars_Count',4,'START upd_BatchStatus',5,'START check_BatchFlags',
6,'prompt',null)
from dual;
SPOOL OFF
START saved_settings
START query



 















 

Tom Kyte
August 10, 2003 - 11:02 am UTC

...
accept process prompt ">"
set termout off
STORE SET saved_settings REPLACE
set termout on

SET FEEDBACK OFF HEADING OFF
SPOOL query.sql
...

SET TERMOUT ON.....feedback

Denise, August 11, 2003 - 9:33 am UTC

Tom

wish there was a response rating option that allowed for
simply providing feedback and not giving your response a
"rating"....as your responses are always very much appreciated(sorry for the 'Not Useful' rating I'll explain why);

In order to get the system to suppress the "Wrote file...."
statement upon a menu selection I had to strategically
place TERM OFF/ON in several places within the menu script
and also had to place SET TERM ON in each of the scripts
called by the DECODE function.

If SET TERM/TERMOUT OFF/ON was placed as you suggested
it does not work when a script was called and sv parameters for user input was required.

attached is the menu script with the changes, also one of
the five scripts with SET TERMOUT ON and the output to screen. This was the only way I could get this to work
after attempting a myriad of solutions.

set serveroutput on size 1000000
set echo off verify off trimspool on TERM ON linesize 1000
cl screen
prompt ***************************************************
prompt * Select batch verification processing option:
prompt * 1. Verify Client
prompt * 2. Verify Appealcode
prompt * 3. Verify Dollars and Count
prompt * 4. Update Batch Status
prompt * 5. Verify Batch Flags
prompt * 6. Exit
prompt ***************************************************
accept process prompt ">"
SET TERM OFF
STORE SET saved_settings REPLACE
SET TERM ON
SET FEEDBACK OFF HEADING OFF
SPOOL query.sql
select decode(&process,1,'START checkClient',2,'START checkAppealcode',
3,'START checkDollars_Count',4,'START upd_BatchStatus',5,'START check_BatchFlags',
6,'prompt','Please Enter Correct Selection')
from dual;
SPOOL OFF
START saved_settings
START query
**********************************************************
checkAppealcode.sql
SET TERM ON
select p.idnumber,p.usercode1,p.usercode2,bd.batchno,bd.appealcode
from prospect p,batchdonation bd
where bd.appealcode LIKE (upper('&aplcode'))
and bd.batchno between &batch1 and &batch2
and p.idnumber=bd.idnumber;
***********************************************************
output:
*************************************************
* Select batch verification processing option:
* 1. Verify Client
* 2. Verify Appealcode
* 3. Verify Dollars and Count
* 4. Update Batch Status
* 5. Verify Batch Flags
* 6. Exit
***************************************************
>2

START checkAppealcode
Enter value for aplcode:
Enter value for batch1:
Enter value for batch2:






The pipeline solution is interesting.

Philip Heath, December 09, 2003 - 12:10 pm UTC

Tom,

I pulled an anonymous PL/SQL block out of a Perl script, and I converted it to a pipelined function just as your example shows. It works in sql*plus as your example did. However, I went to do the execute within a select statement within my Perl script, and OCI doesn't like it:

PLS-00428: an INTO clause is expected in this SELECT statement (DBD ERROR: OCIStmtExecute) [for statement ``
BEGIN

select * from table( ccdbo.update_market_area_codes() );

END;
'' with params: ])

This is in Perl 5.8.0 using DBI compiled against the 9.0.1 client with a 9.2.0.4 server. Is there a way to have OCI execute this call without an into clause?

Thanks,
Philip

Too many dbms_output statements

Jeevan, May 21, 2004 - 2:36 pm UTC

Tom,

I have a procedure which does a lot of calculations based on various parameters and data in various tables. Whenever a user calls me reporting any problems/queries, I have to debug it and to do so, I add dbms_output lines to the code and check the values at various stages. After I am done, I comment those lines and move the code into production.

So to avoid this everytime, what if I leave all the dbms_output lines uncommented? Will it impact anyway on the server by too many outputs? Because, this procedure is called almost by every user logging to the application. Do you see a problem if so many dbms_output.put_line messages being fired on the server?

Thanks for all your help to the Oracle users.

Regards.

Tom Kyte
May 21, 2004 - 4:37 pm UTC

if you have my books -- you'll know my stance on this.

code in production needs to be instrumented even more than code in TEST!!!!!

you need the instrumented code to help debug in production, you cannot just drop in instrumented code at the last minute in production. in production -- stability is the keyword, no changes.

soooo -- leave it in. just leave it all in.

think about it... what if Oracle

o didn't have v$ tables (instrumentation)
o timed statistics
o sql_trace=true
o alert logs
o trace files
o events


sure, we could theoretically "run faster", but only if you got really really lucky. We would mostly run 1,000's of times slow cause you would have no real data with which to figure out "what is wrong"


Every other line of my code is DEBUG and it is always in production. Always. I write it in there from day1 (and wish more people would).....

Change the NO to YES in the url up there and see what happens.

Sorry, but I did not get your point exactly.

Jeevan, May 21, 2004 - 5:03 pm UTC

Tom,

So do you suggest that I leave the dbms_output lines in the procedure so that I can debug later on? Of course, I have tested this code multiple times in other environments and currently this code executes correctly in production too.

Thanks again.

Tom Kyte
May 22, 2004 - 4:44 pm UTC

I mandate that anyone that works for me -- or provides code to me in some fashion -- provides is fully instrumented as part of the design from day one.

I'm saying -- you need dbms_output in there in production more than you need it anywhere.

Leave it in, definitely. Imagine if we took away sql_trace, v$tables, statspack, etc when we shipped Oracle. You'd be doing the same thing by taking your instrumentation out for production. It would be the worst thing you can do.

Thank You!!!

Jeevan, May 24, 2004 - 11:03 am UTC

Tom,

Thanks for an excellent explaination. I always was worried so far that firing too many dbms_output.put_line statements in prodn might affect. Glad that I asked this question. This will definitely save a lot of debugging & troubleshooting time.

Once again, we all really appreciate the help & guidance you have been extending to the Oracle community.

something like "tee" in sqlplus

A reader, July 04, 2005 - 6:27 am UTC

Tom,

Is there something in SQLPLUS like the "TEE" command in unix?
I'm developing a script which will be run by the Operations team & I want to log the script output as well as print it on the screen.

How can I achieve this?

Thanks as always!

Tom Kyte
July 04, 2005 - 10:41 am UTC

spool does this

spool file.name
query
spool off

query result will appear on screen and in file

How about Huge data which buffer size exceeds 1,000,000

Suresh, January 08, 2007 - 3:30 am UTC

Hi, I am using PL-SQL, I have Probelm with spooling more than max buffer can hold. I set serveroutput as

set serveroutput on size 100000

and then I ran my procedures
After 35,000 records buffer problem is coming
Is there any solution to my problem???

Thanks in Advance,
Suresh
Tom Kyte
January 08, 2007 - 12:26 pm UTC

10g



ops$tkyte%ORA10GR2> set serveroutput on size unlimited
ops$tkyte%ORA10GR2>

With SQL*Plus 10g serveroutput size is by default UNLIMITED

Tonguç, January 10, 2007 - 7:23 am UTC


From SQL*Plus: Release 9.2.0.4.0
Connected to: Oracle9i Enterprise Edition Release 9.2.0.7.0

SQL> show serveroutput
serveroutput OFF
SQL> set serveroutput on
SQL> show serveroutput
serveroutput ON size 2000 format WORD_WRAPPED

From SQL*Plus: Release 9.2.0.4.0
Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.2.0

SQL> show serveroutput
serveroutput OFF
SQL> set serveroutput on
SQL> show serveroutput
serveroutput ON size 2000 format WORD_WRAPPED

From SQL*Plus: Release 10.2.0.1.0
Connected to: Oracle9i Enterprise Edition Release 9.2.0.7.0

SQL> show serveroutput
serveroutput OFF
SQL> set serveroutput on
SQL> show serveroutput
serveroutput ON SIZE UNLIMITED FORMAT WORD_WRAPPED

From SQL*Plus: Release 10.2.0.1.0
Connected to: Oracle9i Enterprise Edition Release 9.2.0.7.0

SQL> show serveroutput
serveroutput OFF
SQL> set serveroutput on
SQL> show serveroutput
serveroutput ON SIZE UNLIMITED FORMAT WORD_WRAPPED

dbms_output format

A reader, November 17, 2008 - 8:32 pm UTC

How do I get dbms_output.put_line to format the output nicely? In the following example, I was trying to display a SQL with proper indentation, but the output is very different than I had entered. Thanks.

SQL> show serveroutput
serveroutput ON SIZE UNLIMITED FORMAT WORD_WRAPPED
SQL> DECLARE
  2     l_sql VARCHAR2(4000) := 
  3  'SELECT *
  4  FROM (
  5     SELECT OWNER,
  6            OBJECT_NAME,
  7            SUBOBJECT_NAME,
  8            OBJECT_ID,
  9            DATA_OBJECT_ID,
 10            OBJECT_TYPE,
 11            CREATED,
 12            LAST_DDL_TIME,
 13            TIMESTAMP,
 14            STATUS,
 15            TEMPORARY,
 16            GENERATED,
 17            SECONDARY
 18     FROM   all_objects
 19     WHERE  status = ''VALID''
 20     ORDER  BY object_name
 21  )
 22  WHERE  rownum <= 5';
 23  
 24  BEGIN
 25     dbms_output.put_line(l_sql);
 26  END;
 27  /
SELECT *
FROM (
   SELECT OWNER,
          OBJECT_NAME,
          SUBOBJECT_NAME,
          OBJECT_ID,
          DATA_OBJECT_ID,

OBJECT_TYPE,
          CREATED,
          LAST_DDL_TIME,
          TIMESTAMP,
          STATUS,
          TEMPORARY,

GENERATED,
          SECONDARY
   FROM   all_objects
   WHERE  status = 'VALID'
   ORDER  BY object_name
)
WHERE  rownum <= 5

PL/SQL procedure successfully completed.

Tom Kyte
November 18, 2008 - 7:39 pm UTC

<b>ops$tkyte%ORA10GR2> set linesize 32767
</b>ops$tkyte%ORA10GR2> DECLARE
  2     l_sql VARCHAR2(4000) :=
  3  'SELECT *
  4  FROM (
  5     SELECT OWNER,
  6            OBJECT_NAME,
  7            SUBOBJECT_NAME,
  8            OBJECT_ID,
  9            DATA_OBJECT_ID,
 10            OBJECT_TYPE,
 11            CREATED,
 12            LAST_DDL_TIME,
 13            TIMESTAMP,
 14            STATUS,
 15            TEMPORARY,
 16            GENERATED,
 17            SECONDARY
 18     FROM   all_objects
 19     WHERE  status = ''VALID''
 20     ORDER  BY object_name
 21  )
 22  WHERE  rownum <= 5';
 23
 24  BEGIN
 25     dbms_output.put_line(l_sql);
 26  END;
 27  /
SELECT *
FROM (
   SELECT OWNER,
          OBJECT_NAME,
          SUBOBJECT_NAME,
          OBJECT_ID,
          DATA_OBJECT_ID,
          OBJECT_TYPE,
          CREATED,
          LAST_DDL_TIME,
          TIMESTAMP,
          STATUS,
          TEMPORARY,
          GENERATED,
          SECONDARY
   FROM   all_objects
   WHERE  status = 'VALID'
   ORDER  BY object_name
)
WHERE  rownum <= 5

PL/SQL procedure successfully completed.

Paula, August 13, 2009 - 10:09 am UTC

Please don't jump too hard on newbies trying to use/understand Oracle documentation. I've seen in Oracle 11.1, in section 87 DBMS_OUTPUT, under Operational Notes
this line:

Typing SET SERVEROUTPUT ON in SQL*Plus has the effect of invoking
DBMS_OUTPUT.ENABLE (buffer_size => NULL);

which would lead me to think that if I include the enable, then a get_line, I wouldn't need to use the set serveroutput on.
Why do I want to do that? Multiple people can use that procedure, and if they forget to set it on, they won't see any error messages generated by the procedure.
I end up using a function instead, so I can get around it, but the Oracle documentation gave me hope that I could avoid using set serverout on, and I thought I was doing it wrong.
I'm disappointed, but if Tom says it cannot be done, that trumps Oracle documentation for me!
Tom Kyte
August 13, 2009 - 12:35 pm UTC

well, the documentation is not incorrect - set serveroutput on does in fact do that, but sqlplus doesn't know that was done - so sqlplus doesn't know to call "dbms_output.get_lines" afterwards.

the default setting of serveroutput is OFF (a sqlplus flag)

unless and until you turn it on - sqlplus is not aware you want it printed, it assumes you do not want the overhead of calling dbms_output.get_lines after every statement.


A reader, August 13, 2009 - 3:56 pm UTC


Paula, August 26, 2009 - 11:55 am UTC

Dear "a reader",

My point is that if
SET SERVEROUTPUT ON
in SQL*Plus has the effect of invoking
DBMS_OUTPUT.ENABLE (buffer_size => NULL);
it is a quick trip-stumble-fall for a newbie to think that
DBMS_OUTPUT.ENABLE (buffer_size => NULL);
has the effect of invoking
SET SERVEROUTPUT ON

why would I put into a stored procedure a "dbms_output.put_line" if I didn't want to SEE that output?

I think it is sad that I can put into a stored procedure a DBMS_OUTPUT.ENABLE and use dbms_output.put_line and then I have to tell sql_plus to print what I've asked the procedure to output. But when I use utl_file.put_line, all of a sudden sqlplus KNOWS to put it into the file I've defined.


BTW, the rating is for "a reader", not the original response
Tom Kyte
August 26, 2009 - 7:39 pm UTC

My point is that if 
   SET SERVEROUTPUT ON
in SQL*Plus has the effect of invoking
   DBMS_OUTPUT.ENABLE (buffer_size => NULL);
it is a quick trip-stumble-fall for a newbie to think that 
   DBMS_OUTPUT.ENABLE (buffer_size => NULL);
has the effect of invoking
   SET SERVEROUTPUT ON


Only if you use faulty logic.

You are saying "if A implies B, then B implies A"

If it is raining, the sidewalk is wet.
If the sidewalk is wet, it must be raining (no, i squirted a hose on it)


sqlplus is a client program - just like you could write (you could in fact write sqlplus, there is no magic to it, it is not "special").

Tell you what, why is it that when I run your developed java code and I set dbms_output on - you did not print the output for me?

As for the "But when I use utl_file.put_line, all of a
sudden sqlplus KNOWS to put it into the file I've defined."

well, I'm not really sure how to address that - because you seem to think sqlplus has something to do with the writing of the file - it does not.

sqlplus could be replaced with YOUR CODE and you call the procedure and the file appears, your code did NOTHING to make the file appear.


All dbms_output.put_line does it write to a buffer, an array, in memory. If the client wants to display it - that is fine, if they do not, that is fine - we don't care (in the server), we just either buffer the data (enable) or not (disable)

It is up to the client to retrieve and print the buffer out - if you do not tell sqlplus "RETRIEVE THIS BUFFER AND PRINT IT OUT", sqlplus (a client program, something you could write) will not print it out.

People would be completely annoyed if they said "sqlplus - do not print out anything" and sqlplus started printing out stuff - wouldn't then. serveroutput defaults to off - unless and until you turn it on - it would be a bug to print out anything.

Still not sure how DBMS_OUTPUT.ENABLE works

Karla, October 09, 2009 - 6:13 am UTC

I've used DBMS_OUTPUT for years, always with SERVEROUTPUT as I've never been able to get ENABLE and GET_LINE(S) to work.

If I understand correctly (which is probably the problem):

ENABLE simply switches buffering on.
PUT_LINE writes to the buffer with a line terminator.

SET SERVEROUTPUT ON is a sql*plus command that dumps each buffered line to the screen as it's written to the buffer, effectively issuing ENABLE and then GET_LINE for each line written to the buffer.

So, if you're using ENABLE, then GET_LINE(S) is how you get a line from the buffer and write it to screen?

So, I tested this:





me> set serveroutput on
me>
me> DECLARE
2 v_line VARCHAR2(100);
3 v_status INTEGER;
4 BEGIN
5
6 --dbms_output.enable(2000); -- enable buffering
7 dbms_output.put_line('This is a test'); -- write to the buffer
8 --dbms_output.get_line(v_line, v_status); -- get the line from the buffer
9 END;
10 /
This is a test

PL/SQL procedure successfully completed.

me>
me> SET SERVEROUTPUT OFF
me> DECLARE
2 v_line VARCHAR2(100);
3 v_status INTEGER;
4 BEGIN
5
6 dbms_output.enable(2000); -- enable buffering
7 dbms_output.put_line('This is a test'); -- write to the buffer
8 dbms_output.get_line(v_line, v_status); -- get the line from the buffer
9 END;
10 /

PL/SQL procedure successfully completed.

me>



So, GET_LINE doesn't dump to the screen?

I'm clearly missing a very important point, here.

enable serveroutput

Abhisek, April 13, 2010 - 6:16 am UTC

Hi Tom,

Can we enable the serveroutput in PL/SQL block. I know it is a SQL Plus command to set serveroutput on but can we incorporate in PL/SQL block?

Also to change the buffer size dynamically i use dbms_output.enable(null) but doing so doesnt print the results on screen. Reason: serveroutput is off.

My question is can we make the two things: setting serveroutput on and dynamically changing buffer, be done in PL/SQL block.
Tom Kyte
April 13, 2010 - 9:23 am UTC

you can call dbms_output.enable - BUT - sqlplus won't know you did that so you'd still need to tell sqlplus "hey, ENABLE OUTPUT please!!!" because sqlplus has to know to retrieve the data from dbms_output and print it.

ops$tkyte%ORA10GR2> set serveroutput off
ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> begin
  2          dbms_output.enable;
  3          dbms_output.put_line( 'hello world' );
  4  end;
  5  /

PL/SQL procedure successfully completed.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> begin
  2          dbms_output.put_line( 'more stuff' );
  3  end;
  4  /

PL/SQL procedure successfully completed.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> set serveroutput on
ops$tkyte%ORA10GR2> exec null
hello world
more stuff

PL/SQL procedure successfully completed.


ops$tkyte%ORA10GR2> set serveroutput off
ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> begin
  2  --      dbms_output.enable;
  3          dbms_output.put_line( 'hello world' );
  4  end;
  5  /

PL/SQL procedure successfully completed.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> begin
  2          dbms_output.put_line( 'more stuff' );
  3  end;
  4  /

PL/SQL procedure successfully completed.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> set serveroutput on
ops$tkyte%ORA10GR2> exec null

PL/SQL procedure successfully completed.




so there we see that calling dbms_output.enable enabled dbms_output - but sqplus doesn't KNOW to do it until you tell it.


DBMS_OUTPUT.ENABLE

suriya, May 06, 2011 - 7:02 am UTC

Hi tom,

i'm using toad for run my queries,so it has explicit option to turn on the dbms_output.so not yet used dbms_output.enable in my programs.but from yo replies i came to know dbms_output.enable is using for enable the dbms_output ...but also confused with dbms_output.enable..can yo pls explain me clearly??
Tom Kyte
May 06, 2011 - 10:35 am UTC


In the dbms_output package, there is a boolean variable. it defaults to FALSE.

If it is set to false, then when you call dbms_output.put_line, put_line just returns - it does nothing, there is no output.

when you call dbms_output.enable (that is what set serveroutput on in sqlplus does), it sets that flag to true. That makes it so that dbms_output.put_line doesn't just return, it actually records the output so that toad, sqplus,whatever can call dbms_output.get_lines at the end of your plsql call to show you the output it accumulated.

DBMS_OUTPUT.ENABLE

suriya, May 11, 2011 - 6:46 am UTC

Thanks tom...your answer very useful to me...now i clearly understood use of DBMS_OUTPUT.ENABLE

DBMS_OUTPUT.ENABLE

Lukasz, July 27, 2011 - 3:05 am UTC

Thanks Tom, great answer. Made everything clear!

SET SERVEROUTPUT ON - Still confuses me!!

Karthik, August 26, 2012 - 7:53 am UTC

Tom,

A million thanks to your service to the Oracle community.

I need a clarification for the below code with respect to the SET SERVEROUTPUT ON subject,
SQL> sho serveroutput
serveroutput ON size 2000 format WORD_WRAPPED
SQL> exec dbms_output.put_line('Hello');

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.01
SQL> BEGIN
  2     dbms_output.put_line('Hello');
  3  END;
  4  /

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.04


Although SERVEROUTPUT is turned ON, I wonder why SQL Plus is unable to display the string "Hello".
Tom Kyte
August 29, 2012 - 1:20 pm UTC

ops$tkyte%ORA11GR2> show serveroutput
serveroutput ON SIZE 1000000 FORMAT WORD_WRAPPED
ops$tkyte%ORA11GR2> exec dbms_output.disable

PL/SQL procedure successfully completed.

ops$tkyte%ORA11GR2> show serveroutput
serveroutput ON SIZE 1000000 FORMAT WORD_WRAPPED
ops$tkyte%ORA11GR2> exec dbms_output.put_line( 'hello' );

PL/SQL procedure successfully completed.

ops$tkyte%ORA11GR2> exec dbms_output.enable

PL/SQL procedure successfully completed.

ops$tkyte%ORA11GR2> exec dbms_output.put_line( 'hello' );
hello

PL/SQL procedure successfully completed.




the command "set serveroutput on" simply issues "dbms_output.enable(...)"

If you explicitly disable output (which you must be doing somewhere, in some stored procedure, in some login.sql script, some script you are running) - then sqlplus might THINK it is enabled - but the database begs to differ


so, look around for someone calling dbms_output.disable

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library