2025年1月10日金曜日

PL/SQLのコードをOracle SQL Developer Extension for VSCodeで開発する

オラクルはVSCodeの拡張機能として、2024年1月にOracle SQL Developer Extension for VSCodeをリリースしています。VSCode向けの、生成AIによるコード補完やコード生成を行う拡張機能が一般に利用可能になったこともあり、それらの機能を活用するためにPL/SQLのコードをVSCodeで開発する方法を確認してみます。

確認作業はOracleの開発ツールのプロダクト・マネージャのJeff Smithさんによる、以下のブログ記事に沿って行います。

PL/SQL debugger now available in SQL Developer for VS Code
https://www.thatjeffsmith.com/archive/2024/10/pl-sql-debugger-now-available-in-sql-developer-for-vs-code/

PLSQLを実行するデータベースとして、ローカルPCのコンテナで動作しているOracle Database 23ai Freeを使います。Autonomous DatabaseはパッケージDBMS_DEBUG_JDWPをサポートしていないため、Oracle SQL Developer Extension for VSCodeのPL/SQLデバッガは使えません。Oracle SQL Developerに含まれるデバッガであれば、Autonomous Databaseで利用できます。

Debugging your PL/SQL in Oracle Autonomous Databases
https://www.thatjeffsmith.com/archive/2021/02/debugging-your-pl-sql-in-oracle-autonomous-databases/

以下より実施した確認作業を紹介します。

Jeff Smithさんの記事に従って、以下のDEBUGGING_DEBUGGER.plsを作業に使用します。

オリジナルのコードはデータベースにサンプル・スキーマHRがインストールされていることを前提としたコードになっています。

本記事は、Oracle APEXのアプリケーションから呼び出すプロシージャ、ファンクションおよびパッケージを、VSCodeで作成することを想定しています。データベースでの作業は、APEXのワークスペース・スキーマに接続して作業します。そのため、スキーマHRが存在することを前提にできません。

代わりにAPEXのサンプル・データセットHRデータを、APEXのワークスペースにインストールします。

作業対象のデータベースのAPEXのワークスペースにサインインし、SQLワークショップユーティリティサンプル・データセットを開きます。


サンプル・データセットに含まれるHRデータインストールをクリックします。


言語英語以外に選択肢はなく、スキーマはワークスペースのデフォルト・パーシング・スキーマが選ばれます。

通常は変更不要なので、そのままへ進みます。


データセットのインストールをクリックします。APEXのサンプル・データセットのHRデータは、オラクルがGitHubで公開しているHRサンプル・スキーマとほぼ同じですが、表名が競合しないように、表名の接頭辞としてOEHR_が付加されています。


サンプル・データセットがインストールされます。

アプリケーションは作成せず、終了をクリックします。


以上で作業に使用するスキーマの準備ができました。前掲のDEBUGGING_DEBUGGER.plsは、表HR.EMPLOYEES、HR.JOBSの代わりにOEHR_EMPLOYEES、OEHR_JOBSを参照するように変更済みです。

VSCodeを使う作業に移ります。

必ずしも必要な作業ではありませんが、PL/SQLコードを保持するリポジトリをGitHubに作成しました。リポジトリ名はdatabase-scriptsとしています。


ローカルの環境にクローンします。

git clone https://github.com/<username>/database-scripts.git

% git clone https://github.com/ujnak/database-scripts.git

Cloning into 'database-scripts'...

remote: Enumerating objects: 4, done.

remote: Counting objects: 100% (4/4), done.

remote: Compressing objects: 100% (4/4), done.

remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)

Receiving objects: 100% (4/4), done.

% 


VSCodeを起動します。Oracle SQL Developer Extension for VSCodeが未インストールであれば、拡張機能からインストールしておきます。


作成したディレクトリ(本記事ではdatabase-scripts)を開き、フォルダdebugger-testを作成します。その下にファイルDEBUGGING_DEBUGGER.plsを作成します。


ローカルのコンテナとして動作しているOracle Database 23ai Freeの環境に接続して作業を行います。こちらの記事の手順で作成した環境です。

おそらく、VSCodeとOracle Databaseの間でファイアウォールなどがなく、VSCodeからOracle Database(SQL*Netによる接続)、およびOracle DatabaseからVSCode(JDWP - Java Debug Wire Protocolによる接続)へTCPで接続可能なネットワーク環境であれば、同様に動作すると思われます。

拡張機能のSQL Developerを開いて、オラクル・データベースへの接続作成します。


PL/SQLの開発作業は、APEXのワークスペース・スキーマで接続して実施します。PL/SQLデバッガを実行するために、ワークスペース・スキーマへの権限の割り当てと、JDWPによる接続を許可するためのネットワークACLの作成SYSで行なう必要があります。

そのため、SYSによる接続を作成します。

接続名local-23ai-freepdb1-sysとしました。ロールSYSDBAユーザー名sysパスワードにはsysのパスワードを設定します。データベースへの接続時にパスワードの入力を省略するため、パスワードの保存チェックしておきます。

接続タイプ基本ホスト名localhostポート1521タイプサービス名サービス名freepdb1になります。

上記の設定でテストを行い、問題がなければ保存します。


パスワードの保存未チェックのときは、データベースへの接続を要求したときに、以下のようにパスワードの入力が求められます。


APEXのワークスペース・スキーマにPL/SQLデバッガを実行する権限を与えます。以下のコマンドを実行します。

grant debug connect session to <ワークスペース・スキーマ名>;

作成済みの接続local-23ai-freepdb1-sysをクリックしてデータベースに接続します。その接続のSQLワークシートを開きます。SQLワークシートに上記のコマンドを記述し、ボタン文の実行をクリックします。

SQLワークシート上でカーソルが割り当たっている文が実行されます。スクリプト出力Grantが正常に実行されました。と表示されたらコマンドの実行は完了です。


APEXのワークスペース・スキーマによる接続を作成します。

接続名local-23ai-freepdb1-wksp_apexdevとします。

接続先のデータベースは先ほどのSYSと同じです。接続ユーザーはAPEXのワークスペース・スキーマを指定します。APEXのワークスペース・スキーマはパスワードが未設定であったり、CREATE SESSIONまたはCONNECTロールが未割り当ての場合があります。あらかじめ、APEXのワークスペース・スキーマを接続ユーザーとして、データベースに接続できるかどうか確認し、不足があればAPEXのワークスペース・スキーマに追加で権限やロールを割り当てておきます。

今回の作業では、APEXのワークスペース・スキーマ(以下の設定ではユーザー名)としてWKSP_APEXDEVを指定しています。このスキーマは、サンプル・データセットHRデータをインストールしたスキーマです。


作成した接続local-23ai-freepdb1-wksp_apexdevをクリックし、データベースに接続します。

作成済みのファイルDEBUGGING_DEBUGGER.plsを開きます。タイプarray_jobs、プロシージャdebugging_step_infoおよびdebugging_debuggerの3つを作成するため、これらの行を全て選択します。


スクリプトを表示している画面の右上にあるギアのアイコン赤いアクセントが付いている方のアイコン)をクリックし、選択したスクリプトをデバッグ用にコンパイルします。スクリプトを実行する接続先の選択を求められたときは、APEXのワークスペース・スキーマへの接続であるlocal-23ai-freepdb1-wksp_apexdevを選択します。


スクリプトDEBUGGING_DEBUGGER.plsを実行すると、タイプARRAY_JOBS、プロシージャDEBUGGING_STEP_INTOおよびDEBUGGING_DEBUGGERが作成されます。

今までの作業で開いているファイルおよびSQLワークシートは、以降の作業では使用しません。一旦、これらのファイルをすべて閉じます。

接続local-23ai-freepdb1-wksp_apexdev(ローカルのコンテナで動作しているOracle Database 23ai FreeのPDB、FREEPDB1のスキーマWKSP_APEXDEV)にプロシージャDEBUGGING_DEBUGGERが作成されています。

このプロシージャを開きます。


プロシージャDEBUGGING_DEBUGGERが開いたら、右上の実行ボタンのデバッグを実行します。


デバッグを開始する画面が開きます。処理が実行される接続名(今回はlocal-23ai-freepdb1-wksp_apexdev)、ターゲット(今回はDEBUGGING_DEBUGGER)、それとプロシージャDEBUGGING_DEBUGGERに渡すパラメータXへの入力値が求められます。

デバッグをクリックするとデータベース・サーバーはVSCodeへ、JDWPによる接続を試みます。そのため、あらかじめネットワークACLによる許可が必要です。

ACLの表示をクリックすると、実行すべきコマンドが表示されます。


ACLの表示をクリックすると、IPアドレスの選択を求められます。データベース・サーバーから作業に使用しているVSCodeへの接続するためのIPアドレスになります。ホストとコンテナはネットワークが異なるため、ローカルホストの指定である127.0.0.1では接続できません。127.0.0.1でない方の接続先(以下の例では192.168.10.146)を選択します。


デバッグを実行するために必要なネットワークACLを追加するコードが表示されます。Copyをクリックし、クリップボードに保存します。


データベースにSYSで接続し、クリップボードにコピーしたネットワークACLを追加するコードを実行します。

接続local-23ai-freepdb1-sysを開き、その接続でSQLワークシートを開きます。SQLワークシートにクリップボードからネットワークACLを追加するコードをペーストし、ペーストした文を実行します。


スクリプト出力PL/SQLプロシージャが正常に完了しました。と表示されれば、ネットワークACLの追加は完了です。


接続local-23ai-freepdb1-sysを閉じます。ネットワークACLが書かれているSQLワークシートも不要なので、タブを閉じておきます。保存は不要です。


DEBUGGING_DEBUGGER.runの画面に戻ります。すでに閉じている場合は、再度プロシージャDEBUGGING_DEBUGGERをデバッグ実行します。

パラメータX入力値として5を設定します。

デバッグを実行する前にPL/SQLの表示をクリックし、プロシージャDEBUGGING_DEBUGGERのデバッグを行なうために実行されるPL/SQLコードを確認します。


プロシージャDEBUGGING_DEBUGGERを呼び出すコードとして、以下が表示されます。
-- runner for WKSP_APEXDEV.DEBUGGING_DEBUGGER
SET SERVEROUTPUT ON
DECLARE
  X NUMBER;
BEGIN
  X := 5;
  WKSP_APEXDEV.DEBUGGING_DEBUGGER(
    X => X);
  -- Rollback;
end;

SQLコードが確認できたら不要なタブなので、タブを閉じておきます。保存は不要です。


デバッグをクリックします。JDWPの接続先の選択を求められたときは、ネットワークACLとして追加した接続先を選択します。


プロシージャDEBUGGING_DEBUGGERに引数X5を与えた実行結果が、スクリプト出力に表示されます。

ブレークポイントが設定されていないため、デバッグ実行でもスクリプトの最後まで処理が実行されます。


プロシージャDEBUGGING_DEBUGGER.plsのタブに移り、ブレークポイントを設定します。

行番号の左隣をクリックすると赤いマークが付き、ブレークポイントとして設定されます。


タブDEBUGGING_DEBUGGER.runに移り、再度デバッグをクリックします。


今度は設定したブレークポイントの位置で、PL/SQLの処理が一時停止します。

左側には、一時停止した時点での変数の値、ウォッチ式コールスタックといったスクリプトの実行状況が表示されます。


画面上部にデバッガの操作パネルが表示されています。

一番左の6個の点のアイコンを掴むと、操作パネルを移動できます。それ以外は左から、続行ステップ・オーバーステップ・インステップ・アウト再起動停止(または中断)になります。

この辺りの操作は、PL/SQLに限らず一般的なデバッガが持つ機能と同じです。


さて、以上でPL/SQLでのコードの記述やデバッグができるようになりました。

DEBUGGING_DEBUGGERのコードを修正します。以下の2行をプロシージャDEBUGGING_DEBUGGERの中間に挿入します。
 -- print how many lops we will do
 DBMS_OUTPUT.PUT_LINE('x is ' || x);
コードを挿入した後に、コンテキスト・メニューを表示してデバッグ用にコンパイルします。


プロシージャDEBUGGING_DEBUGGERをコンパイルした後、先ほどと同様にコードを実行します。プロシージャに挿入したコードが実行されていることが確認できます。


上記の変更はデータベースに保存されているプロシージャDEBUGGING_DEBUGGERを更新しています。記事の最初に作成したDEBUGGING_DEBUGGER.plsは更新されません。


パッケージ、プロシージャ、ファンクションといったPL/SQLで記述されたデータベースのオブジェクトは、コードがデータベースに保存されます。これらのコードをGitなどのリポジトリに保存する場合はファイルとして保存することになります。データベースに保存されるコードとGitに保存されるコードが自動的に同期されることはありません。

どのようなフローで同期させるかは、開発するアプリケーションの規模や開発チームの大きさで変わるように思います。アプリケーションや開発チームが小さければ、データベースに保存されているオブジェクトを直接編集し、編集が完了したコードをデータベースからGitに保存する方が手間も少なく開発速度も速いでしょう。反対にアプリケーションや開発チームが大きい場合は、勝手にデータベースのオブジェクトを変更されると大きな問題になりそうです。Gitなどを使って変更を管理し、テストやレビューを受けたコードよりデータベースのオブジェクトを作成し、直接データベースのオブジェクトを変更するのは禁止する、といった運用が妥当なように思います。

Oracle SQL Developer Extension for VSCodeのデバッガに関する設定は、設定デバッガにあります。


全てJDWPでの接続に関する項目です。


今回の記事は以上になります。

余談

最近話題のAI Code EditorとしてCursorがあります。CursorはVSCodeをフォークして作られていて、VSCode用の拡張機能をサポートしています。

Oracle APEXのアプリケーション開発に使うには、フロントエンドの開発では拡張機能のLive Serverが必要です。バックエンドではOracle SQL Developer Extension for VSCodeが必要です。

この両方の拡張機能がCursorで使えるか確認してみました。

Cursor自体には、Live ServerおよびOracle SQL Developer Extension for VSCodeの両方とも組み込めています。


Live Serverは問題なく動作します。


Oracle SQL Developer Extension for VSCodeで問題なくデバッグも動きました。


CursorもVSCodeと同様に、Oracle APEXのアプリケーション開発に使用できるでしょう。