SQL*Plusが使う環境変数を試す（Oracle Database 12c Release 2)


Oracle Database 12c Release 2に付属するSQL*Plusが使ういくつかの環境変数の動作を検証してみました。

# マニュアルの記述
 SQL*Plusには環境変数として[SQL*Plusユーザーズ・ガイド及びリファレンスマニュアル](https://docs.oracle.com/cd/E82638_01/SQPUG/configuring-SQL-Plus.htm#GUID-5A2953BF-9E2F-450B-AFBA-EE2846C59B5E) に記載があります。しかし、検証してみると必ずしもマニュアル通りに動作しなかったり、マニュアルがあいまいだったりするため検証することにしました。

# TWO_TASK
TWO_TASKは古いバージョンから継続して使われる環境変数で、デフォルトの接続文字列を示します。
マニュアルの記載は以下の通りです。

> 接続文字列を指定するUNIX環境変数。データベースを指定しない接続は、TWO_TASKに指定したデータベースに接続されます。

マニュアルにある「データベースを指定しない接続」とは「@接続文字列」が無い接続方法を指すようです。
Oracle Databaseでは「接続文字列」とは、tnsnames.oraに記述された接続記述子の名前を指すことが多いと思います。下記のように実行すると、
SQL*Plus は接続先として scott/tiger@MYDB と指定した場合と同じ動きになります。

```
$ cat ORACLE_HOME/network/admin/tnsnames.ora
MYDB =
  (DESCRIPTION=
    (ADDRESS=(PROTOCOL=TCP)(HOST=remhost1)(PORT=1521))
    (CONNECT_DATA=
      (SERVER=DEDICATED)
      (SERVICE_NAME=MYDB)
    )
  )

$ export TWO_TASK=MYDB
$ sqlplus scott/tiger

SQL*Plus: Release 12.2.0.1.0 Production on 月 6月 4 17:31:05 2018

Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
に接続されました。
SQL> 

```

マニュアルには「接続文字列」としか記述していませんが、実際にはtnsnames.oraファイルの接続記述子ではなく、tnsnames.oraファイルの記述をそのまま書くことができます。

```
$ export TWO_TASK='(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=remhost1)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=MYDB)))'
$ sqlplus scott/tiger

SQL*Plus: Release 12.2.0.1.0 Production on 月 6月 4 17:32:58 2018

Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
に接続されました。
SQL>

```

# SQLPATHとORACLE_PATH
これらの環境変数はスクリプト・ファイルの場所を指定します。マニュアルの記述は以下の通りです。

**SQLPATH**
> SQLスクリプトの位置を指定する環境変数またはWindowsレジストリ・エントリ。SQL*Plusでは、SQLPATHで指定されたディレクトリおよびSQLPATHディレクトリのサブディレクトリに、SQLスクリプト(login.sqlを含む)が検索されます。SQLPATHは、コロンで区切られたディレクトリのリストです。UNIX版のインストールでは、デフォルト値は設定されません。

**ORACLE_PATH**
> SQLスクリプトの位置を指定する環境変数。SQL*PlusがORACLE_PATHでスクリプト・ファイルを検出できない場合、またはORACLE_PATHが設定されていない場合は、現行の作業ディレクトリが検索されます。 
 
SQLPATHには複数のディレクトリを指定できますが、どちらも「スクリプトを探すパス」という意味では同じです。同時に設定した場合の動作はどこにも記述が無いため検証してみました。
以下のように設定します。

|環境変数|設定値|スクリプト内容|
|:---|:---|:---|
|ORACLE_PATH|/home/oracle/oracle_path|SELECT 'ORACLE_PATH' PATH FROM DUAL;|
|SQLPATH|/home/oracle/sqlpath1:/home/oracle/sqlpath2|SELECT 'SQLPATH[12]' PATH FROM DUAL;|
|HOME|/home/oracle|SELECT 'CURRENT' PATH FROM DUAL;|

環境変数で指定されたディレクトリにtest.sqlを配置し、ディレクトリ名がわかるSELECT文を実行するように記述します。
ORACLE_PATHとSQLPATHを両方設定してtest.sqlを実行します。

```
$ cd /home/oracle
$ export ORACLE_PATH=/home/oracle/oracle_path
$ export SQLPATH=/home/oracle/sqlpath1:/home/oracle/sqlpath2
$ sqlplus scott/tiger
SQL> @test.sql

PATH
-----------
ORACLE_PATH

```

上記のように、ORACLE_PATHディレクトリが優先されていることがわかります。
次に優先されたスクリプトを削除し、次に実行されるパスを検証します。

```
$ rm /home/oracle/oracle_path/test.sql
$ sqlplus scott/tiger
SQL> @test.sql

PATH
-------
CURRENT

```

次に検索されたのはカレント・ディレクトリでした。
次にカレント・ディレクトリのtest.sqlファイルを削除してみます。

```
$ rm /home/oracle/test.sql
$ sqlplus scott/tiger
SQL> @test.sql

PATH
--------
SQLPATH1

```

SQLPATHで指定された最初のディレクトリのスクリプトが実行されました。

/home/sqlpath1には更にサブ・ディレクトリが作成されていて、その中にもtest.sqlを配置してみました。

```
$ rm /home/oracle/sqlpath1/test.sql
$ sqlplus scott/tiger
SQL> @test.sql

PATH
--------
SQLPATH2

$ rm /home/oracle/sqlpath2/test.sql
$ sqlplus scott/tiger
SQL> @test.sql
SP2-0310: ファイル"test.sql"をオープンできません。

```

SQLPATHで指定されたディレクトリのサブ・ディレクトリは検索しないようです。

上記の検証のように、環境変数ORACLE_PATHとSQLPATHを両方指定した場合のスクリプト実行パスは、
ORACLE_PATH → カレント・ディレクトリ　→ SQLPATHで指定された順番に検索され、発見されたスクリプトが実行されることがわかりました。
ただし、SQLPATHのサブ・ディレクトリまでは検索しないことがわかりました。