假设将数据加载到 CLOB 中,换行符为CHR(13)||CHR(10)
,并且如果您直接从表中选择,您可以以预期的格式看到它,那么问题在于 SQL*Plus 如何与DBMS_OUTPUT
.
默认情况下,SET SERVEROUTPUT ON
将 设置FORMAT
为WORD_WRAPPED
。文档说“SQL*Plus 左对齐每一行,跳过所有前导空格”,但没有指出这也会跳过所有空白行。
如果您设置SERVEROUTPUT ON FORMAT WRAPPED
或... TRUNCATED
然后您的空白行将重新出现。但是你需要确保你的 linesize 足够宽,可以打印最长的行,特别是如果你使用TRUNCATED
.
(此外,您的代码没有声明l_pos NUMBER := 1
,并且缺少 finalDBMS_OUTPUT.NEW_LINE
因此您将丢失 CLOB 的最后一行)。
为了演示,如果我创建一个只有一个 CLOB 列的虚拟表,并使用具有您正在寻找的回车/换行符的值填充它:
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;
我得到:
TEXT
--------------------------------------------------------------------------------
Hello Mr. X
Text from Mailboddy
Greetins
Mr. Y
使用您的程序(稍作修改,以便运行):
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
包含:
Hello Mr. X
Text from Mailboddy
Greetins
Mr. Y
如果我只在您的代码中更改一行,则:
SET SERVEROUTPUT ON FORMAT WRAPPED;
那么file
现在包含:
Hello Mr. X
Text from Mailboddy
Greetins
Mr. Y
您可能需要考虑UTL_FILE
这一点,而不是DBMS_OUTPUT
,具体取决于您的配置。这样的事情可能会给你一些指示。