e-learning、オラクル研修、LMS(学習管理システム)のiStudy

e-learning、オラクル研修、LMS(学習管理システム)のiStudy

第5回 「PL/SQLでのSELECT文(1)」

2011.12.19

「PL/SQLを使ってみよう」今回は、SELECT文について説明します。

前回、今後の予定として、2回ほど高度な変数宣言の仕方を紹介しますと申し上げました。
しかし、ひとつひとつの文法を順番に説明するだけでなく、実用的な応用例も紹介しないと、読者の方も退屈するのではないか?と考えました。
ということで、今回はまず理解していただきたい基本的な技術として、PL/SQLでSELECT文を使う方法をご紹介します。単独でSELECT文を使う場合と、PL/SQLでSELECT文を使う場合の違いに注目してください。SQL*Plusあるいは、SQL*Developerなどで、scottユーザに接続すればこのとおりに確認できます。

まず、以下のようなきちんと実行できる単独のSELECT文があります。

SQL> SELECT SAL FROM EMP WHERE EMPNO = 7934;

SAL
----------
1300

ちゃんと実行できましたね。
社員表(EMP表)から、社員番号(EMPNO)が7934の社員の給与(SAL)を問い合わせました。
では、このSELECT文をPL/SQLブロックで実行してみましよう。
PL/SQLブロックにするには、変数宣言など必要なければ、BEGIN と END; で囲めばいいですよね。すると、どうでしょう。以下のようなエラーになります。

▼▼▼▼▼ ここから ▼▼▼▼▼
SQL> BEGIN
2 SELECT SAL FROM EMP WHERE EMPNO = 7934;
3 END;
4 /
SELECT SAL FROM EMP WHERE EMPNO = 7934;
*
行2でエラーが発生しました。:
ORA-06550: 行2、列3:
PLS-00428: INTO句はこのSELECT文に入ります。
▲▲▲▲▲ ここまで ▲▲▲▲▲

きちんと実行できるはずのSELECT文が、PL/SQLブロックの中でエラーになるのはなぜでしょうか?
それは、PL/SQLブロック内で、SELECT文を使う場合は、問い合わせた結果を変数に代入するという記述が必要だからです。一般にPL/SQLに限らず、プログラム内での SELECT文の役割はデータベースから問い合わせた結果を変数に代入することです。
変数に代入してこそ、初めてプログラム内でその値を保持し、それ以降の実行文にその値を渡すことができるわけですから。

では、PL/SQLの場合、SELECTで問い合わせた結果を変数に代入する記述はどのようなものでしょうか?それは、そのSELECT文の返す行数によって、二つのパターンに 分かれます。1行だけ返す場合と、複数行を返す場合の二つのパターンです。
今回は、1行だけ返すSELECT文の場合をご紹介します。

1行だけ結果を返すSELECT文のPL/SQLブロック内での記述は以下の構文です。

SELECT 列1, 列2, ・・・ INTO 変数1, 変数2, ・・・
FROM ~(略)

要は、簡単にいうと、SELECT句の次にINTO句を設けて、SELECT句で指定した列の値を順番どおりにINTO句の変数に代入するという構文です。
したがって、SELECT句で指定した列の数と、INTO句で指定した変数の数は同じである必要があります。もちろんこの変数は宣言部などで宣言済みである必要があります。
本メルマガでは、この構文をSELECT INTO文と呼ぶこととします。

では、さっそく先ほどの問い合わせをSELECT INTO文で行ってみましょう。
そのためには、変数宣言が必要ですが、EMP表のSAL列の値を格納する V_SALという変数を宣言してみましょう。データ型は数値なのでNUMBER型です。
前回説明したように、以下のような宣言となります。

<宣言部で>
V_SALL  NUMBER;

あるいは、EMP表のSAL列と同じデータ型ですから、以下のような宣言でもOKです。
このほうが意味がわかりやすいですね。

<宣言部で>
V_SALL  EMP.SAL%TYPE;

ではPL/SQLブロック全体を記述し、サーバーに送信し、実行したものは以下のとおりです。

▼▼▼▼▼ ここから ▼▼▼▼▼
SQL> DECLARE
2 V_SAL EMP.SAL%TYPE;
3 BEGIN
4 SELECT SAL INTO V_SAL FROM EMP WHERE EMPNO = 7934;
5 END;
6 /

PL/SQLプロシージャが正常に完了しました。
▲▲▲▲▲ ここまで ▲▲▲▲▲

今度は、エラーになりませんね。
先頭のDECLAREから宣言部が始まり、V_SAL変数を宣言しています。3行目のBEGINから実行部が始まりますが、問い合わせたSAL列の値をV_SAL変数に代入しています。
これで確かにエラーにはなりませんが、プログラムとしては意味のない処理ですね。
せっかく変数に値を代入しても、その後の実行文がないので、変数の値は使われません。
ブロックの実行が終った段階で、PL/SQLブロック内の変数は消えてしまいますので、無意味な処理です。ですから、その変数の値を使ってなにか処理をしないとプログラムらしくありません。その変数でなにか処理をしましょう。
例えば、DBMS_OUTPUT.PUT_LINEで画面に出力しましょう。
DBMS_OUTPUTは、SQL*PlusやSQL*Developerなどの画面にのみ、サーバーから戻るメッセージを表示できます。

▼▼▼▼▼ ここから ▼▼▼▼▼
SQL> SET SERVEROUTPUT ON
SQL> DECLARE
2 V_SAL EMP.SAL%TYPE;
3 V_ENAME EMP.ENAME%TYPE;
4 BEGIN
5 SELECT SAL, ENAME INTO V_SAL, V_ENAME FROM EMP WHERE EMPNO = 7934;
6 DBMS_OUTPUT.PUT_LINE(V_ENAME || 'さんの給与は' || V_SAL || 'です'); 7 END;
 8 /
MILLERさんの給与は1300です

PL/SQLプロシージャが正常に完了しました。
▲▲▲▲▲ ここまで ▲▲▲▲▲

今度はどうでしょう? 少しプログラムらしくなりましたね。
2行目で、SAL列用の変数の他、ENAME列用の変数V_ENAMEを宣言しています。
5行目のSELECT INTO文でSAL列とENAME列の値をそれぞれの変数に代入します。6行目でそれらの変数を文字列連結して、DBMS_OUTPUT.PUT_LINEにより、サーバーの メッセージバッファに格納します。ブロックの終了とともに、そのメッセージがクライアントに戻り、SQL*Plusの機能により画面に表示されたわけです。

このようにプログラムにおいて、SELECT文の役割は問い合わせたデータの表示ではなく、変数への代入であることがお分かりいただけると思います。
では、今日は1行結果を返すSELECT文からその結果を変数に代入する方法を解説しました。
次回も引き続き、SELECT関係の説明をいたします。

次回もご期待ください。

先頭へ戻る