PL/
SQL(ピーエル・エスキューエル)は、Oracle Databaseの機能を拡張するために開発された
プログラミング言語です。
SQLをベースに、手続き型プログラミングの概念を取り入れ、より高度な
データベース操作やビジネスロジックの実装を可能にします。
Ada言語の影響を受けており、その文法や構造に共通点が見られます。
PL/
SQLは
1988年にOracle Databaseに追加され、
SQLの非手続き的な性質を補完するために生まれました。「PL/
SQL」という名称は、手続き型言語(Procedural Language)としての拡張に由来します。これにより、変数の利用、条件分岐(if文)、繰り返し処理(for文、loop文)などの制御構造が利用可能になり、
SQLだけでは困難だった複雑な処理を
データベース内で効率的に実行できます。
特に、問い合わせ結果の各行を個別に処理する際には、カーソルを用いたFETCHループが有効です。また、数値計算の最適化のため、ハードウェアが直接サポートする整数型(PLS_INTEGER)のようなPL/
SQL固有の
データ型も提供されています。ビジネスロジック(BL)を
SQLと別の言語で記述するよりも効率的ですが、可読性の観点から、全てのBLをPL/
SQLで代替することは一般的ではありません。
SQLの拡張言語としては、Sybase ASEや
Microsoft SQL ServerのTransact-
SQLも存在しますが、PL/
SQLとは文法や
SQLエンジンの処理方法が異なります。Transact-
SQLは全ての構文を
SQLエンジンで処理するのに対し、PL/
SQLではPL/
SQLエンジンが構文を解析し、DML(データ操作言語)は
SQLエンジンに渡して実行します。このため、Transact-
SQLではストアドプロシージャから結果セットを直接返せますが、PL/
SQLではカーソルや配列変数を介してデータを返す必要があります。
PostgreSQLのPL/pg
SQLはPL/
SQLを参考にしていますが、DBMSの実装依存や出力引数の扱いが異なるため、完全な互換性はありません。一方、
IBMのDB2や
MariaDBは、Oracle Databaseからの移行を促進するため、PL/
SQLの互換機能を導入しています。
文法
PL/
SQLの文法は
Ada言語をベースとしており、Oracle CorporationのCEOである
ラリー・エリソンが、過去に国防総省向けのシステム開発で
Ada言語を採用していたことが背景にあります。
PL/
SQLでは、基本的な
データ型に加えて、ネストした表(配列)、レコード型(
構造体)、レコード型の配列、索引付き表(連想配列)などを利用できます。さらに、「XXテーブルのYY列の型」や「XXテーブルのレコードの型」のような間接的な型指定が可能です。これにより、
データベースオブジェクトの変更に対して、再コンパイルだけで対応でき、実行時に自動的な再コンパイルも試みられます。
ブロックと例外
PL/
SQLのコードは、BEGIN〜ENDまたはDECLARE〜BEGIN〜ENDで囲まれた「ブロック」内に記述します。例外(エラー)処理は、BEGINとENDの間にEXCEPTION句を挿入することで行い、入れ子構造も可能です。変数の定義などはDECLARE〜BEGINに記述します。
直接記述されたブロックは「無名ブロック」と呼ばれ、即時実行されます。一方、ストアドプロシージャやトリガーは、評価済みの形でサーバーに登録されます。
コメント
PL/
SQLでは、行頭に'--'を記述するか、'/'〜'/'で囲むことでコメントを記述できます。
ストアドプロシージャとストアドファンクション
PL/
SQLのコードに名前を付けてサーバーに登録し、呼び出し可能にしたものがストアドプロシージャとストアドファンクションです。プロシージャは戻り値を持ちませんが、ファンクションは持ちます。ストアドプロシージャとストアドファンクションは、通常の
SQL文よりも処理が高速ですが、参照している
データベーススキーマが変更された場合には再コンパイルが必要です。ストアドファンクションは、通常の
SQL文の関数として使用できます。
テーブルの行追加、更新、削除のタイミングで自動的に実行されるPL/
SQLブロックを
データベーストリガと呼びます。トリガは、データ1件ずつ処理でき、変更前後の値を利用できます。参照整合性の管理や、非正規化されたテーブルの同期などに便利ですが、過度な利用はプログラムの複雑化を招く可能性があります。
パッケージ
PL/
SQLのパッケージは、
Ada言語の概念を受け継いでおり、永続性のある変数やストアドプロシージャをまとめることができます。
C言語における静的変数やヘッダーファイルに近い役割を果たしますが、
インスタンス化ができないため、オブジェクト指向言語のクラスとは異なります。パッケージには「自動初回コード(INITブロック)」を記述でき、パッケージが最初に呼び出された時にのみ実行されます。
ビルトイン/ユーティリティパッケージ
PL/
SQLには、DBMS_OUTPUT(バッファ出力)、UTL_FILE(ファイル出力)、DBMS_PIPE、DBMS_ALERT(同期通信)、DBMS_
SQL(動的
SQL)などのユーティリティパッケージがあります。これらのパッケージは、標準で提供されており、DBMS_やUTL_で始まる名前を持ちます。ユーザーがパッケージを作成する際には、これらの名前を避ける必要があります。また、パッケージSTANDARDで定義されているプロシージャやファンクションは、パッケージ名を省略して呼び出すことができます。
例
(ここに無名ブロック、ストアドプロシージャ、例外処理、カーソル処理の例を記述)
脚注
(ここに脚注を記述)
出典
(ここに出典を記述)
外部リンク
(ここに外部リンクを記述)