Oracle PL/SQLパッケージ: タイプ、仕様、本体 [例]

パッケージインとは何ですか Oracle?

PL/SQL パッケージは、関連するサブプログラム (プロシージャ/関数) を 1 つの要素に論理的にグループ化したものです。パッケージはコンパイルされ、後で使用できるデータベース オブジェクトとして保存されます。

パッケージのコンポーネント

PL/SQL パッケージには XNUMX つのコンポーネントがあります。

  • パッケージ仕様
  • パッケージ本体

パッケージ仕様

パッケージ仕様はすべての公開宣言で構成されます variables、カーソル、オブジェクト、プロシージャ、関数、例外。

以下に、パッケージ仕様のいくつかの特徴を示します。

  • 仕様で宣言されている要素はすべて、パッケージの外部からアクセスできます。 このような要素はパブリック要素として知られています。
  • パッケージ仕様はスタンドアロン要素であるため、パッケージ本体がなくても単独で存在できます。
  • パッケージが参照するたびに、その特定のセッションに対してパッケージのインスタンスが作成されます。
  • セッションのインスタンスが作成された後、そのインスタンスで開始されたすべてのパッケージ要素は、セッションが終了するまで有効です。

構文

CREATE [OR REPLACE] PACKAGE <package_name> 
IS
<sub_program and public element declaration>
.
.
END <package name>

上記の構文は、パッケージ仕様の作成を示しています。

パッケージ本体

これは、パッケージ仕様に存在するすべての要素の定義で構成されます。 仕様で宣言されていない要素の定義を持つこともできます。これらの要素はプライベート要素と呼ばれ、パッケージ内からのみ呼び出すことができます。

以下にパッケージ本体の特徴を示します。

  • すべてのサブプログラムの定義が含まれている必要があります/カーソル 仕様で宣言されているもの。
  • また、仕様で宣言されていないサブプログラムやその他の要素を含めることもできます。 これらはプライベート要素と呼ばれます。
  • これは信頼できるオブジェクトであり、パッケージの仕様に依存します。
  • 仕様がコンパイルされるたびに、パッケージ本体の状態は「無効」になります。 したがって、仕様のコンパイル後に毎回再コンパイルする必要があります。
  • プライベート要素は、パッケージ本体で使用する前に最初に定義する必要があります。
  • パッケージの最初の部分はグローバル宣言部分です。 これには、パッケージ全体から見える変数、カーソル、プライベート要素 (前方宣言) が含まれます。
  • パッケージの最後の部分はパッケージ初期化部分で、セッション内で初めてパッケージが参照されるたびに XNUMX 回実行されます。

構文:

CREATE [OR REPLACE] PACKAGE BODY <package_name>
IS
<global_declaration part>
<Private element definition>
<sub_program and public element definition>
.
<Package Initialization> 
END <package_name>
  • 上記の構文は、パッケージ本体の作成を示しています。

次に、プログラム内でパッケージ要素を参照する方法を見ていきます。

パッケージ要素の参照

要素がパッケージ内で宣言および定義されたら、それらを使用するには要素を参照する必要があります。

パッケージのすべてのパブリック要素は、パッケージ名に続いてピリオドで区切られた要素名を呼び出すことによって参照できます。つまり、' 。 '。

パッケージのパブリック変数も同じ方法で使用して、値を割り当てたり、そこから値を取得したりできます。 。 '。

PL/SQLでパッケージを作成する

PL/SQL では、セッション内でパッケージが参照または呼び出されるたびに、そのパッケージの新しいインスタンスが作成されます。

Oracle 「パッケージの初期化」を通じて、このインスタンスの作成時にパッケージ要素を初期化したり、任意のアクティビティを実行したりする機能を提供します。

これは、すべてのパッケージ要素を定義した後にパッケージ本体に書き込まれる実行ブロックにすぎません。 このブロックは、セッション内で初めてパッケージが参照されるたびに実行されます。

構文

PL/SQLでパッケージを作成する

CREATE [OR REPLACE] PACKAGE BODY <package_name>
IS
<Private element definition>
<sub_program and public element definition>
.
BEGINE
<Package Initialization> 
END <package_name>
  • 上記の構文は、パッケージ本体でのパッケージ初期化の定義を示しています。

事前申告

パッケージ内の前方宣言/参照とは、プライベート要素を個別に宣言し、パッケージ本体の後半部分で定義することだけです。

プライベート要素は、パッケージ本体ですでに宣言されている場合にのみ参照できます。 このため、前方宣言が使用されます。 ただし、ほとんどの場合、プライベート要素はパッケージ本体の最初の部分で宣言および定義されるため、これを使用するのはかなり珍しいです。

前方宣言は、によって提供されるオプションです。 Oracle、これは必須ではなく、使用するかどうかはプログラマの要件次第です。

事前申告

構文:

CREATE [OR REPLACE] PACKAGE BODY <package_name>
IS
<Private element declaration>
.
.
.
<Public element definition that refer the above private element>
.
.
<Private element definition> 
.
BEGIN
<package_initialization code>; 
END <package_name>

上記の構文は前方宣言を示しています。プライベート要素はパッケージの前方部分で個別に宣言され、後半部分で定義されています。

パッケージ内でのカーソルの使用法

他の要素とは異なり、パッケージ内でカーソルを使用する場合は注意が必要です。

カーソルがパッケージ仕様またはパッケージ本体のグローバル部分で定義されている場合、一度開かれたカーソルはセッションが終了するまで持続します。

したがって、カーソルを参照する前に、常にカーソル属性 '%ISOPEN' を使用してカーソルの状態を確認する必要があります。

過負荷

オーバーロードは、同じ名前のサブプログラムを多数持つという概念です。 これらのサブプログラムは、パラメーターの数、パラメーターのタイプ、戻り値の型によって互いに異なります。つまり、名前は同じで、パラメーターの数、パラメーターのタイプ、または再タイプが異なるサブプログラムは、オーバーロードとみなされます。

これは、多くのサブプログラムが同じタスクを実行する必要があるが、それぞれの呼び出し方法が異なる必要がある場合に便利です。 この場合、サブプログラム名はすべて同じに保たれ、パラメーターは呼び出しステートメントに従って変更されます。

: この例では、「emp」テーブル内の従業員情報の値を取得および設定するパッケージを作成します。 get_record 関数は、指定された従業員番号のレコード タイプの出力を返し、set_record プロシージャは、そのレコード タイプのレコードを emp テーブルに挿入します。

ステップ1) パッケージ仕様の作成

過負荷

CREATE OR REPLACE PACKAGE guru99_get_set
IS
PROCEDURE set_record (p_emp_rec IN emp%ROWTYPE);
FUNCTION get record (p_emp no IN NUMBER) RETURN emp%ROWTYPE;
END guru99_get_set:
/

出力:

Package created

コードの説明

  • コード行 1 ~ 5: 99 つのプロシージャと XNUMX つの関数で guruXNUMX_get_set のパッケージ仕様を作成します。 これら XNUMX つは、このパッケージのパブリック要素になりました。

ステップ2) パッケージには、すべてのプロシージャと関数の実際の定義が定義されるパッケージ本体が含まれます。 このステップでは、パッケージ本体が作成されます。

過負荷

CREATE OR REPLACE PACKAGE BODY guru99_get_set
IS	
PROCEDURE set_record(p_emp_rec IN emp%ROWTYPE)
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO emp
VALUES(p_emp_rec.emp_name,p_emp_rec.emp_no; p_emp_rec.salary,p_emp_rec.manager);
COMMIT;
END set_record;
FUNCTION get_record(p_emp_no IN NUMBER)
RETURN emp%ROWTYPE
IS
l_emp_rec emp%ROWTYPE;
BEGIN
SELECT * INTO l_emp_rec FROM emp where emp_no=p_emp_no
RETURN l_emp_rec;
END get_record;
BEGUN	
dbms_output.put_line(‘Control is now executing the package initialization part');
END guru99_get_set:
/

出力:

Package body created

コードの説明

  • コード行 7: パッケージ本体を作成します。
  • コード行 9 ~ 16: 仕様で宣言されている要素「set_record」を定義します。 これは、PL/SQL でスタンドアロン プロシージャを定義するのと同じです。
  • コード行 17 ~ 24: 要素「get_record」を定義します。 スタンドアロン関数を定義するのと同じです。
  • コード行 25 ~ 26: パッケージの初期化部分を定義します。

ステップ3) 上記で作成したパッケージを参照して、レコードを挿入・表示する匿名ブロックを作成します。

過負荷

DECLARE
l_emp_rec emp%ROWTYPE;
l_get_rec emp%ROWTYPE;
BEGIN
dbms output.put line(‘Insert new record for employee 1004');
l_emp_rec.emp_no:=l004;
l_emp_rec.emp_name:='CCC';
l_emp_rec.salary~20000;
l_emp_rec.manager:=’BBB’;
guru99_get_set.set_record(1_emp_rec);
dbms_output.put_line(‘Record inserted');
dbms output.put line(‘Calling get function to display the inserted record'):
l_get_rec:=guru99_get_set.get_record(1004);
dbms_output.put_line(‘Employee name: ‘||l_get_rec.emp_name);
dbms_output.put_line(‘Employee number:‘||l_get_rec.emp_no);
dbms_output.put_line(‘Employee salary:‘||l_get_rec.salary');
dbms output.put line(‘Employee manager:‘||1_get_rec.manager);		
END:
/

出力:

Insert new record for employee 1004
Control is now executing the package initialization part
Record inserted
Calling get function to display the inserted record
Employee name: CCC
Employee number: 1004
Employee salary: 20000
Employee manager: BBB

コードの説明:

  • コード行 34 ~ 37: 無名ブロック内のレコード タイプ変数のデータを設定して、パッケージの「set_record」要素を呼び出します。
  • コード行 38: guru99_get_set パッケージの「set_record」への呼び出しが行われました。 これでパッケージがインスタンス化され、セッションが終了するまで保持されます。
  • これはパッケージへの最初の呼び出しであるため、パッケージの初期化部分が実行されます。
  • レコードは「set_record」要素によってテーブルに挿入されます。
  • コード行 41: 挿入された従業員の詳細を表示するには、「get_record」要素を呼び出します。
  • パッケージは、パッケージへの「get_record」呼び出し中に XNUMX 回目に参照されます。 ただし、パッケージはこのセッションですでに初期化されているため、今回は初期化部分は実行されません。
  • コード行 42 ~ 45: 従業員の詳細を印刷します。

パッケージ内の依存関係

パッケージは関連するものの論理的なグループであるため、いくつかの依存関係があります。以下は、注意する必要がある依存関係です。

  • 仕様はスタンドアロンのオブジェクトです。
  • パッケージ本体は仕様に依存します。
  • パッケージ本体は個別にコンパイルできます。 仕様がコンパイルされるたびに、本体は無効になるため、再コンパイルする必要があります。
  • private 要素に依存するパッケージ本体内のサブプログラムは、private 要素の宣言の後にのみ定義する必要があります。
  • 仕様および本文で参照されるデータベース オブジェクトは、パッケージのコンパイル時に有効なステータスである必要があります。

パッケージ情報

パッケージ情報が作成されると、パッケージソース、サブプログラムの詳細、オーバーロードの詳細などのパッケージ情報が、 Oracle データ定義テーブル。

以下の表に、データ定義テーブルとそのテーブルで使用できるパッケージ情報を示します。

テーブル名 詳細説明 クエリー
ALL_OBJECT object_id、creation_date、last_ddl_time などのパッケージの詳細を示します。すべてのユーザーによって作成されたオブジェクトが含まれます。 SELECT * FROM all_objects where object_name =' '
ユーザー_オブジェクト object_id、creation_date、last_ddl_time などのパッケージの詳細を示します。現在のユーザーによって作成されたオブジェクトが含まれます。 SELECT * FROM user_objects where object_name =' '
ALL_SOURCE すべてのユーザーが作成したオブジェクトのソースを提供します。 SELECT * FROM all_source where name=' '
USER_SOURCE 現在のユーザーが作成したオブジェクトのソースを示します。 SELECT * FROM user_source where name=' '
すべての手順 すべてのユーザーによって作成された、object_id、オーバーロードの詳細などのサブプログラムの詳細を示します。 SELECT * FROM all_procedures
ここで object_name=' '
USER_PROCEDURES 現在のユーザーによって作成されたサブプログラムの詳細 (object_id、オーバーロードの詳細など) を示します。 SELECT * FROM user_procedures
ここで object_name=' '

UTL ファイル – 概要

UTL ファイルは、によって提供される個別のユーティリティ パッケージです。 Oracle 特別なタスクを実行します。これは主に、PL/SQL パッケージまたはサブプログラムからオペレーティング システム ファイルの読み取りと書き込みに使用されます。情報を配置したり、ファイルから情報を取得したりするための個別の関数があります。ネイティブ文字セットでの読み取り/書き込みも可能です。

プログラマーはこれを使用して、あらゆるタイプのオペレーティング システム ファイルを書き込むことができ、ファイルはデータベース サーバーに直接書き込まれます。名前とディレクトリ パスは書き込み時に指定されます。

製品概要

これでパッケージについて学習しました。 PL / SQLの、これで次の作業ができるようになるはずです。

  • PL/SQL パッケージとそのコンポーネント
  • パッケージの特徴
  • パッケージ要素の参照とオーバーロード
  • パッケージ内の依存関係の管理
  • パッケージ情報の表示
  • UTLファイルとは何ですか