確認作業は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がインストールされていることを前提としたコードになっています。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
create or replace type array_jobs is varray(150) of varchar2(100); | |
/ | |
create or replace procedure debugging_step_into (how_many in integer) IS | |
cursor demo_debug is select * from oehr_employees fetch first how_many rows only; | |
fullname varchar2(100); | |
BEGIN | |
for counter in demo_debug LOOP | |
fullname := counter.first_name || ' ' || counter.last_name; | |
dbms_output.put_line(counter.employee_id || ' name is ' || fullname); | |
fullname := ''; | |
end loop; | |
END debugging_step_into; | |
/ | |
create or replace procedure debugging_debugger (x in integer) is | |
y boolean := true; | |
z date := sysdate; | |
jobs_a array_jobs; | |
begin | |
select distinct job_title | |
bulk collect into jobs_a | |
from oehr_jobs | |
order by 1; | |
for i in 1..x LOOP | |
DBMS_OUTPUT.PUT_LINE('Job #' || i || ' is ' || jobs_a(i)); | |
END LOOP; | |
DEBUGGING_STEP_INTO(x); | |
null; -- placeholder | |
end; | |
/ |
本記事は、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になります。
上記の設定でテストを行い、問題がなければ保存します。
パスワードの保存が未チェックのときは、データベースへの接続を要求したときに、以下のようにパスワードの入力が求められます。
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)を選択します。
データベースに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に引数Xに5を与えた実行結果が、スクリプト出力に表示されます。
ブレークポイントが設定されていないため、デバッグ実行でもスクリプトの最後まで処理が実行されます。
プロシージャ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は更新されません。
どのようなフローで同期させるかは、開発するアプリケーションの規模や開発チームの大きさで変わるように思います。アプリケーションや開発チームが小さければ、データベースに保存されているオブジェクトを直接編集し、編集が完了したコードをデータベースから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は問題なく動作します。
CursorもVSCodeと同様に、Oracle APEXのアプリケーション開発に使用できるでしょう。
完