SQL*Plus の新機能を試す（Oracle Database 23c）

# SQL*Plus
SQL\*Plus（sqlplus コマンド）は、Oracle Database の標準CLIクライアントです。Oracle Database 23c に標準添付されている SQL\*Plus にはいくつかの新機能が提供されています。本記事では SQL\*Plus 23c の新機能について解説しています。公式な説明は[マニュアル SQL*Plus User's Guide and Reference 23c](https://docs.oracle.com/en/database/oracle/oracle-database/23/sqpug/changes-this-release-sqpug.html#GUID-18ED1F63-627C-4BE7-8CC1-2E74E4C860BA)に記載されています。本記事の内容は Oracle Database 23 Free を使って検証しています。

# SET ERRORDETAIL
SQL 文やコマンド実行がエラーになった場合、詳細を出力するかを決定します。この変数には以下の値を指定することができます。

|設定値|説明|備考|
|:---|:---|:---|
|OFF|エラーの詳細を出力しない|21c までの動作|
|ON|エラーの詳細を出力する|デフォルト値|
|VERBOSE|ヒントまで出力する||

以下の例ではERRORDETAILSの値を変更しながら、ALTER PLUGGABLE DATABASE 文が失敗する際にエラー・メッセージがどのように変化するかを示しています。

```SQL:
SQL> SET ERRORDETAILS OFF
SQL> ALTER PLUGGABLE DATABASE FREEPDB1 OPEN;
ALTER PLUGGABLE DATABASE FREEPDB1 OPEN
*
ERROR at line 1:
ORA-65019: pluggable database FREEPDB1 already open

SQL> SET ERRORDETAILS ON
SQL> ALTER PLUGGABLE DATABASE FREEPDB1 OPEN;
ALTER PLUGGABLE DATABASE FREEPDB1 OPEN
*
ERROR at line 1:
ORA-65019: pluggable database FREEPDB1 already open
Help: https://docs.oracle.com/error-help/db/ora-65019/

SQL> SET ERRORDETAILS VERBOSE
SQL> ALTER PLUGGABLE DATABASE FREEPDB1 OPEN;
ALTER PLUGGABLE DATABASE FREEPDB1 OPEN
*
ERROR at line 1:
ORA-65019: pluggable database FREEPDB1 already open
Help: https://docs.oracle.com/error-help/db/ora-65019/
Cause:  An attempt was made to open a pluggable database that was already
        opened.
Action: Check the OPEN_MODE column in V$PDBS view.
```

理由はわかりませんが、SHOW ALL コマンドでは一覧にこの変数は出力されません。

```SQL:
SQL> SHOW ALL
appinfo is OFF and set to "SQL*Plus"
arraysize 15
autocommit OFF
autoprint OFF
autorecovery OFF
autotrace OFF
blockterminator "." (hex 2e)
btitle OFF and is the first few characters of the next SELECT statement
cmdsep OFF
colinvisible OFF
coljson OFF
colsep " "
compatibility version NATIVE
concat "." (hex 2e)
copycommit 0
COPYTYPECHECK is ON
define "&" (hex 26)
describe ANNOTATION OFF DEPTH 1 LINENUM OFF INDENT ON
echo OFF
editfile "afiedt.buf"
embedded OFF
errorlogging is OFF
escape OFF
escchar OFF
exitcommit ON
FEEDBACK ON for 6 or more rows SQL_ID OFF
flagger OFF
flush ON
...

```


# PING
PING コマンドは SQL\*Plus からネットワーク上の Oracle Database インスタンスに対して接続性をチェックします。通常、この調査は OS のプロンプトから tnsping コマンドを実行しますが、SQL\*Plus から tnsping コマンド相当の操作を行うことができます。

　パラメータを省略して PING だけ実行すると現在接続の確認を行います。残念ながらヘルプ・メッセージは用意されていません。

```SQL:
SQL> HELP PING
SP2-0172: No HELP matching this topic was found.
Help: https://docs.oracle.com/error-help/db/sp2-0172/
SQL> PING
OK (0.081 msec)
```

PINGコマンドにリモート・インスタンスへの接続文字列を指定することもできます。ただしサービスの存在チェックまでは実行していないため、存在しないサービス名を指定しても成功とみなされます。tnsping コマンドと同じ仕様です。

```SQL:
SQL> PING dbsrv1:1521/service1
Attempting to contact: (DESCRIPTION=(CONNECT_DATA=(SERVICE_NAME=service1))(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.1.200)(PORT=1521)))
Ok (0.572 msec)

SQL> PING dbsrv1:1522/service2
Attempting to contact: (DESCRIPTION=(CONNECT_DATA=(SERVICE_NAME=service2))(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.1.200)(PORT=1522)))
SP2-1683: Ping failed with error TNS-12541.
Help: https://docs.oracle.com/error-help/db/sp2-1683/
```


# OERR
Oracle Database 標準の OS コマンド oerr と同様の動作を SQL\*Plus 上で実行できます。
oerr コマンドと同じようにカテゴリーとエラー番号を指定します。出力結果は SET ERRORDETAILS の値に依存しません。

```SQL:
SQL> OERR ORA 1555
Message: "snapshot too old: rollback segment number %s with name \"%s\" too small"
Help: https://docs.oracle.com/error-help/db/ora-01555/
Cause: rollback records needed by a reader for consistent read are
           overwritten by other writers
Action: If in Automatic Undo Management mode, increase undo_retention
        setting. Otherwise, use larger rollback segments
```

カテゴリー ORA 以外の値を指定すると、以下のエラーが発生します。

```SQL:
SQL> OERR TNS 12154
SP2-0160: unable to open "/opt/oracle/product/23c/dbhomeFree//network_src/mesg/tnsus.msg"
Help: https://docs.oracle.com/error-help/db/sp2-0160/
```

このため、\\$ORACLE_HOME/network ディレクトリに対してシンボリック・リンク \$ORACLE_HOME/network_src を作成します。

```shell:
$ cd $ORACLE_HOME/
$ ln -s network network_src
$ sqlplus / as sysdba
SQL*Plus: Release 23.0.0.0.0 - Production on Tue Oct 24 13:23:36 2023
...
SQL> OERR TNS 12154
Message: "Cannot connect to database. Could not find alias %s in %s."
Help: https://docs.oracle.com/error-help/db/tns-12154/
Cause:  A connection to a database or other service was requested using a
        connection alias but the alias specified could not be resolved into
        a connect descriptor using one of the configured naming methods.
Action: Do the following:
        - Check for mistakes in the connection string that you used.
...
```

# DESCRIBE
テーブル定義を出力する DESCRIBE コマンドの出力に ANNOTATION の情報が追加されます。デフォルトでは従来と同じ出力ですが、「SET DESCRIBE ANNOTATION ON」コマンドを実行することで ANNOTATION の情報が出力されるようになります。以下の例ではテーブル DATA1 の作成時に ANNOTATION を指定しています。SET DESCRIBE ANNOTATION ON コマンドの実行により、ANNOTATION 情報が追加されることがわかります。

```SQL:
SQL> CREATE TABLE data1(c1 number ANNOTATIONS (colann1 'colval1'))
  2   ANNOTATIONS (tabann1 'tabval1');

Table created.

SQL> DESCRIBE data1
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 C1                                                 NUMBER

SQL> SET DESCRIBE ANNOTATION ON
SQL> DESCRIBE data1
Table Annotations (Key: Value)
------------------------------------------------------------------------------------------------------------------------
TABANN1: tabval1

 Name                                    Null?    Type                           Annotations (Key: Value)
 --------------------------------------- -------- ------------------------------ ---------------------------------------
 C1                                               NUMBER                         COLANN1: colval1
```

# ARGUMENT
スクリプトのパラメーターが不足している場合にプロンプトを表示し、変数に値を指定することができます。PROMPT 句には表示するプロンプトを、DEFAULT は入力が無かった場合のデフォルト値を指定します。

```SQL:
SQL> ARGUMENT 1 PROMPT "Enter Arg1:" DEFAULT 'value1'
SQL> DEFINE arg1='&1'
Enter Arg1:test1
SQL> SELECT '&arg1' FROM DUAL;
old   1: SELECT '&arg1' FROM DUAL
new   1: SELECT 'test1' FROM DUAL

'TEST
-----
test1
```

Author: Noriyoshi Shinoda / Date: October 24, 2023