🌍
グローバル一時表とプライベート一時表の違い
はじめに
Oracle Master Silver SQL の学習中に、「一時表のデータはいつ消えるのか?」という点が気になったため、
グローバル一時表とプライベート一時表の違いを実際に SQL 実験で確認しました。
特に、ON COMMIT DELETE ROWS や ON COMMIT PRESERVE DEFINITION などの指定によって
データ削除のタイミングがどう変化するかを検証しています。
一時表とは
一時表とはデータを一時的に保管するための表です。一時表にINSERTしたデータはそのセッションからのみ参照可能で、使用終了したら自動的に削除されます。
一時表にはグローバル一時表とプライベート一時表が存在します。
グローバル一時表
(GLOBAL TEMPORARY TABLE)は「テーブルの定義だけが共有され、データは各セッションごとに独立して存在する」という特殊な構造を持ちます。
bash-4.2$ sqlplus user_a/a@localhost/XEPDB1
SQL*Plus: Release 21.0.0.0.0 - Production on Fri Oct 17 17:56:32 2025
Version 21.3.0.0.0
Copyright (c) 1982, 2021, Oracle. All rights reserved.
Connected to:
Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
SQL> CREATE GLOBAL TEMPORARY TABLE temp_orders (
orde 2 r_id NUMBER,
amount NUMBER
) ON COMMIT DELETE ROWS;
INSERT INTO temp_orders VALUES (1, 1000);
SELECT * FROM temp_orders;
Table created.
SQL> SQL>
1 row created.
SQL>
ORDER_ID AMOUNT
---------- ----------
1 1000
SQL> exit
Disconnected from Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
bash-4.2$ sqlplus sys/Password123@localhost/XEPDB1 as sysdba
SQL*Plus: Release 21.0.0.0.0 - Production on Fri Oct 17 17:57:09 2025
Version 21.3.0.0.0
Copyright (c) 1982, 2021, Oracle. All rights reserved.
Connected to:
Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
SQL> GRANT SELECT ON user_a.temp_orders TO user_b;
Grant succeeded.
SQL> exit
Disconnected from Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
bash-4.2$ sqlplus user_b/b@localhost/XEPDB1
SQL*Plus: Release 21.0.0.0.0 - Production on Fri Oct 17 17:57:32 2025
Version 21.3.0.0.0
Copyright (c) 1982, 2021, Oracle. All rights reserved.
Connected to:
Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
SQL> SELECT * FROM user_a.temp_orders;
no rows selected
ユーザーBがデータを見られなかったのは、データがセッションごとに独立しているためであり、ユーザーAのコミット前であればユーザーAのセッションからは見えますが、コミット後はユーザーAのセッションからも見えなくなります。
パターン①:DELETE ROWS(または省略時のデフォルト)
-- グローバル一時表の作成
CREATE GLOBAL TEMPORARY TABLE temp_orders (
order_id NUMBER,
amount NUMBER
) ON COMMIT DELETE ROWS;
-- データ登録と確認
INSERT INTO temp_orders VALUES (1, 1000);
SELECT * FROM temp_orders;
ORDER_ID | AMOUNT
---------- ----------
1 | 1000
-- コミット後に確認
COMMIT;
SELECT * FROM temp_orders;
no rows selected
パターン②:PRESERVE ROWS
SQL> CREATE GLOBAL TEMPORARY TABLE temp_orders (
orde 2 r_id NUMBER,
amount NUMBER
) ON COMMIT PRESERVE ROWS;
Table created.
SQL> INSERT INTO temp_orders VALUES (1, 1000);
1 row created.
SQL> INSERT INTO temp_orders VALUES (2, 2000);
1 row created.
SQL> SELECT * FROM temp_orders;
ORDER_ID AMOUNT
---------- ----------
1 1000
2 2000
SQL> COMMIT;
Commit complete.
SQL> SELECT * FROM temp_orders;
ORDER_ID AMOUNT
---------- ----------
1 1000
2 2000
プライベート一時表
グローバル一時表(GTT)とは異なり、
✅ テーブル定義もデータもセッションごとに完全に独立し、他ユーザーからは一切見えない
という、より“個人専用・短命”な一時表です。
bash-4.2$ sqlplus user_a/a@localhost/XEPDB1
SQL*Plus: Release 21.0.0.0.0 - Production on Fri Oct 17 18:43:39 2025
Version 21.3.0.0.0
Copyright (c) 1982, 2021, Oracle. All rights reserved.
Last Successful login time: Fri Oct 17 2025 18:19:30 +00:00
Connected to:
Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
SQL> CREATE PRIVATE TEMPORARY TABLE ora$ptt_temp_orders (
order_id NUMBER,
amount NUMBER
) ON COMMI 2 3 4 T PRESERVE DEFINITION;
Table created.
SQL> INSERT INTO ora$ptt_temp_orders VALUES (1, 1000);
SELECT * FROM ora$ptt_temp_orders;
1 row created.
SQL>
ORDER_ID AMOUNT
---------- ----------
1 1000
SQL> COMMIT;
SELECT * FROM ora$ptt_temp_orders;
Commit complete.
SQL>
ORDER_ID AMOUNT
---------- ----------
1 1000
SQL> exit
sqlplus user_a/a@localhost/XEPDB1
Disconnected from Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
bash-4.2$ sqlplus user_a/a@localhost/XEPDB1
SQL*Plus: Release 21.0.0.0.0 - Production on Fri Oct 17 18:44:27 2025
Version 21.3.0.0.0
Copyright (c) 1982, 2021, Oracle. All rights reserved.
Last Successful login time: Fri Oct 17 2025 18:43:40 +00:00
Connected to:
Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
SQL> SELECT * FROM ora$ptt_temp_orders;
SELECT * FROM ora$ptt_temp_orders
*
ERROR at line 1:
ORA-00942: table or view does not exist
ここでは、ON COMMIT 句の指定によって、データや定義がどのタイミングで削除されるかを確認してみます。
パターン①:ON COMMIT DROP DEFINITION
SQL> CREATE PRIVATE TEMPORARY TABLE ora$ptt_temp_orders (
order_id NUMBER,
amount NUMBER
) ON COMMI 2 3 4 T DROP DEFINITION;
INSERT INTO ora$ptt_temp_orders VALUES (1, 1000);
SELECT * FROM ora$ptt_temp_orders;
Table created.
SQL> SQL>
1 row created.
SQL>
ORDER_ID AMOUNT
---------- ----------
1 1000
SQL> COMMIT;
SELECT * FROM ora$ptt_temp_orders;
Commit complete.
SQL> SELECT * FROM ora$ptt_temp_orders
*
ERROR at line 1:
ORA-00942: table or view does not exist
パターン➁:ON COMMIT PRESERVE DEFINITION
SQL> CREATE PRIVATE TEMPORARY TABLE ora$ptt_temp_orders (
order_id NUMBER,
amount NUMBER
) ON COMMI 2 3 4 T PRESERVE DEFINITION;
INSERT INTO ora$ptt_temp_orders VALUES (1, 1000);
SELECT * FROM ora$ptt_temp_orders;
Table created.
SQL> SQL>
1 row created.
SQL>
ORDER_ID AMOUNT
---------- ----------
1 1000
SQL> COMMIT;
SELECT * FROM ora$ptt_temp_orders;
Commit complete.
SQL>
ORDER_ID AMOUNT
---------- ----------
1 1000
SQL>
まとめ
| 種類 | 定義の寿命 | データの寿命 | 可視範囲 | 主な利用用途 |
|---|---|---|---|---|
| グローバル一時表 | 永続(スキーマに残る) | セッションまたはトランザクション単位 | 他ユーザーから定義参照可能(データ不可) | アプリ共通の一時領域 |
| プライベート一時表 | 一時(セッション終了で削除) | セッション単位 | 作成したセッションのみ | スクリプト内限定・一時処理用 |
Discussion