2015/12/01

SQL*PlusのクールなJava実装(SQLcl)を試してみる

本記事は JPOUG Advent Calendar 2015 の1日目です。

Oracle Database を管理する上では欠かせない SQL*Plus の Java 実装が SQL Developer 4.1 Early Adopter から利用可能になりましたので試してみた感想になります。

new Command Line Interface

SQL Developer プロダクトマネージャの Jeff Smith さんは精力的にブログ記事やツイートをされていますが、先日とても気になる記事を見かけました。

この記事と資料は 2015/2/15 の Webinar 向けのもののようですが、どちらも非常に見応えがありました。 上記記事を参考にした導入手順や新しい機能については mon_tu さんが Qiita にて紹介されています。 ここでは動画や関連資料を見て、手元で試してみて気づいた事をまとめます。

環境(Environment)

2015/3/9 に Java 8 対応の SQL Developer 4.1 EA2(4.1.0.18.37) が出ました。(2015/11/30 時点で SQL Developer の最新版は 4.1.2 です)

試した環境は以下になります。
  • クライアント
    • Oracle SQL Developer 4.1.2 (4.1.2.20.64)
    • Oracle SQL Developer Command Line - SQLcl - Early Adopter 4.2.0.15.296.0594
    • Oracle Instant Client 12.1.0.2.0 Basic Package
    • Java SE 8u66
    • OS X(10.11) / Oracle Linux 6.7 / Windows 10
  • サーバ
    • Oracle Database 12.1.0.2.0
リリース版 SQL Developer に同梱されている SQLcl は以下の場所にあります。本記事ではこれらをシェルのコマンド実行パスや alias なりに追加した前提で説明します。
OS X:    SQLDeveloper.app/Contents/Resources/sqldeveloper/sqldeveloper/bin/sql
Linux:   sqldeveloper/sqldeveloper/bin/sql
Windows: sqldeveloper/sqldeveloper/bin/sql.exe
またコンソール出力では各環境のプロンプトを以下のように分けて記載します。
OS X:    % sql
Linux:   $ sql
Windows: > sql.exe

接続(Connections)

従来の SQL*Plus ですと、tnsnames.ora などで指定した接続記述子など接続先の情報を付与しないとローカル接続として扱われてしまいますが、きちんとどこに接続するのか聞いてくれます。

% export JAVA_TOOL_OPTIONS='-Duser.language=en'

% ${path_to_sqldeveloper}/bin/sql
Picked up JAVA_TOOL_OPTIONS: -Duser.language=en

SQLcl: Release 4.1.0 Release Candidate on Mon Nov 30 16:09:39 2015

Copyright (c) 1982, 2015, Oracle.  All rights reserved.


Username? (''?) scott
Password? (**********?) *****
Database? (''?) ol64.vbox/pdb
Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP, Advanced Analytics
and Real Application Testing options

SQL> 
いきなり好感度大だったのですが、EA の SQLcl を試すとそうでは無くなっていました。
% ${path_to_sqlcl}/sql
Picked up JAVA_TOOL_OPTIONS: -Duser.language=en

SQLcl: Release 4.2.0.15.296.0549 RC on Mon Nov 30 16:51:27 2015

Copyright (c) 1982, 2015, Oracle.  All rights reserved.


Username? (''?) scott
Password? (**********?) *****
  USER          = scott
  URL           = jdbc:oracle:thin:@localhost:1521/orcl
  Error Message = ORA-01017: ユーザー名/パスワードが無効です。ログオンは拒否されました。
Username? (RETRYING) ('scott/*********'?) scott@ol64.vbox/pdb
Password? (RETRYING) (**********?) *****
Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP, Advanced Analytics
and Real Application Testing options

SQL>
接続先を指定せずにツールを起動する事はあまりないと思いますが少し残念かなーと思いました。/nolog で起動してから接続するようにしたほうがよいのかも知れません。

SQLcl は SQLPATH 環境変数や TNS_ADMIN 環境変数も見てくれますので、接続先には簡易接続のみならず接続記述子を指定しても繋げます。その他 TWO_TASK 環境変数や LDAP などでも指定できるようです。

ちなみに show jdbc とすると JDBC 接続で取得できる情報が表示されます。
SQL> show jdbc
-- Database Info --
Database Product Name: Oracle
Database Product Version: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP, Advanced Analytics
and Real Application Testing options
Database Major Version: 12
Database Minor Version: 1
-- Driver Info --
Driver Name: Oracle JDBC driver
Driver Version: 12.1.0.2.0
Driver Major Version: 12
Driver Minor Version: 1
Driver URL: jdbc:oracle:thin:@ol64.vbox/pdb
JDBC Thick ドライバを使いたい場合はライブラリパスを通した上で -oci オプションを使用して接続します。試した環境では Linux 以外はライブラリパスの設定が上手くいきませんでした。
  • JDBCの概要 - Oracle Database JDBC開発者ガイド 12cリリース1 (12.1)
$ export LD_LIBRARY_PATH=${path_to_instant_client}

$ sql -oci scott/tiger@pdb
Picked up JAVA_TOOL_OPTIONS: -Duser.language=en

SQLcl: Release 4.1.0 Release Candidate on Mon Nov 30 16:26:34 2015

Copyright (c) 1982, 2015, Oracle.  All rights reserved.


Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP, Advanced Analytics
and Real Application Testing options

SQL> show jdbc

-- Database Info --
Database Product Name: Oracle
Database Product Version: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP, Advanced Analytics
and Real Application Testing options
Database Major Version: 12
Database Minor Version: 1
-- Driver Info --
Driver Name: Oracle JDBC driver
Driver Version: 12.1.0.2.0
Driver Major Version: 12
Driver Minor Version: 1
Driver URL: jdbc:oracle:oci8:@(DESCRIPTION =    (ADDRESS = (PROTOCOL = TCP)(HOST = ol64.vbox)(PORT = 1521))    (CONNECT_DATA =      (SERVER = DEDICATED)      (SERVICE_NAME = pdb)    )  )
V$SESSION_CONNECT_INFO で OCI 経由の接続であることを確認できます。
SQL> select client_driver, client_oci_library, program from v$session natural join v$session_connect_info where sid = sys_context('USERENV', 'SID') fetch first 1 rows only;

CLIENT_DRIVER CLIENT_OCI_LIBRARY          PROGRAM
------------- --------------------------- ------------------------------
jdbcoci       Full Instant Client         java@ol64.vbox (TNS V1-V3)
なお JDBC Thick 接続だと V$SESSION.PROGRAM 列は java ですが、 Thin 接続だとそれと分かるようになっています。
SQL> select client_driver, client_oci_library, program from v$session natural join v$session_connect_info where sid = sys_context('USERENV', 'SID') fetch first 1 rows only;

CLIENT_DRIVER CLIENT_OCI_LIBRARY          PROGRAM
------------- --------------------------- ------------------------------
jdbcthin      Unknown                     SQL Command Line

補完(Object Name/Command Completion)

rlwrap などで辞書を用意しなくても、TAB キーによってコンテキストに応じたコマンドやオブジェクト名の補完が行われます。補完候補はカーソル行の上に表示されます。

SQL> s<TAB>
SQL> S -- 大文字になって候補が出る
SAVEPOINT   SELECT      SET         STARTUP

SQL> Se<TAB>
SQL> SE -- 大文字になって候補が出る
SELECT      SET

SQL> SEl<TAB>
SQL> SELECT -- 大文字になって補完される
オブジェクト名については、SELECT 以外の INSERT/UPDATE/DELETE などでは補完されませんでした。ディクショナリ等は補完対象外のようです。(たくさん出てきても困りますが)
SQL> select * from <TAB>
BONUS      DEPT       EMP        SALGRADE  -- テーブル名の候補が出る

SQL> select e<TAB> from emp
SQL> select E from emp -- テーブルを確定していると対象となる列の候補が出る
EMPNO   ENAME

SQL> select l<TAB> from emp,dept
SQL> select LOC from emp,dept    -- 列名(DEPT.LOC)が補完される

コマンドライン編集(User friendly Editing)

rlwrap を用いなくても、CTRL-P CTRL-N などでコマンド履歴を遡ったり、複数行における SQLcl バッファのカーソル移動が CTRL-F CTRL-B などでも可能になります。

EDIT のヘルプを見ると _EDITOR 事前定義変数に inline と言うものがあることが分かります。CTRL-W CTRL-S は複数行扱う場合は覚えておくと便利そうです。
SQL> help edit

EDIT
 ---------

 Invokes an operation system text editor on the contents of the
specified file or on the contents of the SQL buffer.

 ED[IT] [file_name[.ext]]

The DEFINE variable _EDITOR can be used to set the editor to use

In SQLcl, _EDITOR can be set to "inline". This will set the editor to
be the SQLcl editor.  This supports the following shortcuts
        ^R - Run the current buffer
        ^W - Go to top of buffer
        ^S - Go to bottom of buffer
        ^A - Go to start of line
        ^E - Go to end of line
ただ、zsh シェルのような感覚で操作しようとすると、まだまだ謎の動きをすることがありますし、単語単位のカーソル移動、キルリングへの追加などインタラクティブシェルで出来ていたことと同じ程度の操作性はまだ得られないようです。今後に期待です。

ここから SQLcl の新しいコマンドをヘルプをベースに紹介します。

ALIAS

シェルのエイリアスと同じように、SQL 文、SQL*Plus コマンドに別名をつけて手軽に呼び出せます。

SQL> help alias

ALIAS
------

alias [<name>=<SQL statement>;| LOAD [<filename>]|SAVE [<filename>] | LIST [NAME] | DROP ]

Alias is a command which allows you to save a sql, plsql or sqlplus script and assign it a shortcut command.
        "alias" - print a list of aliases
        "alias list <aliasName>" - list the contents of the alias
        "alias <aliasName>=select :one from dual;" - Simple alias command
        Define an alias simply by using the alias keyword followed by a single identifier
        name followed by an '='. Anything after the '=' will be used as the alias contents.
        For example, if it is SQL, it will be terminated by a ';'. If it is PLSQL, it will
        be terminated by a '/'

Examples:
--------
1. SQL Example with Binds

        SQL> alias fred=select :one from dual;
        In this example, a bind variable can be set up in the alias.
        Running the alias is done like this below with any parameters
        to the alias being bound to a bind variable by SQLcl

        SQL> fred 1
        Command=fred
        :ONE
        ----
        >

2. PL/SQL example
        SQL> alias db= begin dbms_output.put_line('hi'); end;
        >  /
        Here the block of PLSQL is terminated by the '/' on a separate
        line at which point it is accepted as a new alias.

        SQL> db
        Command=db
        PL/SQL procedure successfully completed.
        hi

Summary
-------
        alias ..=.. is terminated by ';'
        alias ..=begin or ..=declare is terminated by a / on a newline
        alias on its own gives a list of existing aliases.
設定は XML ファイルとして保存されるようです。
  • OS X, Linux: $HOME/.sqlcl/aliases.xml
  • Windows: %APPDATA%\sqlcl\aliases.xml

APEX

APEX アプリケーションの一覧を表示するコマンド。APEX は不勉強でよく分かっていません。。。

SQL> help apex

APEX
---------

apex - Lists Application Express Applications
apex export <app id> - Exports the application which could be combined with spool for writing to a file

BRIDGE

データベースリンクを定義せずに SQLcl のセッションにおいて異なる2つのデータベース接続をブリッジする機能。 OpenSSH-5.7 で追加された scp コマンドの -3 オプションみたいな感じでしょうか。

SQL> help bridge

BRIDGE
----

Used mainly to script data move between two connections
It also includes functionality to dynamically create Oracle tables which "fit" the data being received through JDBC
The following functionality is available
A) query tables in other connections
B) query tables in multiple connections in the same statement
C) insert data from one connection into another
D) create a table and insert data into it from another connection

Syntax:
BRIDGE <targetTableName> as "<jdbcURL>"(<sqlQuery>);

Example:
BRIDGE table1 as "dbc:oracle:thin:scott/tiger@localhost:1521/orcl"(select * from dept);
In the above example table1 is created in the current connection. Table1 is defined using the metadata from the query run against the database connection defined in the statement.

The JDBC URL specified has to conform to the format defined by the driver.

BRIDGE new_table   as "jdbc:oracle:thin:[USER/PASSWORD]@[HOST][:PORT]:SID"(select * from scott.emp);
BRIDGE new_table   as "jdbc:oracle:thin:[USER/PASSWORD]@//[HOST][:PORT]/SERVICE"(select * from scott.dept);

CD

シェルの cd コマンドと同じように、カレントの作業ディレクトリを変更するコマンド。地味に便利。

SQL> help cd

CD
---

 Changes path to look for script at after startup.
(show SQLPATH shows the full search path currently:
- CD current directory setting set by last cd command
- baseURL (url for subscripts)
- topURL (top most url when starting script)
- Last Node opened (i.e. file in worksheet)
- Where last script started
- Last opened on sqlcl path related file chooser
- SQLPATH setting
- "." if in SQLDeveloper UI (included in SQLPATH in command line (sdsql))
).

CTAS, DDL

DDL コマンドは DBMS_METADATA.GET_DDL を手軽にしたようなもの、CTAS は列定義やセグメントサイズの変更時に使う事のある Create as select (CTAS) 文を出力するコマンド。

SQL> help ddl

DDL
---

DDL generates the code to reconstruct the object listed.  Use the type option
for materialized views. Use the save options to save the DDL to a file.

DDL [<object_name> [<type>] [SAVE <filename>]] |
SQL> ddl dept

  CREATE TABLE "SCOTT"."DEPT"
   (    "DEPTNO" NUMBER(2,0),
        "DNAME" VARCHAR2(14),
        "LOC" VARCHAR2(13),
         CONSTRAINT "PK_DEPT" PRIMARY KEY ("DEPTNO")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS"  ENABLE
   ) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
 NOCOMPRESS LOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS" ;
SQL> help ctas

CTAS
 ctas table new_table
Uses DBMS_METADATA to extract the DDL for the existing table
 Then modifies that into a create table as select * from
SQL> ctas dept new_dept

  CREATE TABLE "SCOTT"."NEW_DEPT"
   (    "DEPTNO",
        "DNAME",
        "LOC",
         CONSTRAINT "PK_DEPT" PRIMARY KEY ("DEPTNO")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS"  ENABLE
   ) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
 NOCOMPRESS LOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS"
 as
select * from DEPT

FORMAT

SQLcl バッファや指定したファイルの SQL 文をフォーマットするコマンド。SQL Developer ではそのような機能がありましたが、それをコマンドラインでも使えるようになったのは便利かも知れません。

SQL> help format

FORMAT
---------

FORMAT BUFFER - formats the script in the SQLcl Buffer
FORMAT RULES <filename - Loads SQLDeveloper Formatter rules file to formatter.
FORMAT FILE <input_file> <output_file>

Format used is default or for SQLcl can be chosen by setting an environmental variable
pointing to a SQLDeveloper export (.xml) of formatter options.
The variable is called SQLFORMATPATH
In SQLDeveloper the format options are the default chosen in the preferences.
SQL> select
  2  1
  3  from dual;


         1
----------
         1

SQL> format buffer

  1* SELECT 1 FROM dual

HISTORY

H[ISTORY] コマンドによってシェルのように実行したコマンドや SQL の履歴を表示して再利用できます。

SQL> help history

HISTORY
---------
history [<index> | FULL | USAGE | SCRIPT | HELP | TIME | CLEAR (SESSION)?]

SQL>history full
  1  select 1 from dual;
  2  select 2
  >  from dual;
  3  select 3 from dual
  >  where 1=1;

history>SQL usage
  1  (2) select 1 from dual;
  2  (11) select 2 from dual;
  3  (2) select 3 from dual where 1=1;

SQL>history script
 select 1 from dual;
 select 2 from dual;
 select 3 from dual where 1=1;

SQL>history 3
  1  select 3 from dual
  2* where 1=1;

SQL>his time
  1           clear
  2           cl bre
  3  (00.201) select 1 from dual
引数なしで実行すると番号付きで履歴一覧が表示されます。番号を指定するとカレントバッファにその履歴が反映されます。使用回数(USAGE)や処理時間(TIME)も記録されているようでそれらを一覧とともに表示することも出来ます。
SQL> history

  1  show user
  2  show jdbc
  3  show lines
  4  desc dept
  5  select client_driver, client_oci_library, program from v$session natural join v$session_connect_info where sid = sys_context('USERENV', 'SID') fetch first 1 rows only
  6  select e from EMP
  7  select * from emp
  8  select * FROM salgrade
  9  select * FROM SALGRADE
 10  show version

SQL> history 5

  1* select client_driver, client_oci_library, program from v$session natural join v$session_connect_info where sid = sys_context('USERENV', 'SID') fetch first 1 rows only
SQL> l

  1* select client_driver, client_oci_library, program from v$session natural join v$session_connect_info where sid = sys_context('USERENV', 'SID') fetch first 1 rows only

SQL> /


CLIENT_DRIVER CLIENT_OCI_LIBRARY          PROGRAM
------------- --------------------------- ------------------------------
jdbcthin      Unknown                     SQL Command Line
履歴は XML ファイルとして保存されるようです。
  • OS X, Linux: $HOME/.sqlcl/history.xml
  • Windows: %APPDATA%\sqlcl\history.xml

INFORMATION

SQL*Plus ではテーブル定義等の参照に DESC[RIBE] コマンドが用意されていますが、1画面に多くの SQL 実行結果を表示するように LINES[IZE] 変数を大きな値にしていると、その幅で出力されて悲しい思いをすることが多々ありました。

しかし SQLcl ではそのあたり分かっています。LINESIZE の初期値は端末の幅にセットされるようで、出力される列幅(COL[UMN])はディクショナリの定義をもとに設定されるようです。おそらく後述する SQLFORMAT による出力改善の一環だと思います。

SQL> show lines
linesize 318

SQL> desc dept


Name   Null     Type
------ -------- ------------
DEPTNO NOT NULL NUMBER(2)
DNAME           VARCHAR2(14)
LOC             VARCHAR2(13)
新しい INFO[RMATION] コマンドでは、テーブルに付随する索引、制約等も表示されます。
SQL> info dept
TABLE: DEPT
         LAST ANALYZED:2014-09-06 14:00:29.0
         ROWS         :4
         SAMPLE SIZE  :4
         INMEMORY     :DISABLED
         COMMENTS     :

Columns
NAME         DATA TYPE           NULL  DEFAULT    COMMENTS
*DEPTNO      NUMBER(2,0)         No
 DNAME       VARCHAR2(14 BYTE)   Yes
 LOC         VARCHAR2(13 BYTE)   Yes

Indexes
INDEX_NAME     UNIQUENESS  STATUS  FUNCIDX_STATUS  COLUMNS  COLUMN_EXPRESSION
SCOTT.PK_DEPT  UNIQUE      VALID                   DEPTNO


References
TABLE_NAME  CONSTRAINT_NAME  DELETE_RULE  STATUS   DEFERRABLE      VALIDATED  GENERATED
EMP         FK_DEPTNO        NO ACTION    ENABLED  NOT DEFERRABLE  VALIDATED  USER NAME
また info+ とすると統計情報の一部、下限、上限、密度、ヒストグラムの有無、が表示できます。
SQL> info+ dept
TABLE: DEPT
         LAST ANALYZED:2014-09-06 14:00:29.0
         ROWS         :4
         SAMPLE SIZE  :4
         INMEMORY     :DISABLED
         COMMENTS     :

Columns
NAME         DATA TYPE           NULL  DEFAULT    LOW_VALUE    HIGH_VALUE   NUM_DISTINCT   HISTOGRAM
*DEPTNO      NUMBER(2,0)         No                   10           40           4              NONE
 DNAME       VARCHAR2(14 BYTE)   Yes                  ACCOUNTING   SALES        4              NONE
 LOC         VARCHAR2(13 BYTE)   Yes                  BOSTON       NEW YORK     4              NONE

Indexes
INDEX_NAME     UNIQUENESS  STATUS  FUNCIDX_STATUS  COLUMNS  COLUMN_EXPRESSION
SCOTT.PK_DEPT  UNIQUE      VALID                   DEPTNO


References
TABLE_NAME  CONSTRAINT_NAME  DELETE_RULE  STATUS   DEFERRABLE      VALIDATED  GENERATED
EMP         FK_DEPTNO        NO ACTION    ENABLED  NOT DEFERRABLE  VALIDATED  USER NAME
SQL> help information

INFORMATION
--------

This command is like describe but with more details about the objects requested.

INFO[RMATION] {[schema.]object[@connect_identifier]}
INFO+ will show column statistics
INFO[RMATION] コマンドはその仕様上、プロシージャなどの表示には使用できないようですので、その場合は DESC[RIBE] コマンドと使い分けることになりそうですね。
  • COLUMN - SQL*Plusユーザーズ・ガイドおよびリファレンス リリース12.1
  • DESCRIBE - SQL*Plusユーザーズ・ガイドおよびリファレンス リリース12.1

LOAD

CSV ファイルからのデータローディングを行う為のコマンド。SQL*Loader よりもカジュアルに実行できそうですね。

SQL> help load

LOAD
-----

Loads a comma separated value (csv) file into a table.
The first row of the file must be a header row.  The columns in the header row must match the columns defined on the table.

The columns must be delimited by a comma and may optionally be enclosed in double quotes.
Lines can be terminated with standard line terminators for windows, unix or mac.
File must be encoded UTF8.

The load is processed with 50 rows per batch.
If AUTOCOMMIT is set in SQLCL, a commit is done every 10 batches.
The load is terminated if more than 50 errors are found.

LOAD [schema.]table_name[@db_link] file_name

NET

SQLcl で接続したネットワーク情報を表示、定義、削除するコマンド。

SQL> help net

NET
------

NET is a command which allows you to save a network details and assign it a shortcut command.
Available in SQLcl only -

net [<name>=<SQL statement>;| LOAD [<filename>]|SAVE [<filename>] | LIST [NAME] | DROP  ]

  "net" - print a list of net short cuts
  "net list <aliasName>" - list the contents of the short cut
  "net name=localhost:1521/XE;" simple net command
  "net drop name" - delete the short cut called name

net is single line terminated by newline
  net ..=.. is terminated by ';'
net on its own gives a list of existing short cuts.

controlled by
  set net on|off|readonly - default ON
     readonly means only do try to enter a net shortcut on successful connect command
  set noverwrite on|off|warn - default WARN
     net overwrite: warn prints a warning if an override would otherwise happen.
接続先ポート番号は省略できないようです。
SQL> net list
//localhost:1521/pdb
ol64.vbox:1521/pdb

SQL> net xe=ol64.vbox:1521/xe;
SQL> net list

//localhost:1521/pdb
ol64.vbox:1521/pdb
xe
SQL> conn scott/tiger@xe

Connected

SQL> show jdbc

-- Database Info --
Database Product Name: Oracle
Database Product Version: Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
Database Major Version: 11
Database Minor Version: 2
-- Driver Info --
Driver Name: Oracle JDBC driver
Driver Version: 12.1.0.2.0
Driver Major Version: 12
Driver Minor Version: 1
Driver URL: jdbc:oracle:thin:@ol64.vbox:1521/xe
設定は XML ファイルとして保存されるようです。
  • OS X, Linux: $HOME/.sqlcl/netEntries.xml
  • Windows: %APPDATA%\sdsql\netEntries.xml

OERR

oerr ユーティリティ相当のコマンド。

SQL> help oerr

OERR
----
Usage: oerr facility error

Facility is identified by the prefix string in the error message.
For example, if you get ORA-7300, "ora" is the facility and "7300"
is the error.  So you should type "oerr ora 7300".

If you get tns-12533, type "oerr tns 12533", and so on.
(ora and tns facilities only)
SQL> oerr ora 600


00600. 00000 -  "internal error code, arguments: [%s], [%s], [%s], [%s], [%s], [%s], [%s], [%s], [%s], [%s], [%s], [%s]"
*Cause:    This is the generic internal error number for Oracle program
           exceptions. It indicates that a process has encountered a low-level,
           unexpected condition. The first argument is the internal message
           number. This argument and the database version number are critical in
           identifying the root cause and the potential impact to your system.

REPEAT

watch(1) コマンドのように任意の SQL を指定した間隔で実行することが出来ます。

SQL> help repeat

repeat <iterations> <sleep>
        Repeats the current sql in the buffer the specified times with sleep intervals
        Maximum sleep is 120s
工夫次第で Oracle Database のサポートツール oratop の SQL モードで表示されている様なことが出来そうですね。v$session_longops を追跡するのは便利そうです。

REST

Oracle REST Data Services のエクスポートを手軽にするツールのようですが不勉強なので分かりません。。。

SQL> help rest

REST
------

REST allows to export ORDS 3.X services.

             REST export                  -      All modules
             REST export <module_name>    -      Export a specific module
             REST export <module_prefix>  -      Export a specific module related to the given prefix
             REST modules                 -      List the available modules
             REST privileges              -      List the existing privileges
             REST schemas                 -      List the available schemas

PRECOMMAND, POSTCOMMAND

SQL の実行前後に実行したいコマンド(複数可、外部ファイル可)を SET パラメータの PRECOMMAND, POSTCOMMAND として指定できます。 性能検証かなにかで削除、実行、計測、を頻繁に繰り返す際に使えるかも知れませんが、それを単一の外部ファイルにして実行したときとの利便性の違いがまだ見出せません。。。

SQLFORMAT

SQL Developer ではスクリプトを実行する際にヒント句の様なコメントを与えることでさまざまなフォーマットで出力できるようです。

これと同じ事が SQLFORMAT オプションで指定できるようになりました。
SQL> help set sqlformat

SET SQLFORMAT
  SET SQLFORMAT { csv,html,xml,json,ansiconsole,insert,loader,fixed,default}
SQL> select * from dept;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON
SQL> set sqlformat csv
SQL> /

"DEPTNO","DNAME","LOC"
10,"ACCOUNTING","NEW YORK"
20,"RESEARCH","DALLAS"
30,"SALES","CHICAGO"
40,"OPERATIONS","BOSTON"
SQL> set sqlformat html
SQL> /

<!DOCTYPE html>
<html>

(省略)

<table><thead><tr>      <th>DEPTNO</th>
        <th>DNAME</th>
        <th>LOC</th>
</tr></thead>
<tbody id="data">

        <tr>
<td align="right">10</td>
<td>ACCOUNTING</td>
<td>NEW YORK</td>
        </tr>
        <tr>
<td align="right">20</td>
<td>RESEARCH</td>
<td>DALLAS</td>
        </tr>

(省略)

</tbody></table><!-- SQL:
null--></body></html>
SQL> set sqlformat insert
SQL> /

REM INSERTING into dept
SET DEFINE OFF;
Insert into "dept" (DEPTNO,DNAME,LOC) values (10,'ACCOUNTING','NEW YORK');
Insert into "dept" (DEPTNO,DNAME,LOC) values (20,'RESEARCH','DALLAS');
Insert into "dept" (DEPTNO,DNAME,LOC) values (30,'SALES','CHICAGO');
Insert into "dept" (DEPTNO,DNAME,LOC) values (40,'OPERATIONS','BOSTON');
SQL> set sqlformat json
SQL> /

{"items":[
{"deptno":10,"dname":"ACCOUNTING","loc":"NEW YORK"},{"deptno":20,"dname":"RESEARCH","loc":"DALLAS"},{"deptno":30,"dname":"SALES","loc":"CHICAGO"},{"deptno":40,"dname":"OPERATIONS","loc":"BOSTON"},{}]}
SQL> set sqlformat loader
SQL> /

 10|"ACCOUNTING"|"NEW YORK"|
 20|"RESEARCH"|"DALLAS"|
 30|"SALES"|"CHICAGO"|
 40|"OPERATIONS"|"BOSTON"|
SQL> set sqlformat text
SQL> /

"DEPTNO"null"DNAME"null"LOC"
10null"ACCOUNTING"null"NEW YORK"
20null"RESEARCH"null"DALLAS"
30null"SALES"null"CHICAGO"
40null"OPERATIONS"null"BOSTON"
SQL> set sqlformat xml
SQL> /

<?xml version='1.0'  encoding='UTF8' ?>
<RESULTS>
        <ROW>
                <COLUMN NAME="DEPTNO"><![CDATA[10]]></COLUMN>
                <COLUMN NAME="DNAME"><![CDATA[ACCOUNTING]]></COLUMN>
                <COLUMN NAME="LOC"><![CDATA[NEW YORK]]></COLUMN>
        </ROW>

(省略)

</RESULTS>
同一 SQL の結果をさまざまな形式で出力できます。CSVJSON などは意外に使えるかも知れません。

ここまでは予測できるフォーマットですが、端末好きには気になる ANSICONSOLE というオプションがあります。これは文字通り ANSI エスケープシーケンスを含んだ結果を出力します。

あらかじめ以下のフォーマットで定義されているシーケンスを利用することで、頑張ってエスケープシーケンスを書かなくても良くなっています。
@|シーケンス[,シーケンス] 文字列|@
ANSICONSOLE を有効にすると問合せ結果の列ヘッダが修飾されて必要最小限の幅になるのが好きです。
手元で試したい方は以下の gist を使ってみてください。 カラフルに 256 色を使いたい場合は従来?通りエスケープシーケンスを直書きする必要がありますね。

SSHTUNNEL

SQLcl から SSH 接続のトンネルを設定するコマンド。ユースケースとしては Oracle Cloud への接続になるのでしょうか。(使ったことないですが)

SQL> help sshtunnel

SSHTUNNEL
---------

Creates a tunnel using standard ssh options
such as port forwarding like option -L of the given port on the local host
will be forwarded to the given remote host and port on the remote side. It also supports
identity files, using the ssh -i option
If passwords are required, they will be prompted for.

SSHTUNNEL <username>@<hostname> -i <identity_file> [-L localPort:Remotehost:RemotePort]

Options

-L localPort:Remotehost:Remoteport

Specifies that the given port (localhost) on the local (client) host is to be forwarded to
the given remote host (Remotehost) and port (Remoteport) on the remote side.  This works by
allocating a socket to listen to port on the local side.
Whenever a connection is made to this port, the connection is forwarded over
the secure channel, and a connection is made to remote host & remoteport from
the remote machine.

-i identity_file
Selects a file from which the identity (private key) for public key authentication is read.
トンネルした接続を net で定義しておくと便利そうです。秘密鍵の指定は必須でパスフレーズはあってもなくても大丈夫です。Windows 環境でも使えました。
SQL> sshtunnel yoshikaw@seravee.local -i c:\app\id_rsa -L 8888:ol64.vbox:1521
SSH Tunnel connected
SQL> connect scott@localhost:8888/pdb

Password? (**********?) *****
Connected
ssh コマンドの Java 実装が使われていると思いますが、いわゆる $HOME/.ssh/config を使用した多段 SSH 前提だとどう組み合わせられるのかは調べていませんが、複数の sshtnnel を alias などにしておけば出来そうですね。

TNSPING

tnsping ユーティリティー相当のコマンド。

SQL> help tnsping

TNSPING
-------

 The TNSPING utility determines whether the listener for a service on an
 Oracle Net network can be reached successfully.
 If you can connect successfully from a client to a server (or a server
 to another server) using
 the TNSPING utility, then it displays an estimate of the round trip time
 (in milliseconds) it takes to reach the Oracle Net service.

 If it fails, then it displays a message describing the error that occurred.
 This enables you to see the network error that is occurring without the
 overhead of a database connection.

Use the following command to test connectivity:

  tnsping <address>

 Where the address is a TNS entry, or a JDBC connection String. For example:

  TNSPING DB@ACME.COM
 or
  TNSPING localhost:1521/orcl
簡易接続で指定する場合はポート番号は省略出来なさそうです。
SQL> tnsping ol64.vbox/pdb

 ping:-1ms
SQL> tnsping ol64.vbox:1521/pdb

 ping:17ms
ですが TNS エントリでの指定は設定がまずかったのか成功しませんでした。
SQL> !tnsping pdb

TNS Ping Utility for Linux: Version 12.1.0.2.0 - Production on 01-DEC-2015 00:41:41

Copyright (c) 1997, 2014, Oracle.  All rights reserved.

Used parameter files:
/u01/app/oracle/product/12.1.0/dbhome_1/network/admin/sqlnet.ora


Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = ol64.vbox)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = pdb)))
OK (10 msec)

SQL> tnsping pdb

 ping:-1ms

おわりに

SQLcl については3月頃にちまちまと調べて書き始めたのですが、次々と新機能が実装されて追いかけられずそのままにしていました。今回アドベントカレンダーのネタとして整理しようとしましたが、結局多くがコマンドヘルプと外部記事へのリンクのみになってしまいました。。。

SQL Developer では SQL*Plus のコマンドが幾つか使えましたが、それ(Script Engine)を切り出したらいいんじゃね?的な発想がいいですね! SQLcl は昨年 12月には紹介されていることに気づきました。

順調に改修を重ねてきたようで SQLcl で検索してみると海外の Oracle 系セミナーでの発表事例が増えてきました。 そういえば今年の Oracle DBA & Developer Day では開発ツールについてのセッションがあるので見逃せません。 SQLcl の GA が来年リリース予定の Oracle Database 12.2 に同梱されるか分かりませんが、開発や検証時に役立つ機能、作業が効率化できる機能が満載なのでこれからも積極的に使っていこうと思います。

2日目は Shinnosuke Akita さんです。楽しみですね!

0 件のコメント:

コメントを投稿