オラクル社が提供するOracle Databaseでは、データベース言語「SQL」以外に、SQLを拡張した「PL/SQL」が使用できます。SQLは知っているものの、PL/SQLはあまりよく知らないという方もいるのではないでしょうか。
PL/SQLはSQLをさらに使いやすくするために豊富な機能が備わっています。本記事では、Oracle Databaseで利用できるプログラミング言語「PL/SQL」の中でも、その概要から基本的な書き方について解説します。
PL/SQLとは?
PL/SQLとは、オラクル社が開発した手続き型言語で、非手続き型言語のSQLを拡張したものです。SQLでは利用できない、if(分岐)、forまたはloop(繰り返し)といった制御を行えるようになり、より効率的な処理を行うことが可能です。
他にも、PL/SQLの特徴としては、以下があげられます。
● 複数のSQLをまとめてOracle Databaseに送信でき、高いパフォーマンスを発揮する
● Oracle Databaseすべてのバージョンで利用でき、移植性が高い
● データベースにプログラムを格納する「ストアドプログラム」が作成できる
PL/SQLは「無名のPL/SQLプログラム」と「ストアドプログラム」があり、上記は無名のPL/SQLプログラムです。ストアドプログラムの場合は、さらにストアドファンクションとストアドプロシージャに分かれます。処理実行後、戻り値があるのがストアドファンクション、戻り値がないのがストアドプロシージャです。
PL/SQLの基本構造は「宣言部」「実行部」「例外処理部」の3つで構成されています。
無名のPL/SQLプログラムは、以下のような構造です。
DECLARE
/* 宣言部 */
BEGIN
/* 実行部 */
EXCEPTION
/* 例外処理部 */
END;
ストアドプログラムの場合は、先頭に関数名を記載します。たとえば、ストアドプロシージャの場合は以下のような形になります。
CREATE OR REPLACE PROCEDURE 関数名
IS
/* 宣言部 */
BEGIN
/* 実行部 */
EXCEPTION
/* 例外処理部 */
END;
それでは、ここからさらに各構造内での書き方についてみていきます。
PL/SQLの宣言部の書き方
宣言部では、変数や配列、カーソルおよび例外定義など、PL/SQLブロック(このプログラム全体)で使用するオブジェクトを定義します。
2.1 関数名の書き方
無名PL/SQLプログラムでは宣言部は「DECLARE」からはじまりますが、ストアドプログラムではDECLAREの代わりに関数名を記載し、「IS」以降から宣言部が始まります。ストアドファンクションの場合は戻り値があるため、戻り値のデータ型も記載します。
ストアドプロシージャの例
CREATE OR REPLACE PROCEDURE testproc
IS
・・・
ストアドファンクションの例
CREATE OR REPLACE FUNCTION testfunc
RETURN BOOLEAN /* 戻り値のデータ型を記載する */
IS
・・・
変数
変数は、処理の中でデータを一時的に保存しておくための場所です。デフォルトでは値はNULLですが、NOT NULLオプションを付けることで変数内にNULLが入ることを防ぐことができます。NOT NULLオプションをつけた場合は初期値の設定が必須です。値を入れる際の演算子は「:=」を使用します。
変数の定義例
DECLARE
code NUMBER(8) /* 数値型の変数を宣言 */
message VARCHAR2(20) := ‘HELLO, PLSQL’ /* 文字列型の変数を宣言 */
BEGIN
・・・
配列
PL/SQLでは、配列のことをコレクションとも呼ばれます。コレクションには「連想配列」「ネストした表」「VARRAY」の3種類があります。
連想配列は、配列の添え字のデータ型と要素のデータを宣言します。添え字には数値型だけでなく文字列も利用でき、連続した値である必要はありません。配列のサイズは自動拡張されます。
連想配列の宣言例
DECLARE
/* 数値を添え字にもつ連想配列を宣言 */
TYPE my_code IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER;
BEGIN
・・・
ネストした表は、上限がない一次元配列です。添え字は数値型のみですが、連続した値である必要はないため、要素を順序付けすることなく格納できます。
ネストした表の定義例
DECLARE
/* ネストした表を宣言 */
TYPE my_nest IS TABLE OF VARCHAR2(10);
BEGIN
・・・
VARRAYは可変長配列です。宣言時に要素数の指定が必要であり、添え字は連続した値になります。配列のサイズは自動拡張されません(EXTENDメソッドで動的に拡張も可能)。
VARRAYの定義例
DECLARE
/* VARRAYを宣言 */
TYPE my_varray IS VARRAY OF VARCHAR(20);
BEGIN
・・・
カーソル
PL/SQLでは、テーブルからデータを取得し、それを基に処理を行うことができます。テーブルからデータを取得し一時的に格納する変数にカーソルがあります。以下の例では、EMPLOYEEテーブルから取得したEMPNOを、カーソルC1に格納しています。
変数の定義例
DECLARE
/* カーソルを宣言 */
CURSOL c1 IS SELECT EMPNO FROM EMPLOYEE;
BEGIN
・・・
PL/SQLの処理部の書き方
処理部では、実際に実行する処理を記述します。PL/SQLではSQLをそのまま記述するだけでなく、分岐や繰り返しといった手続き型の処理が記述できます。ここでは、手続き型処理の記述の仕方について解説します。
分岐(IF)
IF文は、一般的なプログラミング言語と同じように分岐を記述できます。注意すべき点としては、他のプログラミング言語では「ELSEIF」または「ELSE IF」となるところが「ELSIF」となっている点です。
IF文の記述例
BEGIN
IF message = ‘apple’ THEN
/* messageの値がapple */
DBMS_OUTPUT.PUT_LINE('messageは apple です。');
ELSIF message = ‘orange’ THEN
/* messageの値がorange */
DBMS_OUTPUT.PUT_LINE('messageは orange です。');
ELSE
/* messageの値がどちらでもない*/
DBMS_OUTPUT.PUT_LINE('messageは apple でも orange でもありません。');
END IF;
繰り返し(LOOP)
繰り返しの制御は、繰り返し回数を指定する「FOR ... LOOP」、繰り返し条件を指定する「WHILE ... LOOP」、無限ループを指定するLOOPが利用できます。これも、他のプログラミング言語とそれほど違いはありません。以下は「FOR ... LOOP」の記述例です。
FOR ... LOOPの記述例
BEGIN
/* 5回繰り返し */
FOR I IN 1..5 LOOP
・・・
END LOOP;
END;
PL/SQLの例外処理の書き方
PL/SQLブロックの処理実行中に発生したエラー(例外)に対応した処理のことを例外処理と呼びます。これは、例外が発生した場合でも、正常に処理させるために使用します。
・・・
EXCEPTION
/* 例外処理部 */
END;
例外は、Oracle Databaseで事前に定義されている「内部例外」、ユーザーが独自に定義する「ユーザー定義例外」、PL/SQLブロック内に処理内容が定義されていない「定義外例外」があります。ここでは例として内部例外に対する処理について解説します。
以下の例では、「too_many_rows」という内部例外が発生したときに、rollbackする処理です。
例外処理例
EXCEPTION
WHEN no_data_found THEN rollback;
END;
no_data_found例外とは、SELECT INTO 文で返される行数が1行もない場合に発生します。
内部例外については、「PL/SQL言語リファレンス」マニュアルに記載がありますので、詳細についてはそちらをご確認ください。
まとめ
本記事では、Oracle Databaseで利用できるプログラミング言語「PL/SQL」の中でも、その概要から特長、基本的な書き方について解説しました。PL/SQLを利用できるようになると、それまでSQLを1つずつ実行して処理していたものをまとめて処理できるようになり、利便性が向上します。
Oracle Databaseを扱うのであれば、ぜひ習得しておきたい技術です。本記事を読んで興味を持った方は、さらに知識を深めていきましょう。
- カテゴリ:
- 【DB入門】Oracle
- キーワード:
- データベース