0

可能重复:
为什么空行没有存储在变量中

我尝试从我的数据库中读取和输出一个文本文件。它可以工作,但空行将被删除。

例子:

Hello Mr. X

Text from Mailboddy

Greetins
Mr. Y

输出:

Hello Mr. X
Text from Mailboddy
Greetins
Mr. Y

代码:

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 中使用空行工作。但在文件中,所有空行都被删除。

4

1 回答 1

1

假设将数据加载到 CLOB 中,换行符为CHR(13)||CHR(10),并且如果您直接从表中选择,您可以以预期的格式看到它,那么问题在于 SQL*Plus 如何与DBMS_OUTPUT.

默认情况下,SET SERVEROUTPUT ON将 设置FORMATWORD_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,具体取决于您的配置。这样的事情可能会给你一些指示。

于 2012-10-08T16:46:46.527 回答