Oracle PL/SQLパッケージ: タイプ、仕様、本体 [例]
⚡ スマートサマリー
PL/SQLパッケージは、関連するプロシージャ、関数、変数、カーソル、例外を、仕様と本体を持つ1つのスキーマオブジェクトにグループ化します。仕様は公開インターフェースを宣言し、本体はプライベートな実装を保持することで、モジュール性とパフォーマンスを向上させます。

パッケージインとは何ですか Oracle?
Oracle PL / SQLの パッケージは論理的なグループですping 関連する サブプログラム (プロシージャ/関数)を単一の要素にまとめます。パッケージはコンパイルされ、後で再利用できるデータベースオブジェクトとして保存されます。
パッケージのコンポーネント
PL/SQLパッケージは2つの構成要素から成り立っています。
- パッケージ仕様
- パッケージ本体
パッケージ仕様
パッケージ仕様は、すべての公開宣言から構成されます。 variables, カーソルオブジェクト、プロシージャ、関数、および 例外.
以下に、パッケージ仕様のいくつかの特徴を示します。
- 仕様書で宣言された要素は、パッケージの外部からアクセスできます。このような要素はパブリック要素と呼ばれます。
- パッケージ仕様は独立した要素であり、パッケージ本体がなくても単独で存在できることを意味します。
- パッケージが参照されるたびに、そのセッション専用のパッケージのインスタンスが作成されます。
- セッションのインスタンスが作成された後、そのインスタンスで開始されたすべてのパッケージ要素は、セッションが終了するまで有効です。
構文
CREATE [OR REPLACE] PACKAGE <package_name> IS <sub_program and public element declaration> . . END <package name>
上記の構文は、パッケージ仕様の作成方法を示しています。
パッケージ本体
パッケージ本体は、パッケージ仕様に存在するすべての要素の定義で構成されます。また、仕様で宣言されていない要素の定義を含めることもできます。これらの要素はプライベート要素と呼ばれ、パッケージ内部からのみ呼び出すことができます。
以下に、パッケージ本体の特性を示します。
- 仕様書で宣言されているすべてのサブルーチン/カーソルの定義が含まれている必要があります。
- また、仕様書に明記されていないサブルーチンやその他の要素を含めることもできます。これらはプライベート要素と呼ばれます。
- これは依存オブジェクトであり、パッケージ仕様に依存します。
- 仕様がコンパイルされるたびに、パッケージ本体の状態は「無効」になります。そのため、仕様のコンパイル後には毎回再コンパイルする必要があります。
- プライベート要素は、パッケージ本体で使用する前に最初に定義する必要があります。
- パッケージ本体の最初の部分は、グローバル宣言部分です。これには、パッケージ全体から参照可能な変数、カーソル、およびプライベート要素(前方宣言)が含まれます。
- パッケージの最後の部分は、パッケージの初期化部分であり、セッション内でパッケージが初めて参照されるたびに一度だけ実行されます。
構文:
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 「パッケージの初期化」を通じて、このインスタンスの作成時にパッケージ要素を初期化したり、任意のアクティビティを実行したりする機能を提供します。
これは、パッケージのすべての要素を定義した後、パッケージ本体に記述される実行ブロックです。このブロックは、セッション内でパッケージが初めて参照されるたびに実行されます。
以下のスクリーンショットは、パッケージを作成する際に、パッケージ初期化ブロックがパッケージ本体内にどのように配置されるかを示しています。
構文
CREATE [OR REPLACE] PACKAGE BODY <package_name> IS <Private element definition> <sub_program and public element definition> . BEGIN <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」を使用してカーソルの状態を確認する必要があります。
過負荷
オーバーロードとは、同じ名前を持つ複数のサブルーチンを作成する概念です。これらのサブルーチンは、引数の数、引数の型、または戻り値の型によって互いに異なります。つまり、同じ名前であっても、引数の数、引数の型、または戻り値の型が異なるサブルーチンは、オーバーロードとみなされます。
これは、複数のサブルーチンが同じタスクを実行する必要があるものの、それぞれの呼び出し方法を異なるものにしたい場合に便利です。この場合、サブルーチン名はすべて同じままで、呼び出し文に応じてパラメータが変更されます。
例1: この例では、「emp」テーブル内の従業員情報の値を取得および設定するためのパッケージを作成します。get_record関数は、指定された従業員番号に対応するレコードタイプの出力を返し、set_recordプロシージャは、そのレコードタイプのレコードをempテーブルに挿入します。
ステップ1)パッケージ仕様の作成
以下のスクリーンショットは、guru99_get_set パッケージ仕様が作成されている様子を示しています。 Oracle.
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
Code 説明
- Code 1行目~5行目: guru99_get_set のパッケージ仕様を、1つのプロシージャと1つの関数で作成します。これらは、このパッケージの公開要素となります。
ステップ2) パッケージにはパッケージ本体が含まれており、そこにすべてのプロシージャと関数の実際の定義が記述されています。このステップでは、パッケージ本体を作成します。
以下のスクリーンショットは、guru99_get_set パッケージ本体の定義を示しています。 Oracle.
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; BEGIN dbms_output.put_line('Control is now executing the package initialization part'); END guru99_get_set; /
出力:
Package body created
Code 説明
- Code 7行目: パッケージ本体を作成しています。
- Code 9行目~16行目: 仕様書で宣言されている要素「set_record」を定義します。これは、PL/SQLでスタンドアロンプロシージャを定義するのと同じです。
- Code 17行目~24行目: 要素「get_record」を定義します。これは、独立した関数を定義するのと同じです。
- Code 25行目~26行目: パッケージの初期化部分を定義します。
ステップ3) 上記で作成したパッケージを参照して、レコードを挿入および表示するための匿名ブロックを作成します。
以下のスクリーンショットは、パッケージを呼び出す匿名ブロックと、その出力を示しています。 Oracle.
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:=1004; l_emp_rec.emp_name:='CCC'; l_emp_rec.salary:=20000; l_emp_rec.manager:='BBB'; guru99_get_set.set_record(l_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:'||l_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
Code 説明:
- Code 34行目~37行目: パッケージの「set_record」要素を呼び出すために、匿名ブロック内でレコードタイプ変数のデータを設定します。
- Code 38行目: guru99_get_set パッケージの 'set_record' が呼び出されました。これでパッケージがインスタンス化され、セッション終了まで保持されます。これはパッケージへの最初の呼び出しであるため、パッケージの初期化部分が実行され、'set_record' 要素によってレコードがテーブルに挿入されます。
- Code 41行目: 挿入された従業員の詳細を表示するために、「get_record」要素を呼び出します。この呼び出し中にパッケージが2回目に参照されますが、パッケージはこのセッションで既に初期化されているため、初期化部分は再度実行されません。
- Code 42行目~45行目: 従業員の詳細を印刷します。
パッケージ内の依存関係
パッケージは論理グループであるためping 関連する事柄には、いくつかの依存関係があります。以下に、対処すべき依存関係を示します。
- 仕様書は独立したオブジェクトである。
- パッケージ本体は仕様に依存します。
- パッケージ本体は個別にコンパイルできます。仕様がコンパイルされるたびに、パッケージ本体も再コンパイルする必要があります。そうしないと、パッケージ本体は無効になってしまうからです。
- パッケージ本体内のサブルーチンで、プライベート要素に依存するものは、プライベート要素の宣言後にのみ定義されるべきである。
- 仕様書および本文中で参照されるデータベースオブジェクトは、パッケージコンパイル時に有効な状態である必要があります。
パッケージ情報
パッケージが作成されると、パッケージソース、サブルーチンの詳細、オーバーロードの詳細などのパッケージ情報が利用可能になります。 Oracle データ辞書テーブル。
以下の表は、データ辞書テーブルと、各テーブルで使用可能なパッケージ情報を示しています。
| テーブル名 | 詳細説明 | クエリー |
|---|---|---|
| すべてのオブジェクト | パッケージの詳細情報(オブジェクトID、作成日、最終DDL時刻など)を提供します。すべてのユーザーによって作成されたオブジェクトが含まれています。 | SELECT * FROM all_objects where object_name =' ' |
| ユーザーオブジェクト | パッケージの詳細情報(オブジェクトID、作成日、最終DDL時刻など)を提供します。現在のユーザーによって作成されたオブジェクトが含まれています。 | SELECT * FROM user_objects where object_name =' ' |
| ALL_SOURCE | すべてのユーザーが作成したオブジェクトのソースを提供します。 | SELECT * FROM all_source where name=' ' |
| USER_SOURCE | 現在のユーザーが作成したオブジェクトのソースを示します。 | SELECT * FROM user_source where name=' ' |
| すべての手順 | すべてのユーザーによって作成されたサブルーチンのオブジェクトID、オーバーロードの詳細などを表示します。 | SELECT * FROM all_procedures Where object_name=' ' |
| USER_PROCEDURES | 現在のユーザーによって作成されたサブプログラムの詳細 (object_id、オーバーロードの詳細など) を示します。 | SELECT * FROM user_procedures Where object_name=' ' |
UTL_FILE – 概要
UTL_FILEは、 Oracle 特殊なタスクを実行するために使用されます。主にPL/SQLパッケージまたはサブプログラムからオペレーティングシステムファイルを読み書きするために使用されます。ファイルへの情報入力とファイルからの情報取得のための独立した機能を備えています。また、ネイティブ文字セットでの読み書きも可能です。
プログラマーはこれを利用してあらゆる種類のオペレーティングシステムファイルを書き込むことができ、ファイルはデータベースサーバーに直接書き込まれます。書き込み時にファイル名とディレクトリパスが指定されます。





