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すると、空白行が再び表示されます。ただし、特に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

コードの 1 行だけを変更すると、次のようになります。

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 に答える