CLOB
Oracleで列のサイズをバイト単位で取得するにはどうすればよいですか?
LENGTH()
DBMS_LOB.getLength()
どちらもで使用されている文字数を返しますが、使用されているCLOB
バイト数を知る必要があります(マルチバイト文字セットを扱っています)。
いくつか考えた後、私はこの解決策を思いつきました:
LENGTHB(TO_CHAR(SUBSTR(<CLOB-Column>,1,4000)))
SUBSTR
最初の 4000 文字のみを返します (最大文字列サイズ)
TO_CHAR
CLOB
からに変換しますVARCHAR2
LENGTHB
文字列で使用される長さをバイト単位で返します。
受け入れられた回答よりも幅広いケースで元の問題を解決するため、コメントを回答として追加しています。注: データに含まれるマルチバイト文字の最大長とおよその割合を知っておく必要があります。
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(DBMS_LOB.SUBSTR(<CLOB-Column>,3000,3001))),0)
+NVL(LENGTHB(TO_CHAR(DBMS_LOB.SUBSTR(<CLOB-Column>,6000,6001))),0)
+...
最長の CLOB をカバーするために必要な数のチャンクを追加し、データの 1 文字あたりの平均バイト数に従ってチャンク サイズを調整します。
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;
/
NVL(length(clob_col_name),0) は私にとってはうまくいきます。
簡単な解決策は、 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 で動作すると確信していますか?
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