4

clobデータ型を返す関数を実装しました。結果をDBMS Outputに出力したいと思います。残念ながら、ORA-06502: PL/SQL: 数値または値のエラーが発生しました。これは DBMS_OUTPUT のサイズが原因だと思います。

これがコードです。

DECLARE

    TYPE tp_col_array IS TABLE OF varchar2(32767); 
    FUNCTION my_fn (        
        p_in_proc_date IN varchar2)
        RETURN clob AS         
         vr_output_str clob;

        BEGIN            

        -- Detailed code hidden due to privacy. Sorry

        RETURN vr_output_str;

        EXCEPTION 
            WHEN LOGIN_DENIED
            THEN 
                DBMS_OUTPUT.PUT_LINE('Invalid username/password: logon denied');
        RETURN 'TEST Terminated';

    END my_fn;

BEGIN
    DBMS_OUTPUT.PUT_LINE(my_fn('31-AUG-14'));    
END;

この問題を理解するのに役立つものを次に示します
1) バッファのサイズを無制限に設定するために以下を追加しましたが、機能しませんでした..

DBMS_OUTPUT.ENABLE(NULL);

また

set serveroutput on size unlimited;

関連リンク: http://www.oracle-developer.net/display.php?id=327

2) vr_output_str のサイズは75387であり、それが戻り型がCLOBである理由です。

DBMS_LOB.getlength(vr_output_str); // =75387

3) 以下を実行することで問題を解決できますが、関数を 3 回実行したため、これは良い解決策ではないと思います。

DBMS_OUTPUT.PUT_LINE(SUBSTR(my_fn ('31-AUG-14'), 1, 32767));
DBMS_OUTPUT.PUT_LINE(SUBSTR(my_fn ('31-AUG-14'), 32768, 32767));
DBMS_OUTPUT.PUT_LINE(SUBSTR(my_fn ('31-AUG-14'), 65536, 32767));

4) Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Productionを使用しています

4

2 に答える 2

10

clob が 32767 バイトより大きい場合、dbms_output.put_line を直接使用して clob を出力することはできません。

この場合、clob を反復処理して一度に 1 つの小さなチャンクを出力するプロシージャを作成できます。このような手順とテスト スクリプトは次のとおりです。

declare 

  c clob;

  procedure print_clob( p_clob in clob ) is
      v_offset number default 1;
      v_chunk_size number := 10000;
  begin
      loop
          exit when v_offset > dbms_lob.getlength(p_clob);
          dbms_output.put_line( dbms_lob.substr( p_clob, v_chunk_size, v_offset ) );
          v_offset := v_offset +  v_chunk_size;
      end loop;
  end print_clob;


begin
  for i in 1..10000 loop
     c := c || 'test';
  end loop;
  --This will result in ora-06502
  --dbms_output.put_line(c);

  print_clob(c);

end;

v_chunk_size は、一度にチャンクされる 32767 バイト未満になる必要があることに注意してください。エンコーディングが 1 文字あたり 2 バイトの場合、(32767/2) を使用する必要があります。

于 2014-11-03T22:05:11.683 に答える
0

次の手順の方が適切です。

  • Oracle 10g には put_line の制限 (最大 32767 文字) がありますが、10g より前の Oracle には最大 255 文字の制限があります。
  • 出力 clob 中のすべての反復ループで行末を追加する「put_line」。したがって、put() をより適切に使用します (そして最後に「DBMS_OUTPUT.NEW_LINE」を使用します)。
    手順 print_clob( p_clob in clob ) IS
        v_offset 番号 デフォルト 1;
        v_chunk_size番号:= 255;
      始める
        ループ
          v_offset > dbms_lob.getlength(p_clob); の場合は終了します。
          dbms_output.put( dbms_lob.substr( p_clob, v_chunk_size, v_offset ) );
          v_offset:= v_offset + v_chunk_size;
        エンドループ;
        DBMS_OUTPUT.NEW_LINE;  
      END print_clob;
于 2015-09-01T18:08:24.763 に答える