DUAL 表
DUAL 表とは、オラクル固有のディクショナリ表の 1つで、DUMMY カラムだけで作成されている。
DUMMY カラムには 'X' という 1 レコードだけが存在する。
DUAL 表のオーナは SYS であるが、 PUBLIC シノニム宣言によって
すべてのユーザーから DUAL としてアクセスが可能になっている。
DUAL 表は通常の1 レコードの表とは異なりオプティマイザによって、特別な 実行計画 (FAST_DUAL) が生成される。
一般的な使い方としては、SQL での関数の呼び出しや確認に使用される。
SQLPlus で関数を呼び出して結果を表示する。
--
SQL> SET SERVEROUTPUT ON
DECLARE
vResult NUMBER;
BEGIN
vResult := EXTRACT(DAY FROM SYSDATE);
DBMS_OUTPUT.PUT_LINE('今日は' || vResult || '日です');
END;
/
SQL だけで内容的に同じことを行う
--
SELECT '今日は' || EXTRACT(DAY FROM SYSDATE) || '日です')
FROM DUAL ;
注意
PL/SQLで DUAL 表を関数呼び出しだけを目的とした使用方法は避ける(SQL 文の解析で実行速度が低下する)。
高速化のつもりで DECODE 関数を使用するために DUAL 表にアクセスしているのは、現在では古いコーディングスタイルといえるだろう。
現在(Oracle 9i 以降)では CASE 文(および CASE 式) がサポートされている。そちらを使用するほうが見た目も効率も良い。
× SELECT SYSDATE INTO vDate FROM DUAL ;
○ vDate := SYSDATE ;
SELECT 内に記述してある関数において、データの更新を行ってはいけない。(※)
(※) 自律型トランザクションを用いることで更新することが可能にはなる。しかし、これといった理由はないが、あまりお勧めはしない。
FAST DUAL
Oracle 10g (おそらくR2) から DUAL表 へのアクセスにおいて内部的に FAST DUAL に変換する機能が追加されている。
この FAST_DUAL は 実表の DUAL にアクセスしないため consistent gets も発生しない。このため 以前の DUAL より高速に動作する。FAST DUAL の実体?は X$DAUL を参照している模様。
SQL> SET AUTOTRACE ON EXPLAIN
SQL> SELECT * FROM dual;
.....
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| DUAL | 1 | 2 | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------
SQL> SELECT sysdate FROM dual;
....
-----------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-----------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 (0)| 00:00:01 |
| 1 | FAST DUAL | | 1 | 2 (0)| 00:00:01 |
-----------------------------------------------------------------
DUAL表 関連事項