Assuming the data is loaded into the CLOB with the line breaks as CHR(13)||CHR(10)
, and you can see it in the expected format if you just select directly from the table, then the problem is with how SQL*Plus is interacting with DBMS_OUTPUT
.
By default, SET SERVEROUTPUT ON
sets the FORMAT
to WORD_WRAPPED
. The documentation says 'SQL*Plus left justifies each line, skipping all leading whitespace', but doesn't note that this also skips all blank lines.
If you set SERVEROUTPUT ON FORMAT WRAPPED
or ... TRUNCATED
then your blank lines will reappear. But you need to make sure your linesize is wide enough for the longest possible line you want to print, particularly if you go with TRUNCATED
.
(Also, your code is not declaring l_pos NUMBER := 1
, and is missing a final DBMS_OUTPUT.NEW_LINE
so you'll lose the final line from the CLOB).
To demonstrate, if I create a dummy table with just a CLOB column, and populate it with a value that has the carriage return/linefeed you're looking for:
create table t42(text clob);
insert into t42 values ('Hello Mr. X' || CHR(13) || CHR(10)
|| CHR(13) || CHR(10)
|| 'Text from Mailboddy' || CHR(13) || CHR(10)
|| CHR(13) || CHR(10)
|| 'Greetins' || CHR(13) || CHR(10)
|| 'Mr. Y');
select * from t42;
I get:
TEXT
--------------------------------------------------------------------------------
Hello Mr. X
Text from Mailboddy
Greetins
Mr. Y
Using your procedure (very slightly modified so it will run):
sqlplus -s $DBLOGIN <<ENDE_SQL > file
SET FEEDBACK OFF;
SET SERVEROUTPUT ON FORMAT WORD_WRAPPED; -- setting this explicitly for effect
DECLARE
l_text CLOB;
l_pos number := 1; -- added this
BEGIN
SELECT text
INTO l_text
FROM t42;
while dbms_lob.substr(l_text, 1, l_pos) is not null LOOP
if dbms_lob.substr(l_text, 2, l_pos) = CHR(13) || CHR(10) then
DBMS_OUTPUT.NEW_LINE;
l_pos:=l_pos + 1;
else
DBMS_OUTPUT.put(dbms_lob.substr(l_text, 1, l_pos));
end if;
l_pos:=l_pos + 1;
END LOOP;
dbms_output.new_line; -- added this
END;
/
ENDE_SQL
file
contains:
Hello Mr. X
Text from Mailboddy
Greetins
Mr. Y
If I only change one line in your code, to:
SET SERVEROUTPUT ON FORMAT WRAPPED;
then file
now contains:
Hello Mr. X
Text from Mailboddy
Greetins
Mr. Y
You might want to consider UTL_FILE
for this, rather than DBMS_OUTPUT
, depending on your configuration. Something like this might give you some pointers.