Is dbms_output.put() being buffered differently from dbms_output.put_line()?

Tom Tresansky picture Tom Tresansky · Sep 21, 2012 · Viewed 9.1k times · Source

Im using Aqua Data Studio to debug a stored proc by scattering output statments throughout.

I have a delete statement in the package which violate an integrity constraint:

DELETE FROM x WHERE x.ID = an_x_with_children;

My proc fails with an ORA-02292 on this line, as expected. I want to see the value of the an_x_with_children variable. So I wrap the line with outputs like so:

dbms_output.put('Attempting to delete x: ' || an_x_with_children);
DELETE FROM x WHERE x.ID = an_x_with_children;
dbms_output.put(' Success');

And expect to see the message as the last thing in the messages console prior to the integrity constraint violated error message. But it doesn't print!

Now if I change the output to use the put_line() procedure like this:

dbms_output.put_line('Attempting to delete x: ' || an_x_with_children);
DELETE FROM x WHERE x.ID = an_x_with_children;
dbms_output.put_line(' Success');

I see the message "Attempting to delete x: 123" immediately before the proc errors out.

The docs for the dbms_output package don't mention the put and put_line procedures behaving any differently in this respect. For instance, it says

Output that you create using PUT or PUT_LINE is buffered.

So I would expect either both or neither to show output when the proc errors.

Can someone explain what's going on with this behaviour to me?

Answer

Rob van Wijk picture Rob van Wijk · Sep 21, 2012

Here is an example that shows the behaviour you're seeing:

SQL> exec dbms_output.put_line('hello')
hello

PL/SQL procedure successfully completed.

SQL> exec dbms_output.put('hello again')

PL/SQL procedure successfully completed.

SQL> exec dbms_output.put(' and again')

PL/SQL procedure successfully completed.

SQL> exec dbms_output.new_line
hello again and again

PL/SQL procedure successfully completed.

The documentation says "SQL*Plus calls GET_LINES after issuing a SQL statement or anonymous PL/SQL calls."

And procedure GET_LINES says "This procedure retrieves an array of lines from the buffer."

With PUT you haven't completed your line yet. And so it doesn't print.

The NEW_LINE procedure mentions this as well: "This procedure puts an end-of-line marker. The GET_LINE Procedure and the GET_LINES Procedure return "lines" as delimited by "newlines". Every call to the PUT_LINE Procedure or NEW_LINE Procedure generates a line that is returned by GET_LINE(S)."

Regards,
Rob.