2 PL/SQLの概要
PL/SQLは、SQLの手続き型拡張機能としてオラクル社が提供する言語であり、移植性を備えた高性能のトランザクション処理言語です。ここでは、そのメリットと、主な特徴およびアーキテクチャについて説明します。
ここでのトピック
2.1 PL/SQLの利点
PL/SQLには、その他のプログラミング言語と比較したときに、いくつかのメリットがあります。
2.1.1 SQLとの緊密な統合
PL/SQLは、SQLと緊密に統合された、最も広く使用されているデータベース操作言語です。
次に例を示します。
-
PL/SQLでは、SQLのデータ操作、カーソル制御およびトランザクション制御のすべての文、SQLのすべてのファンクション、演算子および擬似列を使用できます。
-
PL/SQLでは、SQLデータ型を完全にサポートしています。
PL/SQLとSQLのデータ型間で変換を行う必要はありません。たとえば、PL/SQLプログラムがSQL型
VARCHAR2
の列から値を取得する場合は、その値をVARCHAR2
型のPL/SQL変数に格納できます。明示的にデータ型を指定することなく、PL/SQLデータ項目を、データベース表の列や行のデータ型にできます(「%TYPE属性の使用」および「%ROWTYPE属性の使用」を参照)。
-
PL/SQLでは、SQL問合せを実行し、結果セットの行を一度に1行ずつ処理することができます(「問合せ結果セットの一度に1行ずつの処理」を参照)。
-
PL/SQLファンクションは、SQL
SELECT
文のWITH
句で宣言および定義できます(『Oracle Database SQL言語リファレンス』を参照)。
PL/SQLは静的SQLおよび動的SQLの両方をサポートしています。静的SQLとは、コンパイル時にテキスト全体がわかるSQLのことです。動的SQLとは、実行時までテキスト全体が不明なSQLのことです。動的SQLを使用すると、アプリケーションをより柔軟で多目的に使用できます。詳細は、「PL/SQLの静的SQL」および「PL/SQLの動的SQL」を参照してください。
2.1.2 高いパフォーマンス
PL/SQLでは、複数文のブロックをデータベースに送信して、アプリケーションとデータベースの間の通信量を大幅に削減できます。
バインド変数
PL/SQLコードにSQLのINSERT
、UPDATE
、DELETE
、MERGE
またはSELECT
文を直接埋め込むと、PL/SQLコンパイラは、WHERE
句およびVALUES
句内の変数をバインド変数に変換します(詳細は、「静的SQL文における名前解決」を参照)。これらのSQL文は、同じコードが実行されるたびにOracle Databaseによって再利用されるため、パフォーマンスが向上します。
バインド変数は、動的SQLの使用時にPL/SQLによって自動的には作成されませんが、明示的に指定することによって動的SQLとともに使用できます(詳細は、「EXECUTE IMMEDIATE文」を参照)。
サブプログラム
PL/SQLサブプログラムは実行可能な形式で格納され、繰り返し起動することができます。ストアド・サブプログラムはデータベース・サーバー内で実行されるため、ネットワークを介した1回の起動で大規模なジョブを開始できます。この作業の分割によってネットワークの通信量が軽減され、応答時間が短縮されます。ストアド・サブプログラムはキャッシュされ、ユーザー間で共有されるため、メモリー要件と起動のオーバーヘッドが低減します。サブプログラムの詳細は、「サブプログラム」を参照してください。
オプティマイザ
PL/SQLコンパイラには、コードのパフォーマンスが向上するように再調整する機能を持つオプティマイザがあります。オプティマイザの詳細は、「PL/SQLオプティマイザ」を参照してください。
2.1.3 高い生産性
PL/SQLは、設計およびデバッグ時間を削減するための多くの機能を備えていて、どの環境でも同様です。
PL/SQLでは、データを操作するコードをコンパクトにすることができます。Perlのようなスクリプト言語が、ファイルのデータを読み込み、変換して、書き込むのと同じように、PL/SQLは、データベースのデータを問い合せ、変換して、更新することができます。
あるOracleツールでPL/SQLの使用方法を習得すれば、その知識は他のOracleツールにも活用できます。PL/SQLの特長の概要は、「PL/SQLの主な特長」を参照してください。
2.1.4 移植性
PL/SQLは、移植性のあるOracle開発用の標準言語です。
PL/SQLアプリケーションは、Oracle Databaseが動作する任意のオペレーティング・システムおよびプラットフォームで実行できます。
2.1.5 スケーラビリティ
PL/SQLストアド・サブプログラムは、データベース・サーバー上のアプリケーション処理を集中化することでスケーラビリティを高めます。
共有サーバーの共有メモリー機能を使用すると、単一ノード上の何千もの同時ユーザーをOracle Databaseでサポートできるようになります。サブプログラムの詳細は、「サブプログラム」を参照してください
Oracle Connection Managerでネットワーク接続を多重化して、さらにスケーラビリティを高めることもできます。Oracle Connection Managerの詳細は、『Oracle Database Net Servicesリファレンス』を参照してください。
2.1.6 管理性
PL/SQLストアド・サブプログラムでは、クライアント・システムごとにサブプログラムのコピーを1つずつ保持するのではなく、データベース・サーバー上にコピーを1つのみ保持することができるため、管理性が向上します。
サブプログラムは任意の数のアプリケーションで使用することができ、呼出し元のアプリケーションに影響を与えることなく、サブプログラムを変更できます。サブプログラムの詳細は、「サブプログラム」を参照してください。
2.1.7 オブジェクト指向プログラミングのサポート
PL/SQLでは、オブジェクト指向の設計に使用可能なオブジェクト型を定義できます。
PL/SQLは、「抽象データ型」を使用したオブジェクト指向のプログラミングをサポートします。
2.2 PL/SQLの主な特長
PL/SQLでは、SQLのデータ操作機能と手続き型言語の処理機能の両方が利用できます。
SQLを使用して問題が解決できる場合、PL/SQLプログラムからSQL文を発行できます。新しいAPIを学習する必要はありません。
その他の手続き型プログラム言語と同様に、PL/SQLでは、定数と変数の宣言、プログラム・フローの制御、サブプログラムの定義、およびランタイム・エラーのトラップを行うこともできます。
複雑な問題を容易に理解できるサブプログラムに分割し、複数のアプリケーションで再利用できます。
ここでのトピック
2.2.1 エラー処理
PL/SQLでは、エラーを簡単に検出して処理できます。
エラーが発生するとPL/SQLによって例外が呼び出されます。通常の実行は中止され、PL/SQLブロックの例外処理部に制御が移ります。Cプログラムの場合のように、すべての操作をチェックして処理が成功したことを確認する必要はありません。
詳細は、「PL/SQLのエラー処理」を参照してください。
2.2.2 ブロック
PL/SQLソース・プログラムの基本単位はブロックで、関連する宣言および文をグループ化します。
PL/SQLブロックは、キーワードDECLARE
、BEGIN
、EXCEPTION
およびEND
で定義します。これらのキーワードは、ブロックを宣言部、実行部、例外処理部に分けます。このうち必ず存在する必要があるのは実行部のみです。ブロックにはラベルを付けられます。
宣言はブロックの中で局所的に有効で、そのブロックの実行が完了すると消滅します。これによって、変数およびサブプログラムの名前空間が一杯になることを回避できます。
ブロックはネストできます。ブロックは実行可能文であるため、実行可能文を配置できる場所であれば別のブロックでも配置できます。
ブロックは、(SQL*PlusやEnterprise Managerなどの)対話型ツールに送信するか、またはOracleプリコンパイラやOCIのプログラムに埋め込むことができます。対話型ツールまたはプログラムによって、ブロックが1回実行されます。ブロックはデータベースに格納されないため、(ラベルがある場合でも)無名ブロックと呼ばれます。
無名ブロックは、メモリーにロードされるたびにコンパイルされます。このコンパイルには、次の3段階があります。
-
構文チェック: PL/SQL構文がチェックされ、解析ツリーが生成されます。
-
セマンティック・チェック: 型チェックおよび解析ツリーに対する追加処理が行われます。
-
コード生成
注意:
無名ブロックはSQL文です。
構文の詳細は、「ブロック」を参照してください。
例2-1 PL/SQLブロック構造
この例は、PL/SQLブロックの基本構造を示しています。
<< label >> (optional) DECLARE -- Declarative part (optional) -- Declarations of local types, variables, & subprograms BEGIN -- Executable part (required) -- Statements (which can use items declared in declarative part) [EXCEPTION -- Exception-handling part (optional) -- Exception handlers for exceptions (errors) raised in executable part] END;
2.2.3 変数および定数
PL/SQLでは変数と定数を宣言し、式を使用可能な任意の場所で使用できます。
プログラムの実行中に、変数の値を変更できますが、定数の値は変更できません。
詳細は、「宣言」および「変数への値の代入」を参照してください。
2.2.4 サブプログラム
PL/SQLのサブプログラムは、繰り返し起動できる名前付きPL/SQLブロックです。
サブプログラムにパラメータが含まれている場合は、起動のたびにパラメータ値を変えることができます。PL/SQLにはプロシージャとファンクションの2種類のサブプログラムがあります。ファンクションは結果を戻します。
PL/SQLサブプログラムの詳細は、「PL/SQLサブプログラム」を参照してください。
PL/SQLでは、他の言語で記述された外部プログラムも起動できます。
詳細は、「外部サブプログラム」を参照してください。
2.2.5 パッケージ
パッケージとは、論理的に関連するPL/SQLの型、変数、定数、サブプログラム、カーソルおよび例外をグループにまとめたスキーマ・オブジェクトのことです。
パッケージをコンパイルしてデータベースに格納し、その内容を複数のアプリケーションで共有できます。パッケージはアプリケーションと考えることができます。
ユーザー独自のパッケージを記述できます(詳細は、「PL/SQLパッケージ」を参照してください)。Oracle Databaseで提供されている製品固有の多数のパッケージを使用することもできます。詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。
2.2.6 トリガー
トリガーとは、データベースに格納され、データベース内で発生したイベントに応答して実行される、名前付きPL/SQLユニットです。
トリガーをイベントの前に起動する場合でもイベントの後で起動する場合でも、またトリガーをイベントごとに実行する場合でもイベントの影響を受ける行ごとに実行する場合でも、イベントを指定できます。たとえば、EMPLOYEES
表がINSERT
文の影響を受けるたびに実行されるトリガーを作成できます。
トリガーの詳細は、「PL/SQLトリガー」を参照してください。
2.2.7 入出力
PL/SQLのほとんどの入出力(I/O)は、SQL文によるデータベース表へのデータの格納や、それらの表の問合せによるものです。他のすべてのPL/SQL I/Oは、Oracle Databaseが提供するPL/SQLパッケージを使用して実行されます。
表2-1 PL/SQL I/O処理パッケージ
パッケージ | 説明 | 参照 |
---|---|---|
|
PL/SQLブロック、サブプログラム、パッケージおよびトリガーからの出力を表示できます。PL/SQLデバッグ情報を表示する場合に特に役立ちます。 |
|
|
HTMLタグを生成するハイパーテキスト・ファンクションを含みます(たとえば、 |
|
|
HTMLタグを生成するハイパーテキスト・プロシージャを含みます。 |
|
|
同じインスタンス内の複数のセッション間で通信できます。 |
|
|
PL/SQLプログラムでオペレーティング・システムのファイルに対して読取りおよび書込みを実行できます。 |
|
|
PL/SQLプログラムでHypertext Transfer Protocol(HTTP)コールアウトを実行し、HTTP経由でインターネット上のデータにアクセスできます。 |
|
|
RFC821の仕様に従って、Simple Mail Transfer Protocol(SMTP)を介して電子メールを送信します。 |
DBMS_OUTPUT
に渡される出力を表示するには、SQL*Plusなどの別のプログラムが必要です。SQL*PlusでDBMS_OUTPUT
の出力を表示するには、事前に、SQL*PlusコマンドSET
SERVEROUTPUT
ON
を発行しておく必要があります。
表2-1のパッケージに含まれるサブプログラムの一部は入力と出力表示の両方を受け入れますが、キーボードから入力されたデータを直接受け入れることはできません。キーボードから入力されたデータを直接受け入れるには、SQL*PlusコマンドPROMPT
およびACCEPT
を使用します。
関連項目:
-
SQL*Plusコマンド
SET
SERVEROUTPUT
ON
の詳細は、『SQL*Plusユーザーズ・ガイドおよびリファレンス』を参照してください。 -
SQL*Plusコマンド
PROMPT
の詳細は、『SQL*Plusユーザーズ・ガイドおよびリファレンス』を参照してください。 -
SQL*Plusコマンド
ACCEPT
の詳細は、『SQL*Plusユーザーズ・ガイドおよびリファレンス』を参照してください。
2.2.8 データの抽象化
データの抽象化によって、詳細な部分を必要以上に意識することなく、データの基本的なプロパティを操作できます。
初めにデータ構造を設計してから、データ構造を操作するアルゴリズムを設計できます。
ここでのトピック
2.2.8.1 カーソル
カーソルとは、特定のSQL文やPL/SQLのSELECT
INTO
文を処理する情報を保存しておく、SQLのプライベート領域を指すポインタです。
カーソルを使用して、結果セットの行を一度に1行ずつ取り出すことができます。カーソル属性を使用して、カーソルの状態に関する情報(文によってこれまでに影響を受けた行数など)を取得できます。
カーソルの詳細は、「カーソルの概要」を参照してください。
2.2.8.2 コンポジット変数
コンポジット変数には内部コンポーネントがあり、個別にアクセスできます。
コンポジット変数全体をサブプログラムにパラメータとして渡すことができます。PL/SQLには、コレクションとレコードという、2種類のコンポジット変数があります。
コレクションの内部コンポーネントは、常に同じデータ型であり、要素と呼ばれます。各要素には、その一意の索引によってアクセスします。リストおよび配列は、コレクションの典型的な例です。
レコードの内部コンポーネントは、データ型が異なる場合があり、フィールドと呼ばれます。各フィールドには、その名前によってアクセスします。レコード変数には、表の1行または表の1行の列の一部を格納できます。
コンポジット変数の詳細は、「PL/SQLのコレクションおよびレコード」を参照してください。
2.2.8.3 %ROWTYPE属性の使用
%ROWTYPE
属性を使用すると、データベースの表またはビュー内の行の全体または一部を表すレコードを宣言できます。
このレコードは、行の全体または一部のすべての列に対して、同じ名前とデータ型のフィールドを持ちます。行の構造が変更されると、それに応じてレコードの構造も変更されます。
%ROWTYPE
の構文およびセマンティクスの詳細は、「%ROWTYPE属性」を参照してください。使用方法の詳細は、「%ROWTYPE属性を使用した項目の宣言」を参照してください。
2.2.8.4 %TYPE属性の使用
%TYPE
属性を使用すると、事前に宣言されている変数または列と同じデータ型のデータ項目を(データ型を知らなくても)宣言できます。
参照先項目の宣言が変更されると、それに応じて参照元項目の宣言も変更されます。%TYPE
属性は、データベースの値を保持する変数を宣言する場合に特に便利です。%TYPE
の構文およびセマンティクスの詳細は、「%TYPE属性」を参照してください。使用方法の詳細は、「%TYPE属性を使用した項目の宣言」を参照してください。
2.2.8.5 抽象データ型
抽象データ型(ADT)は、データ構造と、データを操作するサブプログラムで構成されています。
データ構造を形成する変数は、属性と呼ばれます。属性を操作するサブプログラムは、メソッドと呼ばれます。
ADTはデータベースに格納されます。ADTのインスタンスは、表に格納したり、PL/SQL変数として使用することができます。
ADTにより、大規模なシステムを複数の再利用可能な論理コンポーネントに分割して、複雑さを軽減できます。
静的データ・ディクショナリ・ビュー*_OBJECTS
では、ADTのOBJECT_TYPE
はTYPE
です。静的データ・ディクショナリ・ビュー*_TYPES
では、ADTのTYPECODE
はOBJECT
です。
ADTの詳細は、「CREATE TYPE文」を参照してください。
注意:
ADTは、ユーザー定義型およびオブジェクト型とも呼ばれます。
関連項目:
ADT(またはオブジェクト型)については、『Oracle Databaseオブジェクト・リレーショナル開発者ガイド』を参照してください。
2.2.10 条件付きコンパイル
条件付きコンパイルによって、ソース・テキストを削除することなく、PL/SQLアプリケーションの機能をカスタマイズできます。
たとえば、次のことが可能です。
-
最新のデータベース・リリースで新機能を使用し、古いデータベース・リリースでアプリケーションを実行する場合にそれらの新機能を無効化することができます。
-
開発環境でデバッグ文またはトレース文をアクティブ化し、本番サイトでアプリケーションを実行する場合にそれらの文を隠ぺいすることができます。
詳細は、「条件付きコンパイル」を参照してください。
2.2.11 問合せ結果セットの一度に1行ずつの処理
PL/SQLでは、SQL問合せを発行し、結果セットの行を一度に1行ずつ処理できます。
基本ループを使用するか、または問合せの実行、結果の取出しおよび処理の終了を行う個別の文を使用して処理を正確に制御できます。
例2-2 問合せ結果行の一度に1行ずつの処理
この例では、基本ループを使用します。
BEGIN FOR someone IN ( SELECT * FROM employees WHERE employee_id < 120 ORDER BY employee_id ) LOOP DBMS_OUTPUT.PUT_LINE('First name = ' || someone.first_name || ', Last name = ' || someone.last_name); END LOOP; END; /
結果:
First name = Steven, Last name = King First name = Neena, Last name = Kochhar First name = Lex, Last name = De Haan First name = Alexander, Last name = Hunold First name = Bruce, Last name = Ernst First name = David, Last name = Austin First name = Valli, Last name = Pataballa First name = Diana, Last name = Lorentz First name = Nancy, Last name = Greenberg First name = Daniel, Last name = Faviet First name = John, Last name = Chen First name = Ismael, Last name = Sciarra First name = Jose Manuel, Last name = Urman First name = Luis, Last name = Popp First name = Den, Last name = Raphaely First name = Alexander, Last name = Khoo First name = Shelli, Last name = Baida First name = Sigal, Last name = Tobias First name = Guy, Last name = Himuro First name = Karen, Last name = Colmenares
2.3 PL/SQLのアーキテクチャ
2.3.1 PL/SQLエンジン
PL/SQLコンパイルおよびランタイム・システムは、PL/SQLユニットをコンパイルして実行するエンジンです。
このエンジンは、データベースにインストールすることも、Oracle Formsのようなアプリケーション開発ツールにインストールすることもできます。
どちらの環境でも、PL/SQLエンジンは任意の適切なPL/SQLユニットを入力として受け入れます。図2-1に示すように、SQLエンジンはプロシージャ文のみを実行し、SQL文をデータベースのSQLエンジンに送信します。
通常、PL/SQLユニットはデータベースによって処理されます。
アプリケーション開発ツールは、PL/SQLユニットを処理する際に、それらをローカルのPL/SQLエンジンに渡します。PL/SQLユニットにSQL文がない場合、ローカルのエンジンがPL/SQLユニット全体を処理します。アプリケーション開発ツールが条件制御や反復制御を活用できる場合は、この機能が特に便利です。
たとえば、Oracle Formsアプリケーションは、フィールド・エントリの値のテストや単純な計算のためにSQL文を頻繁に使用します。SQLのかわりにPL/SQLを使用すると、これらのアプリケーションはデータベースへのコールを回避できます。
2.3.2 PL/SQLユニットおよびコンパイル・パラメータ
PL/SQLユニットは、PL/SQLコンパイル・パラメータ(データベース初期化パラメータのカテゴリ)によって影響を受けます。異なるPL/SQLユニット(パッケージの仕様部や本体など)に、異なるコンパイル・パラメータ設定を含めることができます。
PL/SQLユニットは、次のいずれかです。
-
PL/SQLの無名ブロック
-
FUNCTION
-
LIBRARY
-
PACKAGE
-
PACKAGE
BODY
-
PROCEDURE
-
TRIGGER
-
TYPE
-
TYPE
BODY
表2-2に、PL/SQLコンパイル・パラメータの概要を示します。指定したPL/SQLユニットまたはすべてのPL/SQLユニットについて、これらのパラメータの値を表示するには、静的データ・ディクショナリ・ビューALL_PLSQL_OBJECT_SETTINGS
を問い合せます。このビューの詳細は、『Oracle Databaseリファレンス』を参照してください。
表2-2 PL/SQLコンパイル・パラメータ
パラメータ | 説明 |
---|---|
コンパイル時のコレクション、相互参照、およびPL/SQLソース・テキストの識別子データの格納を制御します。PL/Scopeツールにより使用されます(『Oracle Database開発ガイド』を参照)。
|
|
各PL/SQLユニットの条件付きコンパイルを独立して制御できます。
|
|
PL/SQLユニットのコンパイル・モード (
|
|
PL/SQLユニットのコンパイルで使用される最適化レベルを指定します(レベルを高くすると、コンパイラでより多くのPL/SQLユニットの最適化が試行されます)。
|
|
PL/SQLコンパイラによる警告メッセージのレポートを有効または無効にし、エラーとして表示する警告メッセージを指定します。
|
|
バイト長セマンティクスまたは文字長セマンティクスのいずれかを使用して、 バイト長セマンティクスおよび文字長セマンティクスの詳細は、「CHARおよびVARCHAR2変数」を参照してください。
|
|
9.2 PL/SQLコンパイラでコンパイルされているラップされたパッケージを12.1 PL/SQLコンパイラが使用できるかどうかを指定します。デフォルト値は ラップされたパッケージの詳細は、「PL/SQLのソース・テキストのラップ」を参照してください。
|
注意:
PL/SQLユニットをデバッグ用にコンパイルするかどうかを指定するコンパイル・パラメータPLSQL_DEBUG
は、非推奨になりました。PL/SQLユニットをデバッグ用にコンパイルするには、PLSQL_OPTIMIZE_LEVEL=1
を指定します。
表2-2のパラメータのコンパイル時の値が各ストアドPL/SQLユニットのメタデータとともに格納されており、ユニットを明示的に再コンパイルする際にその値を再利用できます。(ストアドPL/SQLユニットは、「CREATE [ OR REPLACE ]文」の1つを使用して作成します。無名ブロックは、ストアドPL/SQLユニットではありません。)
ストアドPL/SQLユニットを明示的に再コンパイルして、そのパラメータ値を再利用するには、ALTER
文をCOMPILE
句およびREUSE
SETTINGS
句とともに使用する必要があります。すべてのALTER
文にこの句があります。ALTER
文の一覧は、「ALTER文」を参照してください。