ねら~ITエンジニア雑記

やきうのお兄ちゃんが綴るOracle Databaseメインのブログ

LOB型(BLOB / CLOB / BFILE)のデータの長さ(バイト数 or 文字数)を確認する(DBMS_LOB.GETLENGTHファンクション)

※2018/8/20訂正:DBMS_LOBパッケージのGETLENGTHファンクションは、BLOB型はバイト数を戻しますが
CLOBについては文字数を返します。バイト数ではありません。謹んでお詫び申し上げます。
下記の記事も参照して下さいやで彡(゚)(゚)

CLOB型の(文字数ではなく)バイト数を返却するファンクションを自作(Oracle Database)
https://gonsuke777.hatenablog.com/entry/2018/08/20/004252

LOB型(BLOB / CLOB / BFILE)のデータの長さ(バイト数 or 文字数)を確認するには
DBMS_LOBパッケージのGETLENGTHファンクションを使用します。

Oracle Database PL/SQLパッケージおよびタイプ・リファレンス
11g リリース2(11.2)
B56262-06
82 DBMS_LOB
GETLENGTHファンクション
http://docs.oracle.com/cd/E16338_01/appdev.112/b56262/d_lob.htm#i998484

下記のサンプルプログラムは、V$SQLAREAビュー の SQL_FULLTEXT列(CLOB型) の
長さ(バイト数 or 文字数)を sql_id毎 に算出して出力しています。

SET SERVEROUTPUT ON SIZE UNLIMITED;
DECLARE
  CURSOR c1 IS
  SELECT DISTINCT
         SQL_ID
    FROM V$SQLAREA
   ORDER BY SQL_ID;
  v_clob_loc CLOB;
  n_length   PLS_INTEGER;
BEGIN
  FOR rec_c1 IN c1
  LOOP
    SELECT SQL_FULLTEXT
      INTO v_clob_loc
      FROM V$SQLAREA
     WHERE SQL_ID = rec_c1.SQL_ID;
    n_length := DBMS_LOB.GETLENGTH(v_clob_loc);
    DBMS_OUTPUT.PUT_LINE('SQL_ID =>"' || rec_c1.SQL_ID || '" LENGTH=>' || n_length);
  END LOOP;
END;
/

実行結果は以下の通りとなります。

SQL> L
  1  DECLARE
  2    CURSOR c1 IS
  3    SELECT DISTINCT
  4           SQL_ID
  5      FROM V$SQLAREA
  6     ORDER BY SQL_ID;
  7    v_clob_loc CLOB;
  8    n_length   PLS_INTEGER;
  9  BEGIN
 10    FOR rec_c1 IN c1
 11    LOOP
 12      SELECT SQL_FULLTEXT
 13        INTO v_clob_loc
 14        FROM V$SQLAREA
 15       WHERE SQL_ID = rec_c1.SQL_ID;
 16      n_length := DBMS_LOB.GETLENGTH(v_clob_loc);
 17      DBMS_OUTPUT.PUT_LINE('SQL_ID =>"' || rec_c1.SQL_ID || '" LENGTH=>' || n_length);
 18    END LOOP;
 19* END;
SQL> /
SQL_ID =>"00fx7adv5q5gm" LENGTH=>52  ★
SQL_ID =>"00vu4ys02dzzh" LENGTH=>490 ★
SQL_ID =>"00w41y43c74zp" LENGTH=>117 ★
:
:
:
SQL_ID =>"gyts2pm7222m3" LENGTH=>229 ★
SQL_ID =>"gz5243fwyy3uy" LENGTH=>349 ★
SQL_ID =>"gzj1jk9n0ju95" LENGTH=>104 ★

PL/SQL procedure successfully completed.

SQL>

この関数の注意点について、マニュアルには下記の記述があります。

GETLENGTHファンクション
このファンクションは、指定されたLOB値の長さを取得します。長さは、バイト数または文字数で戻されます。

CLOB型については、キャラクタセット/NLS_LENGTH_SEMANTICSパラメタ/マルチバイト文字データ等の
条件によって、このファンクションが返す値が変わって来るんだと思います。

後日、検証しますは(´・ω・)ゞ

※20151/30追記
PL/SQL を使わずに直書きした方が簡単でした。。。

SELECT SQL_ID
     , DBMS_LOB.GETLENGTH(SQL_FULLTEXT) AS LEN
  FROM V$SQLAREA
 ORDER BY SQL_ID;

SQL_ID                       LEN
------------------- ------------
00fx7adv5q5gm                 52
00rf3t5q2798c                195
00vu4ys02dzzh                490
00w41y43c74zp                117
013ycv5y4vhbx                113
0150jz4c61afb                 65
01gmsncqrjrfr              1,037