我尝试从数据库中读取并输出文本文件。它可以工作但空行将被删除。
实施例
Hello Mr. X
Text from Mailboddy
Greetins
Mr. Y
输出:
Hello Mr. X
Text from Mailboddy
Greetins
Mr. Y
CODE:
sqlplus -s $DBLOGIN <<ENDE_SQL > file
SET FEEDBACK OFF;
SET SERVEROUTPUT ON;
DECLARE
l_text CLOB;
BEGIN
SELECT text
INTO l_text
FROM table;
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;
END;
/
ENDE_SQL
PL / SQL代码在SQLDeveloper中使用空行。但是在文件中所有空行都被删除了。
答案 0 :(得分:1)
假设数据已加载到CLOB中,换行符为CHR(13)||CHR(10)
,如果您只是直接从表中选择,您可以看到它的预期格式,那么问题在于SQL * Plus是如何与DBMS_OUTPUT
进行互动。
默认情况下,SET SERVEROUTPUT ON
会将FORMAT
设置为WORD_WRAPPED
。文档说'SQL * Plus左对齐每条线,跳过所有前导空格',但是没有注意到这也会跳过所有空行。
如果您设置SERVEROUTPUT ON FORMAT WRAPPED
或... TRUNCATED
,则会重新显示空白行。但是你需要确保你的线条足够宽,以便打印出你想要打印的最长线条,特别是如果你选择了TRUNCATED
。
(此外,您的代码未声明l_pos NUMBER := 1
,并且缺少最终DBMS_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
,具体取决于您的配置。像this这样的东西可能会给你一些指示。