サーバー側プログラミング: PL/SQL、JavaおよびJavaScript
「SQL」では、Structured Query Language(SQL)言語およびデータベースによるSQL文の処理方法について説明します。この章では、データベースに格納された手続き型言語/SQL(PL/SQL)またはJavaプログラムがSQLを使用できる仕組みについて説明します。
-
サーバー側プログラミングの概要SQLなどの非手続き型言語では、処理されるデータ・セットは指定しますが、実行する処理やその処理を実行する方法は指定しません。
-
PL/SQLの概要 PL/SQLは、使いやすく、SQLとシームレスに、堅牢で移植性が備えた、セキュアなサーバー側ストアド・プロシージャ言語を提供します。PL/SQLユニットというプロシージャ・オブジェクトを使用してデータベース・データにアクセスし、データを処理できます。
-
Oracle AI DatabaseにおけるJavaの概要Javaは、オブジェクト指向プログラミング言語の選択肢として、Javaがあります。
-
Oracle AI DatabaseにおけるJavaScriptの概要 JavaScriptは、現在最も一般的なプログラミング言語の1つです。Linux x86-64またはLinux aarch64にデプロイされたOracle AI Databaseは、サーバー側開発でサポートされている言語のリストにJavaScriptを追加します。
-
トリガーの概要データベース・トリガーは、PL/SQL、JavaまたはJavaScriptのいずれかで記述されたコンパイル済のストアド・プログラム・ユニットで、特定の状況でOracle Databaseによって自動的に呼出し(起動)を行います。関連項目: SQL言語の概要は、「SQL」を参照。
サーバー側プログラミングの概要
SQLなどの非手続き型言語では、処理対象のデータ・セットは指定しますが、実行される処理またはその処理の実行方法は指定しません。
手続き型言語プログラムでは、ほとんどの文の実行が、前後の文、およびループまたは条件分岐などの制御構造に依存しますが、このような処理はSQLでは実行できません。手続き型言語と非手続き型言語の相違を例示するために、次のSQL文でemployees表に問い合せるとします。
SELECT employee_id, department_id, last_name, salary FROM employees;
この文はデータを要求しますが、データにロジックを適用しません。ただし、データ・セットの各従業員が給与および部門の業績に基づく昇給の対象者になるかどうかを判定するアプリケーションが必要であるとします。昇給の必要条件は、従業員が過去5年間に3回を超える昇給を受けなかったことです。昇給する場合は、アプリケーションで給与を調整してマネージャに電子メールを送信し、昇給しない場合は、アプリケーションでレポートを更新する必要があります。
この処理を実行するために、条件付きロジックおよびプログラム・フロー制御を必要とする手続き型データベース・アプリケーションでSQLを使用できるようにします。基本的な開発アプローチは次のとおりです。
-
クライアント側プログラミングを使用して、C、C++またはJavaなどの手続き型言語で記述されたアプリケーションにSQL文を埋め込みます。
ソース・コードにSQL文を配置して、コンパイル前にそのSQLSQL文をプリコンパイラまたはJavaトランスレータに送信できます。または、プリコンパイル・ステップを省略し、アプリケーションがデータベースと相互作用できるようにJava Database Connectivity(JDBC)またはOracle Call Interface(OCI)などのAPIを使用することもできます。
-
サーバー側プログラミングを使用して、データベース内に配置するデータ・ロジックを開発します。
アプリケーションは、PL/SQL (「ピー・エルシー・キューエル」と読み取ります)またはJavaで記述されたストアド・サブプログラム(プロシージャおよびファンクション)を明示的に起動できます。JavaScript また、データベースに格納されるプログラム・ユニットの名前を指定し、特定のイベントに応答して起動するトリガーを作成することもできます。
この章では、2番目のアプローチについて説明します。サーバー側プログラミングの主な利点は、データベースに組み込まれた機能を任意の場所にデプロイできることです。指定されたオペレーティング・システム上でタスクを実行するための最善の方法を決定するのは、アプリケーションではなくデータベースです。また、サブプログラムを使用すると、サーバー上にアプリケーション処理を集中化することでスケーラビリティを向上させることができ、また、クライアントでコードを再利用することもできます。サブプログラム・コールは迅速かつ効率的であるため、1回のコールで計算集中型のストアド・サブプログラムを開始し、ネットワーク・トラフィックを軽減できます。
Oracle AI Databaseにデータ・ロジックを格納するには、次の言語を使用できます。
-
PL/SQL
PL/SQLは、SQLへのOracle AI Databaseの手続き型拡張機能である。PL/SQLはデータベースに統合されており、すべてのOracle SQL文、関数およびデータ型をサポートします。データベースAPIに記述されたアプリケーションはPL/SQLストアド・サブプログラムを起動し、実行するPL/SQLコード・ブロックをデータベースに送信します。
-
Java
Oracle AI Databaseは、Javaアプリケーションの開発、格納およびデプロイもサポートします。Javaストアド・サブプログラムはデータベースで実行され、中間層で実行されるプログラムからは独立しています。Javaストアド・サブプログラムは、PL/SQLに類似の実行モデルを使用してSQLとインタフェースを確立します。
-
JavaScript
Linux x86-64またはLinux aarch64にデプロイする場合、Oracle AI Databaseを使用すると、開発者はJavaScriptでビジネス・ロジックを表現できますJavaScriptの非定型実行は、DBMS_MLE PL/SQLパッケージとそのサブルーチンによって可能になります。ビジネス・ロジックをJavaScriptスキーマ・オブジェクトとして格納すると、より複雑なアプリケーションを記述できます。コール仕様では、Javaストアド・プロシージャと同様の方法で、SQLおよびPL/SQLのデータベースに格納されているJavaScriptコードが公開されます。
関連情報:
-
プリコンパイラおよびAPIでのSQL埋込みについて学習するには、Oracle AI Database開発ガイドを参照してください。
-
Oracle AI Databaseアプリケーション開発の概要は、『Oracle AI Database Oracle AI Database開発スタート・ガイド』を参照してください
-
プログラミング環境の選択方法を学習するには、『Oracle AI Database開発ガイド』を参照
-
Oracle AI DatabaseでのJavaScriptサポートについてさらに学習するには、『Oracle AI Database JavaScript開発者ガイド』を参照してください。
PL/SQLの概要
PL/SQLは、使用しやすく、SQLとシームレスで、堅牢かつ移植性を備えたセキュアなサーバー側に格納される手続き型言語を提供します。PL/SQLユニットというプロシージャ・オブジェクトを使用してデータベース・データにアクセスし、データを処理できます。
PL/SQLユニットは、一般に、次のように分類されます。
-
PL/SQLサブプログラムとは、データベースに格納され、アプリケーションから名前でコールできるPL/SQLブロックのことです。サブプログラムを作成すると、データベースではそのサブプログラムを解析し、解析後の表現をデータベースに格納します。サブプログラムは、プロシージャまたはファンクションとして宣言できます。
-
PL/SQL無名ブロックとは、アプリケーション内で表示されるが名前が付いていなかったり、データベースに格納されていないPL/SQLブロックです。多くのアプリケーションでは、SQL文を記述できるところであればどこにでもPL/SQLブロックを記述できます。
PL/SQLのコンパイラとインタプリタはOracle SQL Developerに埋め込まれており、開発者にクライアントとサーバーの両方で一貫性のある、高度な開発モデルを提供しています。また、PL/SQLストアド・プロシージャは、Pro*C、JDBC、ODBCまたはOCIなどの複数のデータベース・クライアント、およびOracle ReportsとOracle Formsからコールできます。
-
PL/SQLサブプログラム PL/SQLサブプログラムは名前付きPL/SQLブロックで、コール元がパラメータ(入力のみ、出力のみ、または入出の値を指定できるパラメータを指定できる。
-
PL/SQLパッケージPL/SQLパッケージとは、関連するサブプログラムの集まりであり、それらで使用されるカーソルおよび変数とともに、1単位として継続的に使用できるようにデータベースに格納されたものです。パッケージ化されたプログラムは、アプリケーションまたはユーザーから明示的にコールできます。
-
PL/SQLの無名ブロック PL/SQL無名ロックとは、名前が付いていなかった非永続PL/SQLユニットである。
-
PL/SQLの言語構造 PL/SQLブロックには、様々なPL/SQL言語構造を組み込むことができる。
-
PL/SQLのコレクションとレコード多くのプログラミング技法では、配列、バッグ、リスト、ネストした表、セットおよびツリーなどのコレクション型が使用されます。
-
PL/SQLの実行方法 PL/SQLでは、解釈実行とネイティブ実行が両方ともサポートされています。
関連情報:
-
パッケージを含むPL/ SQLの詳細は、『Oracle AI DatabasePL/ SQL言語リファレンス』を参照してください。
PL/SQLサブプログラム
PL/SQLサブプログラムは、コール元から、入力のみ、出力のみまたは入出力の値が入るパラメータを指定できる名前付きのPL/SQLブロックです。
サブプログラムは特定の問題を解決するか、関連するタスクを実行してモジュール式のメンテナンス可能なデータベース・アプリケーションのビルディング・ブロックとして機能します。サブプログラムが、PL/SQLプロシージャまたはPL/SQLファンクションのいずれかであること。プロシージャとファンクションは常にコール元に対して1つの値を戻すが、プロシージャでは戻さない点を除き、プロシージャとファンクションは同じです。この章では、この章のPL/SQLプロシージャという用語は、プロシージャまたはファンクションのいずれかを指します。
-
PL/SQLサブプログラムの利点サーバー側プログラミングには、クライアント側プログラミングより多くの利点があります。
-
PL/SQLサブプログラム作成スタンドアロンのストアド・サブプログラムは、
CREATE PROCEDURE文またはCREATE FUNCTION文でスキーマ・レベルで作成されたサブプログラムは、次のとおりです。パッケージに定義されているサブプログラムがパッケージ・サブプログラムと呼ばれ、パッケージの一部とみなされます。 -
PL/SQLサブプログラムの実行ユーザーは、複数の方法で対話的にサブプログラムを実行できます。
関連情報:
-
これらの言語のストアド・プロシージャについて学習するには、『Pro*C/C++開発者ガイド』および『Pro*COBOL開発者ガイド』を参照してください。
PL/SQLサブプログラムの利点
サーバー側プログラミングにはクライアント側プログラミングよりも多くの利点があります。
次のような利点があります。
-
パフォーマンスの向上
-
メモリーの割当て
ストアド・プロシージャは、Oracle AI Databaseの共有メモリー機能を活用しているため、複数のユーザーが実行する場合でも、メモリーにロードする必要がある唯一のプロシージャのコピー1つのみです。コードを複数のユーザーが共有すれば、アプリケーションに必要なデータベース・メモリー要件を実質的に削減できます。
-
生産性の向上
ストアド・プロシージャにより、開発の生産性が向上します。共通のプロシージャを中心にしてアプリケーションを設計することにより、冗長なコーディングを回避できます。たとえば、プロシージャを記述して
employees表内の行を操作できます。どのアプリケーションでも、これらのプロシージャをコールするためにSQL文を書きなおす必要はありません。データ管理の方法に変更があった場合も、修正する必要があるのはプロシージャのみで、プロシージャを使用するアプリケーションを修正する必要はありません。ストアド・プロシージャは、コードを再利用するための最善の方法です。任意の言語で記述されたデータベース接続を行うどのクライアント・アプリケーションもストアド・プロシージャを起動できるため、すべての環境において最大限にコードを再利用できます。
-
完全性
ストアド・プロシージャにより、アプリケーションの整合性と一貫性が向上します。共通のプロシージャ群を中心としてアプリケーションを開発すれば、コーディング・エラーの発生回数が少なくなります。
たとえば、サブプログラムが正確な結果を戻すかどうかをテストし、検証後は、そのサブプログラムを必要な数のアプリケーションで再利用でき、再びテストする必要はありません。プロシージャにより参照されるデータ構造が変更された場合、プロシージャの再コンパイルのみが必要になります。プロシージャをコールするアプリケーションの修正は、必ずしも必要ありません。
-
定義者権限プロシージャによるセキュリティ
ストアド・プロシージャを使用すると、データのセキュリティを強化できます。定義者権限PL/SQLプロシージャは、現行のユーザーではなくその所有者の権限で実行されます。このため、定義者の権限で実行するプロシージャとファンクションを介してのみユーザーがデータにアクセスできるようにすると、ユーザーは実行するデータベース・タスクを制限できます。
たとえば、表を更新するプロシージャへのアクセス権は付与しても、表自体へのアクセス権は付与しないプロシージャへのアクセス権をユーザーに付与できます。ユーザーがプロシージャを呼び出すと、そのプロシージャがプロシージャの所有者の権限で実行されます。プロシージャの実行権限しかなく、表データの問合せ、更新または削除の権限を持たないユーザーは、プロシージャを呼び出すことはできても、表のデータをそれ以外の方法では操作できません。
-
実行者の権限プロシージャで継承される権限およびスキーマのコンテキスト
invoker's rights PL/SQL procedureは、現行のユーザーの権限を使用して現行のユーザーのスキーマで実行されます。つまり、実行者権限プロシージャは特定のユーザーまたはスキーマに結び付けられていません。実行者権限プロシージャは、基礎となるデータがユーザー・スキーマに分割されていても、アプリケーション開発者がアプリケーション・ロジックを簡単に一元化できるようにします。
たとえば、
hr.employees表の更新プロシージャを実行するhr_managerユーザーは給与を更新できますが、同じプロシージャを実行するhr_clerkは住所データの更新にのみ操作を制限されます。
関連情報:
-
PL/SQLサブプログラムの概要は、『Oracle AI Database PL/SQL言語リファレンス』を参照
-
定義者および実行者の権限についてさらに学習するには、『Oracle AI Databaseセキュリティ・ガイド』を参照
PL/SQLサブプログラムの作成
スタンドアロンのストアド・サブプログラムは、CREATE PROCEDURE文またはCREATE FUNCTION文を使用してスキーマ・レベルで作成されたサブプログラムです。パッケージに定義されているサブプログラムがパッケージ・サブプログラムと呼ばれ、パッケージの一部とみなされます。
データベースは、データ・ディクショナリにスキーマ・オブジェクトとしてサブプログラムを格納します。サブプログラムには、パラメータの記述などの仕様部と本体があります。
例11-1 PL/SQLプロシージャ
この例に、スタンドアロンのPL/SQLプロシージャhire_employeesを作成する文の一部を示します。プロシージャは、employees表に1つの行を挿入します。
CREATE PROCEDURE hire_employees
(p_last_name VARCHAR2, p_job_id VARCHAR2, p_manager_id NUMBER,
p_hire_date DATE, p_salary NUMBER, p_commission_pct NUMBER,
p_department_id NUMBER)
IS
BEGIN
.
.
.
INSERT INTO employees (employee_id, last_name, job_id, manager_id, hire_date,
salary, commission_pct, department_id)
VALUES (emp_sequence.NEXTVAL, p_last_name, p_job_id, p_manager_id,
p_hire_date, p_salary, p_commission_pct, p_department_id);
.
.
.
END;
関連情報:
-
サブプログラムの作成方法について学習するには、Oracle AI Database Oracle AI Database開発スタート・ガイドを参照してください。
-
CREATE PROCEDURE文について学習するには、Oracle AI Database PL/SQL言語リファレンスを参照
PL/SQLサブプログラムの実行
ユーザーは、複数の方法で対話的にサブプログラムを実行できます。
オプションは:
-
SQL*PlusやSQL DeveloperなどのOracleツールを使用します
-
Oracle Formsやプリコンパイラのアプリケーションなど、データベース・アプリケーションのコード内で明示的にコールします
-
別のプロシージャやトリガーのコード内で明示的にコールします。
次の図に、各種のデータベース・アプリケーションがhire_employeesをコールする状態を示します。
図1: ストアド・プロシージャの複数の実行

また、権限を付与されたユーザーは、Oracle Enterprise ManagerまたはSQL*Plusを使用して、次のような文でhire_employeesプロシージャを実行できます。
EXECUTE hire_employees ('TSMITH', 'CLERK', 1037, SYSDATE, 500, NULL, 20);
この文により、employees表にTSMITHのための新しいレコードが挿入されます。
ストアド・プロシージャは、プロシージャの本体で参照されるオブジェクトに依存しています。データベースは、この依存性を自動的に追跡して管理します。たとえば、プロシージャに影響を及ぼす方法でhire_employeesプロシージャが参照しているemployees表の定義を変更した場合は、プロシージャを再コンパイルして、引き続き設計どおりに機能することを確認する必要があります。通常、データベースはこのような依存性の管理を自動的に処理します。
関連情報:
-
SQL*PlusおよびSQL Developerについてさらに学習するには、Oracle AI Database Oracle AI Database開発スタート・ガイドを参照してください。
-
プリコンパイラについてさらに学習するには、Oracle AI Database開発ガイドを参照してください。
-
PL/SQLサブプログラムの使用方法を学習するには、Oracle AI Database PL/SQL言語リファレンスを参照してください。
-
EXECUTEコマンドについて学習するには、SQL*Plusユーザーズ・ガイドおよびリファレンスを参照してください。
PL/SQLパッケージ
PL/SQLパッケージとは、関連するサブプログラムとそれらのサブプログラムが使用するカーソルと変数をグループとして使用したもので、1単位として継続的に使用できるようにデータベースに格納しています。パッケージ化されたプログラムは、アプリケーションまたはユーザーから明示的にコールできます。
Oracle AI Databaseには、データベースの機能を拡張し、SQL機能へのPL/SQLアクセスを提供する、提供されている多くのパッケージが含まれています。たとえば、UTL_HTTPパッケージを使用すると、PL/SQLおよびSQLからのHTTPコールアウトでインターネット上のデータにアクセスしたり、Oracle Web Server Cartridgesをコールできます。オラクル社が提供するパッケージは、アプリケーションの作成時や、独自のストアド・プロシージャを作成する場合に使用できます。
-
PL/SQLパッケージの利点PL/SQLパッケージにより、アプリケーション開発者に多数の利点が得られます。
-
PL/SQLパッケージを作成パッケージは、仕様部分と本体という2つの部分に分かれて作成します。パッケージの仕様部ではパッケージのすべてのパブリックな構成メンバーを宣言し、パッケージの本体ではパッケージのすべての構成メンバー(パブリックとプライベート)を定義します。
-
PL/SQLパッケージ・サブプログラムの実行データベース・トリガー、ストアド・サブプログラム、3GLアプリケーション・プログラムおよびOracleツールは、パッケージの内容を参照できます。
PL/SQLパッケージの利点
PL/SQLパッケージは、アプリケーション開発者に多くの利点を提供します。
次のような利点があります。
-
カプセル化
パッケージを使用すると、ストアド・プロシージャ、変数、データ型などに名前を付けて1つの単位としてこれらをカプセル化、つまりグループ化できます。カプセル化により開発時に優れた構成を実現でき、柔軟性も向上します。パッケージ本体を実際には作成せずに、仕様部を作成し、パブリック・プロシージャを参照するようにできます。カプセル化により、権限の管理が簡単になります。パッケージに対する権限を付与されたユーザーは、そのパッケージの構成メンバーにアクセスできるようになります。
-
データ・セキュリティ
パッケージの定義方法により、変数、カーソルおよびプロシージャをパブリックとプライベートのどちらかに指定できます。パブリックはパッケージのユーザーが直接アクセスできることを意味します。プライベートはパッケージのユーザーには非表示になっていることを意味します。
たとえば、パッケージに10個のプロシージャが含まれているとします。この中の3つのプロシージャのみをパブリックに設定して、パッケージのユーザーが実行できるように定義できます。残りのプロシージャはプライベートなので、パッケージ内のプロシージャによってのみアクセスできます。パブリックおよびプライベートのパッケージ変数を、
PUBLICへの権限付与と混同しないでください。 -
パフォーマンスの向上
パッケージ内のプロシージャが初めてコールされた時点で、そのパッケージ全体が小さいチャンクに分割されてメモリーにロードされます。このロードは、スタンドアロン・プロシージャに必要な個別のロードではなく、1回の操作で完了されます。関連するパッケージ・プロシージャがコールされると、メモリーにあるコンパイル済コードを実行するためにディスクI/Oは不要になります。
パッケージ本体は、仕様部に影響を与えずに置換したり再コンパイルできます。結果として、パッケージの構成部も置き換えない場合、パッケージの構成部を参照するスキーマ・オブジェクト(常に仕様部を介して)を再コンパイルする必要はありません。パッケージを使用すると、不必要な再コンパイルが最小限に抑えられるため、全体的なデータベース・パフォーマンスへの影響は少なくなります。
PL/SQLパッケージの作成
パッケージは、仕様部と本体の2つの部分に分けて作成します。パッケージの仕様部ではパッケージのすべてのパブリックな構成メンバーを宣言し、パッケージの本体ではパッケージのすべての構成メンバー(パブリックとプライベート)を定義します。
次の例は、employees_managementのパッケージ仕様を作成する文の一部で、このパッケージは、従業員データベースの管理に使用される複数のサブプログラムをカプセル化します。パッケージの各部分は、異なる文を使用して作成されます。
CREATE PACKAGE employees_management AS
FUNCTION hire_employees (last_name VARCHAR2, job_id VARCHAR2, manager_id NUMBER,
salary NUMBER, commission_pct NUMBER, department_id NUMBER) RETURN NUMBER;
PROCEDURE fire_employees(employee_id NUMBER);
PROCEDURE salary_raise(employee_id NUMBER, salary_incr NUMBER);
.
.
.
no_sal EXCEPTION;
END employees_management;
仕様部に、ファンクションhire_employees、プロシージャfire_employeesおよびsalary_raiseと、例外であるno_salが宣言されています。パッケージへのアクセス権を持つユーザーは、これらすべてのパブリック・プログラム・オブジェクトを使用できます。
CREATE PACKAGE BODY文では、仕様部で宣言されたオブジェクトを定義します。パッケージ本体は、パッケージと同じスキーマに作成する必要があります。パッケージの作成後は、これらのうちいずれかのパブリック・プロシージャまたはファンクションをコールするか、パッケージのいずれかのパブリック例外を呼び出すアプリケーションを開発できます。
CREATE PACKAGE文について学習するには、『Oracle AI Database PL/SQL言語リファレンス』も参照してください。
PL/SQLパッケージ・サブプログラムの実行
データベース・トリガー、ストアド・サブプログラム、3GLアプリケーション・プログラムおよびOracleツールは、パッケージの内容を参照できます。
次の図に、employees_managementパッケージ内のプロシージャおよびファンクションを呼び出すデータベース・アプリケーションを示します。
図2: PL/SQLパッケージ内のサブプログラムのコール

データベース・アプリケーションは、必要に応じて明示的にパッケージ・プロシージャをコールします。employees_managementパッケージに対する権限を付与されたユーザーは、そこに含まれている任意のプロシージャを明示的に実行できます。たとえば、SQL*Plusでは、次の文を発行してhire_employeesパッケージ・プロシージャを実行できます。
EXECUTE employees_management.hire_employees ('TSMITH', 'CLERK', 1037, SYSDATE, 500, NULL, 20);
関連情報:
-
PL/ SQLパッケージの概要は、Oracle AI DatabasePL/ SQL言語リファレンスを参照
-
PL/SQLパッケージのコード化方法を学習するには、『Oracle AI Database開発ガイド』を参照
PL/SQLの無名ブロック
PL/SQL無名ブロックは名前が付与されていない非永続PL/SQLユニットです。
典型的な無名ブロックの用途は次のとおりです。
-
サブプログラムおよびパッケージ構成のコールの開始
-
例外処理の分離
-
他のPL/SQLブロック内でのコードのネストによる制御の管理
無名ブロックには、ストアド・サブプログラムのコードの再利用という利点はありません。表11-1に、2つのPL/SQLユニット・タイプの相違点の概要を示します。
表1無名ブロックとサブプログラムの相違点
| PL/SQLユニット… | 匿名ブロック | サブプログラム |
|---|---|---|
| 名前で指定されますか。 | いいえ | はい |
| 再利用ごとにコンパイルするか | いいえ | いいえ |
| データベースに格納されているか。 | いいえ | はい |
| 他のアプリケーションから起動できるか | いいえ | はい |
| バインド変数値を戻すことができるか | はい | はい |
| 関数値を戻すことができるか | いいえ | はい |
| パラメータを受け取ることができるか | いいえ | はい |
無名ブロックは、オプションの宣言部、実行可能部分および1つまたは複数のオプションの例外ハンドラで構成されます。次のサンプルの無名ブロックでは、変数に格納する従業員の姓を選択して、その名前を出力しています。
DECLARE
v_lname VARCHAR2(25);
BEGIN
SELECT last_name
INTO v_lname
FROM employees
WHERE employee_id = 101;
DBMS_OUTPUT.PUT_LINE('Employee last name is '||v_lname);
END;
Oracle AI Databaseでは、PL/SQLブロックがコンパイルされ、SGAの共有プールに配置されますが、現行インスタンス以外で再利用するためにソース・コードおよびコンパイル済バージョンのデータベースをデータベースに格納することはありません。トリガーとは異なり、無名ブロックはメモリーにロードされるたびにコンパイルされます。共有SQLでは、共有プールに入っている無名のPL/SQLブロックがその共有プールからフラッシュされるまでの間に、その共有プールを再利用および共有することができます。
無名PL/SQLブロックについてさらに学習するには、『Oracle AI Database開発ガイド』も参照してください。
PL/SQLの言語構造
PL/SQLブロックには、様々な異なるPL/SQL言語構造を組み込むことができます。
これらの構造には、次のものが含まれます。
-
変数と定数
プロシージャ、ファンクションまたはパッケージ内にこれらの構造を宣言できます。SQL文やPL/SQL文では、必要になった時点で値を受け渡すために変数や定数を使用できます。
-
カーソル
カーソルは、Oracle AI Databaseデータのレコード単位で処理を容易にするために、プロシージャ、ファンクションまたはパッケージの中で明示的に宣言できます。PL/SQLエンジンで、暗黙的にカーソルを宣言することもできます。
-
例外
PL/SQLを使用すると、PL/SQLコードの処理中に発生する、例外と呼ばれる内部的なエラー条件およびユーザー定義のエラー条件が明示的に処理されます。
PL/SQLでは、完全なテキストが実行時まで認識されない動的SQL文を実行できます。動的SQL文は、実行時にプログラムに入力されたり、プログラムにより作成される文字列に格納されます。この技法により、汎用プロシージャを作成できます。たとえば、実行時までは名前がわからない表を操作するプロシージャを作成できます。
関連情報:
-
動的SQLの詳細は『Oracle AI Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。
-
DBMS_SQLパッケージでの動的SQLの使用方法を学習するには、『Oracle AI Database PL/SQLパッケージおよびタイプ・リファレンス』を参照
PL/SQLのコレクションとレコード
多数のプログラミング技法は、配列、構造体、リスト、ネストした表、セットおよびツリーなどのコレクション型を使用します。
データベース・アプリケーションで収集技法をサポートするために、PL/SQLにはTABLEおよびVARRAYのデータ型が用意されています。これらの型を使用すると、連想配列、ネストした表および可変サイズ配列を宣言できます。
-
コレクションPL/SQLコレクションは、すべて同じ型の要素から成る順序付けられたグループです。
-
レコード PL/SQLレコードは、様々な型のデータ値を格納できるコンポジット変数で、C、C++またはJavaの0型に似ています。レコードは、表内の行データまたは表内の行の特定列を保持する場合に役立ちます。
回収
PL/SQLコレクションは、すべて同じ型の要素の順序付きグループです。
各要素には、コレクション内での位置を決定する一意の添字が付いています。コレクションを作成するには、コレクション型を最初に定義してから、その型の変数を宣言します。
コレクションの機能は、ほとんどの第3世代プログラミング言語に見られる配列と同じです。また、コレクションはパラメータとして渡すことができます。そのため、データベース表との間や、クライアント側アプリケーションとストアド・サブプログラムの間で、データの列を移動するときに使用できます。
レコード
PL/SQLレコードは、様々な型のデータ値を格納できるコンポジット変数で、C、C++またはJavaの0型に似ています。レコードは、表内の行データまたは表内の行の特定列を保持する場合に役立ちます。
名前、給与および採用日など、従業員に関するデータがあるとします。これらの項目は、型は異なりますが論理的には関連しています。項目ごとに1フィールドを含むレコードを使用すると、データを論理単位として処理できます。
%ROWTYPE属性を使用すると、表の1行やカーソルからフェッチされる1行を表すレコードを宣言できます。ユーザー定義レコードの場合は、所有しているフィールドを宣言できます。
関連項目:PL/ SQLレコードの使用方法を学習するには、『Oracle AI DatabasePL/ SQL言語リファレンス』
PL/SQLの実行方法
PL/SQLは解析済の実行およびシステム固有の実行の両方をサポートします。
解析済の実行では、PL/SQLソース・コードがいわゆるバイトコード表現にコンパイルされます。Oracle AI Databaseの一部として実装されている移植可能仮想コンピュータによって、このバイトコードが実行されます。
ネイティブ実行では、計算集中型のユニットで最大限のパフォーマンスが発揮されます。この場合は、PL/SQLユニットのソース・コードが特定のプラットフォームのオブジェクト・コードに直接コンパイルされます。このオブジェクト・コードは、Oracle AI Databaseにリンクされます。
PL/SQLエンジンは、PL/SQLユニットを定義、コンパイルおよび実行します。このエンジンは、Oracle AI Databaseを含む多数のOracle製品に組み込まれた特別なコンポーネントです。多くのOracle製品にPL/SQLコンポーネントが含まれていますが、このトピックでは、Oracle AI Databaseに格納でき、Oracle AI DatabaseのPL/SQLエンジンを使用して処理できるPL/SQLユニットについて説明します。各Oracleツール用のドキュメントでは、それぞれのPL/SQL機能について説明します。
次の図に、Oracle AI Databaseに含まれているPL/SQLエンジンを示します。
図3: PL/SQLエンジンとOracle AI Database

PL/SQLユニットは、データベースに格納されています。アプリケーションによってストアド・プロシージャをコールすると、データベースによって、コンパイルされたPL/SQLユニットがシステム・グローバル領域(SGA)内の共有プールにロードされます。PL/SQL文エグゼキュータとSQL文エグゼキュータは、連動してプロシージャ内の文を処理します。
別のPL/SQLブロック(無名ブロックまたは別のストアド・プロシージャ)からストアド・プロシージャをコールすることもできます。たとえば、Oracle Formsからストアド・プロシージャをコールできます。
Oracle AI Database上で実行されるPL/SQLプロシージャは、Cプログラミング言語で記述され、共有ライブラリに格納された外部プロシージャまたはファンクションをコールできます。Cルーチンは、Oracle AI Databaseとは別のアドレス空内で実行されます。
関連情報:
-
共有プールの目的および内容についてさらに学習するには、「共有プール」を参照してください
-
PL/ SQLアーキテクチャについて学習するには、『Oracle AI DatabasePL/ SQL言語リファレンス』
-
外部プロシージャについてさらに学習するには、『Oracle AI Database開発ガイド』を参照してください
Oracle AI DatabaseにおけるJavaの概要
Javaは、優れたオブジェクト指向プログラミング言語として登場しました。
Javaの機能は、次のとおりです。
-
Java仮想マシン(JVM)。プラットフォームの独立性を確保するための基礎を提供します。
-
自動ストレージ管理機能。ガベージ・コレクションなどがあります。
-
Cから借用し、強力な型指定を強制する言語構文ノート:この章では、Java言語に精通していることを前提としています。
データベースは、複雑な問合せおよび複数のデータ・ビューをサポートする動的データ処理エンジンを備えたJavaプログラムを提供しています。クライアント要求は、即時処理されるようにデータ問合せとして組み立てられます。問合せの結果は動的に生成されます。
JavaとOracle AI Databaseの組合せによって、ビジネス・ニーズの変化に従って簡単に更新できるコンポーネントベースでネットワーク中心のアプリケーションを作成できます。また、アプリケーションおよびデータ・ストアを、デスクトップ上およびインテリジェント・ネットワークやネットワーク中心のサーバーに移動できます。さらに重要なのは、任意のクライアント・デバイスからこれらのアプリケーションおよびデータ・ストアにアクセスできることです。
次の図は、従来の2層のクライアント/サーバー構成を示しています。この構成では、クライアントは、PL/SQLサブプログラムをコールする際と同じ方法でJavaストアド・プロシージャをコールします。
図4: 2層のクライアント/サーバー構成

-
Java Virtual Machine (JVM)の概要 JVMはコンパイル済のJavaコードを実行する仮想プロセッサである。
-
Java Programming Environment Oracleは、エンタープライズ・アプリケーション開発者に、Javaアプリケーションの作成、デプロイおよび管理用のエンドツーエンドJavaソリューションを提供しています。関連項目: Oracle AI DatabaseでのJavaの使用の概要は、Oracle AI Database Java開発スタート・ガイドを参照してください。
Java仮想マシン(JVM)の概要
JVMはコンパイル済のJavaコードを実行する仮想プロセッサである。
Javaソース・コードは、プラットフォームに依存しない低レベルのマシン命令(バイト・コードと呼ばれる)にコンパイルされます。Javaバイトコードは、JVMを介して、プラットフォームに依存する処理に解釈されます。
-
Oracle JVMの概要 Oracle JVMは、Pure Javaアプリケーションを実行する標準的なJava互換環境である。JLSおよびJVMの仕様と互換性があります。
-
Oracle JVMの主要コンポーネント Oracle JVMは、メモリー・ヒープを共有しそのリレーショナル・データに直接アクセスすることで、データベース・カーネルと同じ処理領域およびアドレス領域で実行されます。この設計によりメモリーの使用を最適化して、スループットを向上させます。
Oracle JVMの概要
Oracle JVMは、Pure Javaアプリケーションを実行する標準的なJava互換環境である。JLSおよびJVMの仕様と互換性があります。
Oracle JVMでは、標準のJavaバイナリ形式とAPIがサポートされます。また、Oracle AI Databaseは、実行時の動的クラス・ロードなど、標準のJava言語セマンティクスに準拠します。
次の図に、OracleのJavaアプリケーションがJavaコア・クラス・ライブラリの最上位に配置され、さらに、Oracle JVMの最上位に配置される様子を示します。OracleのJavaサポート・システムはデータベース内に配置されるので、JVMはオペレーティング・システムと直接対話するかわりに、データベースのライブラリと対話します。
図5: Javaコンポーネントの構造

他のJava環境とは異なり、Oracle JVMはOracle AI Database内に埋め込まれています。Oracle JVMと典型的なクライアントJVMには、いくつかの重要な違いがあります。たとえば、標準のJava環境では、コマンドラインで次のコマンドを発行し、インタプリタを介してJavaアプリケーションを実行します(classnameは、JVMにより最初に解釈されるクラス名です)。
java classname
このコマンドによって、オペレーティング・システム上のプロセス内でアプリケーションが実行されます。ただし、コマンドライン・インタフェースを使用していない場合は、アプリケーションをシステムにロードして、インタフェースをパブリッシュしてから、データベース・データ・ディクショナリ内でアプリケーションを実行する必要があります
参照: Oracle JVMと典型的なクライアントJVMのその他の相違の詳細は、『Oracle AI Database Java開発者ガイド』を参照してください。
Oracle JVMの主要コンポーネント
Oracle JVMはデータベースのメモリー・ヒープを共有してリレーショナル・データに直接アクセスするため、データベース・カーネルと同じ処理領域およびアドレス領域で実行されます。この設計によりメモリーの使用を最適化して、スループットを向上させます。
Oracle JVMは、Javaオブジェクトの実行時環境を提供します。Javaのデータ構造、メソッド・ディスパッチ、例外処理および言語レベル・スレッドを完全にサポートします。また、java.lang、java.io、java.net、java.mathおよびjava.utilなど、すべてのコアJavaクラス・ライブラリもサポートしています。
次の図に、Oracle JVMの主要なコンポーネントを示します。
図6: Oracle JVMの主要コンポーネント

Oracle JVMでは、標準のJavaネームスペースがデータベース・スキーマに埋め込まれます。この機能により、JavaプログラムはOracle AI Databaseに格納されたJavaオブジェクトおよび企業内のアプリケーション・サーバーにアクセスできます。
また、Oracle JVMは、データベースのスケーラブルな共有メモリー・アーキテクチャと緊密に統合されています。Javaプログラムでは、ユーザーの介入なしで、コール、セッションおよびオブジェクトの存続期間を効率的に使用します。結果として、セッションが継続状態であっても、Oracle JVMおよび中間層のJavaビジネス・オブジェクトのスケーラビリティを維持できます。
関連項目: Oracle JVMの主要なコンポーネントの詳細は、Oracle AI Database Java開発者ガイドに関する項を参照してください。
Javaプログラミング環境
Oracleは、Javaアプリケーションを作成、デプロイおよび管理するためのエンドツーエンドJavaソリューションをエンタープライズ・アプリケーション開発者に提供します。
このソリューションは、クライアント側とサーバー側のプログラム・インタフェース、Java開発をサポートするツール、およびOracle AI Databaseと統合されたJava Virtual Machineで構成されます。これらの製品はいずれも、Java標準との互換性を持っています。
Javaプログラミング環境は、次の追加機能で構成されています。
-
PL/SQLに等価および相当するJavaストアド・プロシージャ。Javaストアド・プロシージャは、PL/SQLと緊密に統合されています。Javaストアド・プロシージャはPL/SQLパッケージから、プロシージャはJavaストアド・プロシージャからコールできます。
-
SQLデータにアクセスするためのJDBCおよびSQLJプログラミング・インタフェース。
-
クラスの開発、ロードおよび管理を支援するツールおよびスクリプト。
-
Javaストアド・プロシージャJavaストアド・プロシージャとは、SQLにパブリッシュされデータベースに格納されるJavaメソッドのことです。
-
JavaおよびPL/SQLの統合既存のPL/SQLプログラムをJavaから呼び出すか、JavaプログラムをPL/SQLから呼び出すことができます。このソリューションでは、PL/SQLおよびJavaコードを保護して活用します。
Javaストアド・手順
Javaストアド・プロシージャとは、SQLにパブリッシュされデータベースに格納されるJavaメソッドのことです。
PL/SQLサブプログラムと同様に、Javaプロシージャには、SQL*Plusなどの製品で直接起動する方法と、トリガーを使用して間接的に起動する方法があります。また、Oracle NetクライアントOCI、プリコンパイラまたはJDBCからアクセスできます。
Javaメソッドをパブリッシュするには、Javaメソッド名、パラメータ・タイプおよび戻り型を対応するSQLにマップするコール仕様を記述します。クライアント・アプリケーションによってコールされた場合、Javaストアド・プロシージャでは、引数を受け取り、Javaクラスを参照してJava結果値を返すことができます。
アプリケーションは、コール仕様の名前を参照することにより、Javaメソッドをコールします。ランタイム・システムは、Oracleデータ・ディクショナリでコール仕様の定義を検索し、該当のJavaメソッドを実行します。
また、Javaを使用して、PL/SQLに依存しない強力なプログラムを開発することもできます。Oracle AI Databaseには、Javaプログラミング言語とJVMの完全準拠の実装が用意されています。
関連項目: 『Oracle AI Database Java開発者ガイド』では、Javaでストアド・プロシージャを記述する方法と、PL/SQLからストアド・プロシージャにアクセスする方法、およびJavaからPL/SQL機能にアクセスする方法について説明しています。
JavaおよびPL/SQLの統合
既存のPL/SQLプログラムをJavaからコールしたり、JavaプログラムをPL/SQLからコールできます。このソリューションでは、PL/SQLおよびJavaコードを保護して活用します。
Oracle AI Databaseでは、JavaからSQLデータにアクセスするためのJDBCがクライアントとサーバーの両方に用意されています。
- JDBCドライバJDBCはデータベース・アクセス・プロトコルであり、これによりユーザーがデータベースに接続してSQL文を実行し、データベースに問い合せることができるようになります。
JDBCドライバ
JDBCは、データベースがデータベースに接続してSQL文を実行し、データベースへの問合せを実行できるようにするデータベース・アクセス・プロトコルです。
コアJavaクラス・ライブラリには、JDBC APIのjava.sqlが1つのみ用意されています。ただし、JDBCは、ベンダーが特定のデータベースを必要に応じて特化するためのドライバを提供できるように設計されています。Oracleには、次の表に示す個々のJDBCドライバが用意されています。
表2 JDBCドライバ
| ドライバ | 摘要 |
|---|---|
| JDBC Thinドライバ | JDBC Thinドライバを使用すると、Oracle SQLのデータにアクセスする純粋なJavaアプリケーションおよびアプレットを作成できます。JDBC Thinドライバは、他のJavaアプレットと同様にWebページから動的にダウンロードできるため、Webベースのアプリケーションとアプレットに特に適しています。 |
| JDBC OCIドライバ | JDBC OCIドライバは、クライアントまたは中間層にあるOracle固有のネイティブ・コード(つまり非Javaコード)およびライブラリにアクセスし、JDBC Thinドライバに比べてパフォーマンスが向上しますが、サイズが極端に大きくなることと、クライアント側でのインストールというコストの問題があります。 |
| サーバー側JDBC内部ドライバ | Oracle AI Databaseは、サーバー上でJavaコードが実行される場合に、サーバー側内部ドライバを使用します。これにより、サーバーのOracle JVM内で実行中のJavaアプリケーションは、JDBCを使用してローカルに定義されたデータ(つまり、同じシステムの同じプロセスにあるデータ)にアクセスできます。また、基礎となるOracle RDBMSライブラリを直接使用できるため、パフォーマンスが向上し、JavaコードとSQLデータの間にネットワーク接続が介入することによるオーバーヘッドは発生しません。Oracle AI Databaseでは、サーバー上で同じJava-SQLインタフェースがサポートされるため、デプロイ時にコードの再操作を必要としません。 |
関連情報:
-
JDBCの概要は、Oracle AI Database開発ガイドを参照してください。
-
Oracle AI Database Java開発スタート・ガイドおよび『Oracle AI Database JDBC開発者ガイド』
Oracle AI DatabaseにおけるJavaScriptの概要
JavaScriptは、現在最も一般的なプログラミング言語の1つです。Linux x86-64またはLinux aarch64にデプロイされたOracle AI Databaseは、サーバー側開発でサポートされている言語のリストにJavaScriptを追加します。
JavaScriptのモジュールをデータベースに格納し、存続するデータを処理することで、クライアント側開発アプローチより大幅に改善される可能性があります。JavaScriptは、マルチリンガル・エンジン(MLE)によって実行されます。
開発者は、スタンドアロンのJavaScriptコードを実行するか、JavaScriptコードをデータベースにモジュールとしてネイティブに格納するかを選択できます。
-
データベースへのビジネス・ロジックのモジュールとしての格納クライアント側開発関連のJavaScriptと同様に、コードをモジュールの形式で一緒に格納できます。
-
JavaScriptコードの動的実行スタンドアロンJavaScriptコードを実行するフレーム開発者およびユーザーが、データベースにコードを格納する必要なく、
DBMS_MLEパッケージとそのサブルーチンを使用できます。 -
インラインJavaScriptストアド・プロシージャインラインMLEコール仕様は、
CREATE FUNCTIONおよびCREATE PROCEDUREのDDLにJavaScriptコードを直接埋め込みます。関連項目: Oracle AI DatabaseでのJavaScriptサポートについてさらに学習するには、『Oracle AI Database JavaScript開発者ガイド』を参照してください。
データベースへのビジネス・ロジックのモジュールとしての格納
クライアント側開発関連のJavaScriptと同様に、コードをモジュールの形式で一緒に格納できます。
PL/SQLバックグラウンドを持つ開発者は、JavaScriptモジュールはPL/SQLパッケージ本体と同等のものであると考えることができますが、JavaScriptで記述されています。モジュールで宣言されたファンクションは、エクスポートするために、またはプライベートを維持するためにマークできます。
Oracle AI DatabaseのJavaScriptは、ECMAScript 2023標準に準拠しており、データベース内にビジネス・ロジックを格納する様々な機能を開発ユーザーに提供します。
注意:
関連トピック
-
MLEモジュールの概要は、『Oracle AI Database JavaScript開発者ガイド』の第2章を参照。
-
コール仕様の詳細は、『Oracle AI Database JavaScript開発者ガイド』の第5章を参照してください。
MLEを使用してJavaScriptモジュールを作成する例を次に示します。
create mle module if not exists example_module
language javascript as
export function string2obj(inputString) {
if ( inputString === undefined ) {
throw `must provide a string in the form of key1=value1;...;keyN=valueN`;
}
let myObject = {};
if ( inputString.length === 0 ) {
return myObject;
}
const kvPairs = inputString.split(";");
kvPairs.forEach( pair => {
const tuple = pair.split("=");
if ( tuple.length === 1 ) {
tuple[1] = false;
} else if ( tuple.length != 2 ) {
throw "parse error: you need to use exactly one '=' between key and value and not use '=' in either key or value";
}
myObject[tuple[0]] = tuple[1];
});
return myObject;
}
/
MLEモジュールとも呼ばれるJavaScriptモジュールは、ユーザーのスキーマに格納されています。この唯一のファンクションstring2obj()は、コール仕様を作成してSQLおよびPL/SQLに公開できます。コール仕様は、SQLおよびPL/SQLをコールできるすべての場所でJavaScriptコードをコールできるPL/SQLプログラム・ユニットです。string2obj()のコール仕様は、次のように記述できます。
create function if not exists p_string_to_JSON(p_str varchar2) return JSON
as mle module example_module
signature 'string2obj(string)';
/
ファンクションが作成されると、SQLからコールできます。
declare
l_json JSON;
l_string VARCHAR2(100);
begin
l_string := 'a=1;b=2;c=3;d';
l_json := p_string_to_JSON(l_string);
dbms_output.put_line(json_serialize(l_json PRETTY));
end;
/
{
"a" : "1",
"b" : "2",
"c" : "3",
"d" : false
}
PL/SQL procedure successfully completed.
JavaScriptコードの動的実行
スタンドアロンJavaScriptコードを実行するフレームワーク開発者およびユーザーは、データベースにコードを格納する必要なく、DBMS_MLEパッケージとそのサブルーチンを使用できます。
たとえば、Oracle Application Expressおよびデータベース・アクションでは、DBMS_MLEを統合し、PL/SQLパッケージが起動されるという事実を隠します。
MLEモジュールと比較して、DBMS_MLEを使用すると、アプリケーション全体の記述がより難しくなります。たとえば、アプリケーションを個別のエンティティに論理的に分割することがより難しくなります。実行後デバッグ機能にはモジュールが必要で、コード・スニペットの問題のトラブルシューティングが難しくなります。継続的統合(CI)パイプラインでは、同じファイル内のPL/SQLコードとJavaScriptコードのlintに苦労する可能性があります。同様に、統合開発環境(IDE)でも問題が生じる可能性があります。ほとんどの環境では、PL/SQLとJavaScriptの両方を同じウィンドウで扱うことが困難であるためです。
注意:
関連トピック
-
DBMS_MLEおよびそのサブルーチンの詳細は、『Oracle AI Database PL/SQLパッケージおよびタイプ・リファレンス』を参照。 -
動的JavaScript呼出しの詳細は、『Oracle AI Database JavaScript開発者ガイド』の3章を参照してください。
インラインJavaScriptストアド・プロシージャ
インラインMLEコール仕様では、CREATE FUNCTIONおよびCREATE PROCEDUREのDDLにJavaScriptコードが直接埋め込まれます。
JavaScriptを使用して単純な機能を迅速に実装する場合は、インラインMLEコール仕様が適切な選択である可能性があります。このオプションでは、JavaScriptコードを含む別のモジュールをデプロイする必要はありません。JavaScriptファンクションはコール仕様自体の定義に組み込まれています。
MLE LANGUAGE句は、JavaScriptを使用してファンクションが実装されるように指定する際に使用します。言語名に続く文字列は、コール仕様の機能を実装するJavaScriptファンクションの本体として扱われます。コードが実行されると、PL/SQLパラメータはデフォルトのJavaScript型に自動的に変換され、同じ名前のパラメータとしてJavaScriptファンクションに渡されます。引用符で囲まれていないパラメータ名は、すべて大文字のJavaScript名にマップされます。JavaScriptファンクションにより戻される値は、MLEモジュールのコール指定と同様に、PL/SQLコール仕様の戻り型に変換されます。
トリガーの概要
データベース・トリガーはコンパイル済のストアド・プログラム・ユニットで、PL/SQL、JavaまたはJavaScriptのいずれかで記述され、特定の状況でOracle Databaseによって自動的に呼出し(起動)が行われます。
トリガーは、次のいずれかの操作が発生するたびに起動します。
-
特定の表またはビューで、ユーザーによってDML文が発行されたとき。
DML文は、スキーマ・オブジェクトのデータを変更します。たとえば、行の挿入および削除はDMLの処理です。
-
特定のユーザーまたは任意のユーザーが発行したDDL文
DDL文は、スキーマ・オブジェクトを定義します。たとえば、表の作成および列の追加はDDLの処理です。
-
データベースイベント
ユーザーのログインまたはログオフ、エラーおよびデータベースの起動または停止は、トリガーを起動できるイベントです。
トリガーはサブプログラムに類似したスキーマ・オブジェクトですが、起動方法が異なります。サブプログラムはユーザー、アプリケーションまたはトリガーによって明示的に実行されます。トリガーは、トリガー・イベントが発生したときにデータベースによって暗黙的に起動されます。
-
トリガーの利点トリガーを正しく使用すると、より堅牢な、データベースをもっと効果的に使用するアプリケーションを構築および配置できます。
-
トリガーのタイプトリガーは、起動方法と実行するアクションのタイプに応じて分類できます。
-
トリガーのタイミングトリガー・アクションがトリガー文の前後に実行されるかどうかに関係なく、トリガー・タイミングを定義できます。
-
トリガー作成
CREATE TRIGGER文はデータベース・トリガーを作成または置き換えます。 -
トリガーの実行 Oracle Databaseでは、サブプログラム実行と同じステップを使用して内部的にトリガーが実行されます。
-
トリガーの記憶域 Oracle Databaseでは、PL/SQLトリガーは、PL/SQLのストアド・プロシージャと同じように、コンパイル済形式でデータベース・スキーマに格納されます。
関連情報:
-
DMLおよびDDLについて学習するには、「SQL文の概要」
トリガーの利点
トリガーを正しく使用すると、ユーザーはデータベースをより効率的に使用するさらに堅牢なアプリケーションを構築してデプロイできます。
トリガーは、次のような目的で使用できます。
-
導出列の値の自動的な生成
-
無効なトランザクションの防止
-
監査およびイベント・ロギングの提供
-
表アクセスについての情報の記録
トリガーを使用して、すべてのクライアント・アプリケーションに共通の低レベルでのビジネス・ルールを強制実行できます。たとえば、複数のアプリケーションからemployees表にアクセスできます。この表でのトリガーで挿入されるデータの形式が保証される場合は、クライアントごとにこのビジネス・ロジックを再作成する必要はありません。アプリケーションはトリガーを回避できないため、トリガー内のビジネス・ロジックが自動的に使用されます。
トリガーと整合性制約を併用すると、任意の整合性規則を定義して規定できます。ただし、Oracleでは、整合性制約を使用して定義できない複雑なビジネス・ルールを適用するためにのみトリガーを使用することを強くお薦めします。
トリガーを過剰に使用すると相互依存関係が複雑になる可能性があります。また、大規模なアプリケーションでは管理が困難になります。たとえば、トリガーが起動されると、そのトリガー・アクションに含まれるSQL文によって他のトリガーが起動されてトリガーの連鎖状態になり、意図しない影響が起きる可能性があります。
関連情報:
-
アプリケーションのトリガーを計画する場合のガイドラインおよび制限については、Oracle AI Database PL/SQL言語リファレンスを参照してください。
特定の状況で自動的に)。
トリガーのタイプ
トリガーは、起動方法と実行するアクションのタイプに応じて分類できます。
Oracle Databaseは次のタイプのトリガーをサポートしています。
-
行トリガー
行トリガーは、表がトリガーを実行した文の処理の影響を受けるたびに起動されます。たとえば、文が複数の行を更新する場合、
UPDATEが処理する行ごとに1つずつ行トリガーが起動されます。トリガーを実行する文の影響を受ける行がなければ、行トリガーは実行されません。トリガー・アクションのコードが、トリガーを実行する文によって供給されるデータまたは影響を受ける行数に依存する場合には、行トリガーが便利です。 -
文トリガー
文トリガーは、トリガーを実行した文の影響を受ける行数とは関連なく、トリガーを実行した文の実行ごとに1回起動されます。たとえば、文が表から100行を削除すると、文レベルの
DELETEトリガーが1回のみ起動されます。トリガー・アクションのコードが、トリガーを実行する文によって供給されるデータや、影響を受ける行に依存しない場合には、文トリガーが便利です。 -
INSTEAD OFトリガーINSTEAD OFトリガーは、トリガーを実行する文のかわりに、Oracle Databaseによって起動される。これらのトリガーは、DML文を介して直接変更できないビューに透過的に変更する場合に便利です。
-
イベント・トリガー
トリガーを使用すると、データベース・イベントに関する情報を、サブスクライバに対して発行できます。イベント・トリガーは、次のカテゴリに分類されます。
-
システム・イベント・トリガーは、データベース・インスタンスの起動および停止やエラー・メッセージなどのイベントによって起動できます。
-
ユーザー・イベント・トリガーは、ユーザーのログオンおよびログオフに関連したイベントは、DDL文およびDML文によって起動されます。
-
特定の状況で自動的に)。
トリガーのタイミング
トリガー・アクションは、トリガー・アクションがトリガー文の前または後に実行されるかどうかにかかわらず、トリガー・タイミングを定義できます。
単純トリガーは表の単一のトリガーであり、次のいずれか1つのタイミング・ポイントに対してのみアクションを指定できます。
-
起動文の前
-
起動文によって影響を受ける各行の前
-
起動文によって影響を受ける各行の後
-
起動文の後
文および行のトリガーの場合、BEFOREトリガーは、セキュリティを高め、データベースに変更を加える前にビジネス・ルールを有効にできます。アクションのロギングには、AFTERトリガーが理想的です。
複合トリガーは、複数のタイミングポイントで起動する可能性があります。複合トリガーは、様々なタイミング・ポイントに対して実装するアクションで共通データを共有するためのアプローチをプログラム化する際に役立ちます。
複合トリガーについて学習するには、関連項目: Oracle AI Database PL/SQL言語リファレンスを参照してください。
特定の状況で自動的に)。
トリガーの作成
CREATE TRIGGER文はデータベース・トリガーを作成または置き換えます。
PL/SQLトリガーの一般的な構文形式は次のとおりです。
CREATE TRIGGER trigger_name
triggering_statement
[trigger_restriction]
BEGIN
triggered_action;
END;
PL/SQLトリガーの基本的なコンポーネントは次のとおりです。
-
トリガー名
名前は、同じスキーマ内の他のトリガーの中で一意であることが必要です。たとえば、
part_reorder_triggerのような名前にできます。 -
トリガー・イベントまたはトリガーを実行する文
トリガーを実行するイベントまたは文は、トリガーを起動するSQL文、データベース・イベントまたはユーザー・イベントのことです。たとえば、ユーザーが表を更新したとします。
-
トリガー制限
トリガー制限にはブール式を指定し、トリガーが起動されるにはその
trueになる必要があります。たとえば、引当可能部品の数量が現行の再発注数量より少なくなるまで、トリガーは起動されません。 -
トリガーされた処理
トリガー・アクションは、トリガーを実行する文が発行され、トリガーの制限がtrueに評価された場合に実行されるSQL文およびコードを含むプロシージャです。たとえば、ユーザーが保留中のorders表に行を挿入します。
-
例: CREATE TRIGGER文この例では、明細項目表で
INSERT文、UPDATE文またはDELETE文が実行されると起動するトリガーを作成します。 -
例: 行レベル・トリガーの起動このシナリオでは、顧客が2つのオーダーを開始し、オーダーの明細項目を追加または削除します。
関連情報:
-
トリガーを作成する方法を学習するには、『Oracle AI Database Oracle AI Database開発スタート・ガイド』および『Oracle AI Database PL/SQL言語リファレンス』を参照してください。
-
CREATE TRIGGER文について学習するには、Oracle AI Database SQL言語リファレンスを参照してください。
特定の状況で自動的に)。
例: CREATE TRIGGER文
この例では、明細項目表でINSERT文、UPDATE文またはDELETE文が実行されると起動されるトリガーを作成します。
次の文を使用してorders表およびlineitems表を作成するとします。orders表は一意のオーダーごとに行を保持するのに対して、lineitems表は1つのオーダー内の項目ごとに行を保持します。
CREATE TABLE orders
( order_id NUMBER PRIMARY KEY,
/* other attributes */
line_items_count NUMBER DEFAULT 0 );
CREATE TABLE lineitems
( order_id REFERENCES orders,
seq_no NUMBER,
/* other attributes */
CONSTRAINT lineitems PRIMARY KEY(order_id,seq_no) );
次の文で、orders表内のオーダーの項目数を自動的に更新するサンプル・トリガーを作成します。
CREATE OR REPLACE TRIGGER lineitems_trigger
AFTER INSERT OR UPDATE OR DELETE ON lineitems
FOR EACH ROW
BEGIN
IF (INSERTING OR UPDATING)
THEN
UPDATE orders SET line_items_count = NVL(line_items_count,0)+1
WHERE order_id = :new.order_id;
END IF;
IF (DELETING OR UPDATING)
THEN
UPDATE orders SET line_items_count = NVL(line_items_count,0)-1
WHERE order_id = :old.order_id;
END IF;
END;
/
lineitems_triggerでトリガーを実行する文は、lineitems表に対するINSERT、UPDATEまたはDELETEです。トリガー制限はありません。変更される行ごとに、トリガーが起動されます。トリガーは、トリガーを実行する文によって影響を受ける現在の行の、新旧の列値にアクセスできます。表の変更対象の列ごとに、古い値(:old)および新しい値(:new)の2つの相関名があります。セッションで、あるオーダーについてlineitemsの行を更新または挿入すると、このアクションの後、トリガーによってこのオーダーの項目数が計算され、orders表の数値が更新されます。
例: 行レベル・トリガーの起動
このシナリオでは、顧客は2つのオーダーを開始し、オーダーの明細項目を追加および削除します。
シナリオは、「例: CREATE TRIGGER文」で作成されたトリガーに基づいています。
表3行レベル・トリガーの使用例
| SQL文 | トリガーされるSQL文 | 摘要 |
|---|---|---|
SQL> INSERT INTO orders (order_id) VALUES (78); 1 row created. |
顧客がID78のオーダーを作成します。この時点で、顧客のオーダーに項目はありません。
|
|
SQL> INSERT INTO orders (order_id) VALUES (92); 1 row created. |
顧客がID92の別のオーダーを作成します。この時点で、顧客のオーダーに項目はありません。
|
|
SQL> INSERT INTO lineitems (order_id, seq_no) VALUES (78,1); 1 row created. |
UPDATE orders SET line_items_count = NVL(NULL,0)+1 WHERE order_id = 78; |
顧客がオーダー78に項目を追加します。
|
SQL> INSERT INTO lineitems (order_id, seq_no) VALUES (78,2); 1 row created. |
UPDATE orders SET line_items_count = NVL(1,0)+1 WHERE order_id = 78; |
顧客がオーダー78にさらに項目を追加します。
|
SQL> SELECT * FROM orders; ORDER_ID LINE_ITEMS_COUNT --------- ---------------- 78 2 92 0 |
顧客が2つのオーダーのステータスを問い合せます。オーダー78には2つの項目があります。オーダー92には項目がありません。 | |
SQL> SELECT * FROM lineitems; ORDER_ID SEQ_NO ---------- ---------- 78 1 78 2 |
顧客は明細項目のステータスを問い合せます。各項目は注文IDと順序番号によって一意に識別されます。 | |
SQL> UPDATE lineitems SET order_id = 92; 2 rows updated. |
UPDATE orders SET line_items_count = NVL(NULL,0)+1 WHERE order_id = 92; UPDATE orders SET line_items_count = NVL(2,0)-1 WHERE order_id = 78; UPDATE orders SET line_items_count = NVL(1,0)+1 WHERE order_id = 92; UPDATE orders SET line_items_count = NVL(1,0)-1 WHERE order_id = 78; |
顧客がオーダー78の明細項目をオーダー92に移動します。
トリガーが起動されるたびに、トリガー内の両方の |
SQL> SELECT * FROM orders; ORDER_ID LINE_ITEMS_COUNT --------- ---------------- 78 0 92 2 |
顧客が2つのオーダーのステータスを問い合せます。実際の結果としては、オーダー92の明細項目数が0から2に増加し、オーダー78の数が2から0に減少しています。 | |
SQL> SELECT * FROM lineitems; ORDER_ID SEQ_NO ---------- ---------- 92 1 92 2 |
顧客は明細項目のステータスを問い合せます。各項目は注文IDと順序番号によって一意に識別されます。 | |
SQL> DELETE FROM lineitems; 2 rows deleted. |
UPDATE orders SET line_items_count = NVL(2,0)-1 WHERE order_id = 92; UPDATE orders SET line_items_count = NVL(1,0)-1 WHERE order_id = 92; |
顧客はすべてのオーダーからすべての明細項目を削除します。
|
SQL> SELECT * FROM orders; ORDER_ID LINE_ITEMS_COUNT --------- ---------------- 78 0 92 0 SQL> SELECT * FROM lineitems; no rows selected |
顧客が2つのオーダーのステータスを問い合せます。どちらのオーダーにも明細項目がありません。 また、顧客は明細項目のステータスも問い合せます。項目は存在しません。 |
トリガーの実行
Oracle Databaseは、サブプログラムの実行と同じステップを使用してトリガーを内部的に実行します。
両者の唯一の違いは、ユーザー・アカウントがトリガー文を実行する権限を持っていれば、トリガーを起動する権限が付与されることです。この例外を除いて、データベースはストアド・サブプログラムと同じ方法でトリガーを検証して実行します。
トリガー実行についてさらに学習するには、『Oracle AI Database PL/SQL言語リファレンス』を参照してください。
特定の状況で自動的に)。
トリガーの記憶域
Oracle Databaseでは、PL/SQLトリガーは、PL/SQLのストアド・プロシージャと同じように、コンパイル済形式でデータベース・スキーマに格納されます。
CREATE TRIGGER文がコミットすると、コンパイルされたPL/SQLコードがデータベースに格納されます。共有プールからPL/SQLトリガーのソース・コードが削除されます。
次の図に示すデータベース・アプリケーションには、PL/SQLトリガーを暗黙のうちに起動するSQL文が含まれています。トリガーは、それに対応付けられている表とは別々に格納されています。
図7: トリガー

Javaトリガーは、PL/SQLトリガーと同じ方法で格納されます。ただし、Javaトリガーでは、CALL文を使用して、個別にコンパイルされたJavaコードを参照します。このため、Javaトリガーを作成する場合は、JavaコードおよびこのJavaコードを参照するトリガーを作成することが必要となります。
トリガーのコンパイルおよび格納について学習するには、『Oracle AI Database PL/SQL言語リファレンス』も参照してください。
特定の状況で自動的に)。