テーブルのカラム統計情報の参照

dba_tab_col_statistics 系には 列の値の種類数、上限、下限、密度、NULL の個数、バケット数、平均長などの情報をもつ。
但し、上限値、下限値については Oracle の内部表記における上限、下限を RAW 型で格納しているため人間には理解しにくい。
この内容を分かりやすく見るために RAW 型を文字列に変換する ストアド・ファンクション STATS_RAW2STRING を作って上限値、下限値を確認できるようにする。

dba_tab_col_statistics 系ではデータタイプが判別できないため dba_tab_columns 系を使用

dba_tab_columns 系の low_value / high_value は下位互換用のカラムなので将来的には dba_tab_col_statistics と結合が必要になるかもしれない。

select
  table_name, column_name, data_type,
  STATS_RAW2STRING(low_value, data_type) low_value,
  STATS_RAW2STRING(high_value, data_type) high_value
from user_tab_columns
order by table_name, column_id
/
  • 変換前の low_value: カラムの値の下限値のバイナリ表記
  • 変換前の hight_value: カラムの値の上限値のバイナリ表記

SQL*Plus で実行する前に設定しておくと良い設定

set linesize 200
set pages 100
set wrap off
column table_name for a20
column column_name for a20
column data_type for a9
column high_value for a20
column low_value for a20
alter session set nls_date_format = 'yyyy-mm-dd hh24:mi:ss';

実行結果例

TABLE_NAME          COLUMN_NAME          DATA_TYPE LOW_VALUE            HIGH_VALUE
------------------- -------------------- --------- -------------------- --------------------
EMP                 FIRST_NAME           VARCHAR2  Adam                 Winston
EMP                 LAST_NAME            VARCHAR2  Abel                 Zlotkey
EMPLOYEES           COMMISSION_PCT       NUMBER    .1                   .4
EMPLOYEES           DEPARTMENT_ID        NUMBER    10                   110
EMPLOYEES           EMAIL                VARCHAR2  ABANDA               WTAYLOR
EMPLOYEES           EMPLOYEE_ID          NUMBER    100                  206
EMPLOYEES           FIRST_NAME           VARCHAR2  Adam                 Winston
EMPLOYEES           HIRE_DATE            DATE      2001-01-13 00:00:00  2008-04-21 00:00:00
EMPLOYEES           JOB_ID               VARCHAR2  AC_ACCOUNT           ST_MAN
EMPLOYEES           LAST_NAME            VARCHAR2  Abel                 Zlotkey
EMPLOYEES           MANAGER_ID           NUMBER    100                  205
EMPLOYEES           PHONE_NUMBER         VARCHAR2  011.44.1343.329268   650.509.4876
EMPLOYEES           SALARY               NUMBER    2100                 24000
… 略

STATS_RAW2STRING ファンクション

dba_tab_col_statistics、user_tab_col_statistics(dba_tab_columns や user_tab_columns) の high_value、low_value を判読できる文字列に変換するファンクション

dbms_stats.convert_raw_value 関係のプロシージャ群は一部をオーバーロードにしたせいか NCHAR 系がなかったり ROWID 用が用意されたり少々不恰好な状態になってしまってますね。

CREATE FUNCTION STATS_RAW2STRING(P_VALUE IN RAW, P_DATATYPE IN VARCHAR2)
RETURN VARCHAR2
IS
  vDataType  VARCHAR2(2000) := UPPER(P_DATATYPE);
  vDate    DATE;
  vBinaryFloat  BINARY_FLOAT;
  vBinaryDouble  BINARY_DOUBLE;
  vNumber    NUMBER;
  vROWID    ROWID;
  vRet     VARCHAR2(32767) := NULL;
BEGIN
  IF (P_VALUE IS NOT NULL) THEN
    CASE vDataType
    WHEN 'DATE' THEN
      dbms_stats.convert_raw_value(P_VALUE, vDate);
      vRet := vDate;
    WHEN 'BINARY_FLOAT' THEN
      dbms_stats.convert_raw_value(P_VALUE, vBinaryFloat);
      vRet := TO_CHAR(vBinaryFloat);
    WHEN 'BINARY_DOUBLE' THEN
      dbms_stats.convert_raw_value(P_VALUE, vBinaryDouble);
      vRet := TO_CHAR(vBinaryDouble);
    WHEN 'NUMBER' THEN
      dbms_stats.convert_raw_value(P_VALUE, vNumber);
      vRet := TO_CHAR(vNumber);
    WHEN 'CHAR' THEN
      dbms_stats.convert_raw_value(P_VALUE, vRet);
    WHEN 'VARCHAR2' THEN
      dbms_stats.convert_raw_value(P_VALUE, vRet);
    WHEN 'NCHAR' THEN
      vRet := TO_CHAR(UTL_RAW.CAST_TO_NVARCHAR2(P_VALUE));
    WHEN 'NVARCHAR2' THEN
      vRet := TO_CHAR(UTL_RAW.CAST_TO_NVARCHAR2(P_VALUE));
    WHEN 'ROWID' THEN
      dbms_stats.CONVERT_RAW_VALUE_ROWID(P_VALUE, vROWID);
      vRet := TO_CHAR(vROWID);
    ELSE
      vRet := '['|| TO_CHAR(P_VALUE) ||']';
    END CASE;
  END IF;
  RETURN vRet;
EXCEPTION
  WHEN OTHERS THEN
  vRet := 'ERR!['|| TO_CHAR(P_VALUE) ||']';
  RETURN vRet;
END;
/
 


関連事項

日本オラクル
■ 日本オラクル 株式会社
■ オラクルマスター資格 (オラクルマスターとは
■ Oracle Web セミナー