[Oracle] SQL*Plusを使ってコマンドファイルを動的に生成し、実行する。 | Archive Redo Blog

Archive Redo Blog

DBエンジニアのあれこれ備忘録

SQL*Plusでは、単にSQL文を実行するだけでなく、SELECT文の実行結果を様々なフォーマットで表示したり、それをファイルに出力したりすることができます。

このような機能を応用すると、SQL*Plusのコマンドファイルを動的に生成し、即実行するといったことも可能です。


SQL*Plus で何の設定もせずに SELECT 文を実行すると以下のような感じで結果が返ってきます。

SQL> SELECT TABLE_NAME FROM USER_TABLES;

TABLE_NAME
------------------------------------------------------------
DEPT
EMP
BONUS
SALGRADE
TABLE01
TABLE02
TABLE03
TABLE04
TABLE05
TABLE06
TABLE10

TABLE_NAME
------------------------------------------------------------
TABLE07
TABLE08
TABLE09

14行が選択されました。

SQL> 

そこで、以下のように、1 ページの最大行数を拡張し、ヘッダーを非表示にし、処理行数を非表示にして実行すると、余分なものが一切返ってこなくなります。

SQL> set pages 1000
SQL> set hea off
SQL> set feed off
SQL> SELECT TABLE_NAME FROM USER_TABLES;

DEPT
EMP
BONUS
SALGRADE
TABLE01
TABLE02
TABLE03
TABLE04
TABLE05
TABLE06
TABLE10
TABLE07
TABLE08
TABLE09
SQL>

ところが、これを spool コマンドを使ってファイルに出力すると、

SQL> spool table.txt
SQL> SELECT TABLE_NAME FROM USER_TABLES;
       .
       .
       .
SQL> spool off

以下のようにコマンド文まで出力されてしまいます。

table.txt
SQL> SELECT TABLE_NAME FROM USER_TABLES;

DEPT                                                                                                
EMP                                                                                                 
BONUS                                                                                               
SALGRADE                                                                                            
TABLE01                                                                                             
TABLE02                                                                                             
TABLE03                                                                                             
TABLE04                                                                                             
TABLE05                                                                                             
TABLE06                                                                                             
TABLE10                                                                                             
TABLE07                                                                                             
TABLE08                                                                                             
TABLE09                                                                                             
SQL> spool off
※テーブル名の後ろには linesize の設定に応じた空白文字が出力されています。

そこで、set echo off でコマンドファイルのコマンドを非表示にし、set trims on でファイルに余白の空白文字を出力ししないようにし、さらに一連のコマンドを以下のようなコマンドファイルとして保存し、

output_table.sql
set echo off
set pages 1000
set hea off
set feed off
set trims on
spool table.txt
SELECT TABLE_NAME FROM USER_TABLES;
spool off

実行すると、

SQL> @output_table.sql

以下のような余分なものが一切含まれていないプレーンなファイルが出力されます。

table.txt
DEPT
EMP
BONUS
SALGRADE
TABLE01
TABLE02
TABLE03
TABLE04
TABLE05
TABLE06
TABLE10
TABLE07
TABLE08
TABLE09
※先頭行は空白になります。

このようなファイルが出力できれば、これを別のプログラムの入力データにしたり、あるいはこのファイル自体をコマンドファイルにしたりすることができます。

例えば、以下のようなコマンドファイルを編集し、実行すれば、

output_table.sql
set echo off
set pages 1000
set hea off
set feed off
set trims on
spool output_table.sql
SELECT 'CALL OUTPUT_TABLE_DATA_PROC(''' || TABLE_NAME || ''');'
	FROM USER_TABLES ORDER BY TABLE_NAME;
spool off
@output_table.sql

データベースから取得した最新情報を元に以下のようなコマンドファイルを自動生成し、即実行することができるというわけです。

output_table.sql
CALL OUTPUT_TABLE_DATA_PROC('BONUS');
CALL OUTPUT_TABLE_DATA_PROC('DEPT');
CALL OUTPUT_TABLE_DATA_PROC('EMP');
CALL OUTPUT_TABLE_DATA_PROC('SALGRADE')
CALL OUTPUT_TABLE_DATA_PROC('TABLE01');
CALL OUTPUT_TABLE_DATA_PROC('TABLE02');
CALL OUTPUT_TABLE_DATA_PROC('TABLE03');
CALL OUTPUT_TABLE_DATA_PROC('TABLE04');
CALL OUTPUT_TABLE_DATA_PROC('TABLE05');
CALL OUTPUT_TABLE_DATA_PROC('TABLE06');
CALL OUTPUT_TABLE_DATA_PROC('TABLE07');
CALL OUTPUT_TABLE_DATA_PROC('TABLE08');
CALL OUTPUT_TABLE_DATA_PROC('TABLE09');
CALL OUTPUT_TABLE_DATA_PROC('TABLE10');


考え方次第でいろいろと応用できる小技です。