36

CLOBOracleで列のサイズをバイト単位で取得するにはどうすればよいですか?

LENGTH()DBMS_LOB.getLength()どちらもで使用されている文字数を返しますが、使用されているCLOBバイト数を知る必要があります(マルチバイト文字セットを扱っています)。

4

7 に答える 7

20

いくつか考えた後、私はこの解決策を思いつきました:

 LENGTHB(TO_CHAR(SUBSTR(<CLOB-Column>,1,4000)))

SUBSTR最初の 4000 文字のみを返します (最大文字列サイズ)

TO_CHARCLOBからに変換しますVARCHAR2

LENGTHB文字列で使用される長さをバイト単位で返します。

于 2009-11-25T15:50:09.450 に答える
18

受け入れられた回答よりも幅広いケースで元の問題を解決するため、コメントを回答として追加しています。注: データに含まれるマルチバイト文字の最大長とおよその割合を知っておく必要があります。

4000 バイトを超える CLOB がある場合は、SUBSTR ではなく DBMS_LOB.SUBSTR を使用する必要があります。amountパラメータとoffsetパラメータが DBMS_LOB.SUBSTR で逆になっていることに注意してください。

次に、4000 未満の部分文字列が必要になる場合があります。これは、このパラメーターが文字数であるためです。マルチバイト文字がある場合、4000 文字は 4000バイトを超える長さになりORA-06502: PL/SQL: numeric or value error: character string buffer too small、部分文字列の結果が得られるためです。 4000 バイトの制限がある VARCHAR2 に収まる必要があります。取得できる正確な文字数は、データ内の 1 文字あたりの平均バイト数によって異なります。

だから私の答えは:

LENGTHB(TO_CHAR(DBMS_LOB.SUBSTR(<CLOB-Column>,3000,1)))
+NVL(LENGTHB(TO_CHAR(DBM‌​S_LOB.SUBSTR(<CLOB-Column>,3000,3001))),0)
+NVL(LENGTHB(TO_CHAR(DBM‌​S_LOB.SUBSTR(<CLOB-Column>,6000,6001))),0)
+...

最長の CLOB をカバーするために必要な数のチャンクを追加し、データの 1 文字あたりの平均バイト数に従ってチャンク サイズを調整します。

于 2013-04-25T08:39:04.027 に答える
7

VARCHAR2 より大きい CLOB サイズの場合は、これを試してください。

CLOB を「VARCHAR2 互換」サイズの部分に分割し、CLOB データのすべての部分で lengthb を実行し、すべての結果を要約する必要があります。

declare
   my_sum int;
begin
   for x in ( select COLUMN, ceil(DBMS_LOB.getlength(COLUMN) / 2000) steps from TABLE ) 
   loop
       my_sum := 0;
       for y in 1 .. x.steps
       loop
          my_sum := my_sum + lengthb(dbms_lob.substr( x.COLUMN, 2000, (y-1)*2000+1 ));
          -- some additional output
          dbms_output.put_line('step:' || y );
          dbms_output.put_line('char length:' || DBMS_LOB.getlength(dbms_lob.substr( x.COLUMN, 2000 , (y-1)*2000+1 )));
          dbms_output.put_line('byte length:' || lengthb(dbms_lob.substr( x.COLUMN, 2000, (y-1)*2000+1 )));
          continue;
        end loop;
        dbms_output.put_line('char summary:' || DBMS_LOB.getlength(x.COLUMN));
        dbms_output.put_line('byte summary:' || my_sum);
        continue;
    end loop;
end;
/
于 2013-07-25T07:54:58.043 に答える
6

NVL(length(clob_col_name),0) は私にとってはうまくいきます。

于 2015-11-06T15:45:32.937 に答える
6

簡単な解決策は、 CLOB を BLOB にキャストしてから、 BLOB の長さを要求することです。

問題は、Oracle には CLOB を BLOB にキャストする関数がないことですが、それを行う関数を定義するだけで済みます。

create or replace
FUNCTION clob2blob (p_in clob) RETURN blob IS 
    v_blob        blob;
    v_desc_offset PLS_INTEGER := 1;
    v_src_offset  PLS_INTEGER := 1;
    v_lang        PLS_INTEGER := 0;
    v_warning     PLS_INTEGER := 0;  
BEGIN
    dbms_lob.createtemporary(v_blob,TRUE);
    dbms_lob.converttoblob
        ( v_blob
        , p_in
        , dbms_lob.getlength(p_in)
        , v_desc_offset
        , v_src_offset
        , dbms_lob.default_csid
        , v_lang
        , v_warning
        );
    RETURN v_blob;
END;

バイト数を取得するために使用する SQL コマンドは次のとおりです。

SELECT length(clob2blob(fieldname)) as nr_bytes 

また

SELECT dbms_lob.getlength(clob2blob(fieldname)) as nr_bytes

Unicode(UTF-8)を使用せずにOracle 10gでこれをテストしました。しかし、この解決策はUnicode(UTF-8) Oracleインスタンスを使用して正しいに違いないと思います:-)

clob を blob に変換するソリューションを投稿した Nashev のおかげでレンダーしたいOracle で CLOB を BLOB に変換するにはどうすればよいですか? また、ドイツ語で書かれたこの投稿 (コードは PL/SQL です) 13ter.info.blogには、blob を clob に変換する関数が追加されています。

誰かが Unicode(UTF-8) CLOB で 2 つのコマンドをテストできるので、これは Unicode で動作すると確信していますか?

于 2018-02-14T08:43:28.973 に答える
-1

4000 バイトまでしか機能しません。CLOB が 4000 バイトより大きい場合は、これを使用します

declare
v_clob_size clob;

begin

      v_clob_size:= (DBMS_LOB.getlength(v_clob)) / 1024 / 1024;
      DBMS_OUTPUT.put_line('CLOB Size   ' || v_clob_size);   
end;

また

select (DBMS_LOB.getlength(your_column_name))/1024/1024 from your_table
于 2012-04-04T16:33:02.347 に答える