CREATE PACKAGE BODYステートメントは、保存済みパッケージの本文を作成します。 CREATE OR REPLACE PACKAGE BODYステートメントは、新しいパッケージボディを作成するか、既存のパッケージボディを置き換えます。 パッケージは、データベースアプリケーションロジックを整理およびカプセル化するための重要なツールです。 保存されたパッケージを適切に設計すると、コードの保守性、再利用性、パフォーマンスが向上します。
概要
CREATE PACKAGE BODYステートメントを使用して、関連するプロシージャ、ストアド関数、およびデータベースに一緒に格納された他のプログラムオブジェクトのカプセル化されたコレクションであるストアドパッケージのボディを作成できます。 パッケージ本体はこれらのオブジェクトを定義します。 CREATE packageステートメントを使用して定義されるパッケージ仕様は、これらのオブジェクトを宣言します。
構文
CREATE [ OR REPLACE ] PACKAGE BODY <package_name>
{ IS | AS }
[ declaration; ] | [ forward_declaration ] [, ...]
[ { PROCEDURE <proc_name>
[ (<argname> [ IN | IN OUT | OUT ] <argtype> [ DEFAULT <value> ] [, ...]) ]
[ STRICT ]
[ LEAKPROOF ]
[ PARALLEL { UNSAFE | RESTRICTED | SAFE } ]
[ COST <execution_cost> ]
[ ROWS <result_rows> ]
[ SET <config_param> { TO <value> | = <value> | FROM CURRENT } ]
{ IS | AS }
<program_body>
END [ <proc_name> ];
|
FUNCTION <func_name>
[ (<argname> [ IN | IN OUT | OUT ] <argtype> [ DEFAULT <value> ] [, ...]) ]
RETURN <rettype> [ DETERMINISTIC ]
[ STRICT ]
[ LEAKPROOF ]
[ PARALLEL { UNSAFE | RESTRICTED | SAFE } ]
[ COST <execution_cost> ]
[ ROWS <result_rows> ]
[ SET <config_param> { TO <value> | = <value> | FROM CURRENT } ]
{ IS | AS }
<program_body>
END [ <func_name> ];
}
] [, ...]
[ BEGIN
<statement>; [, ...] ]
END [ <name> ]
Where forward_declaration:=
[ { PROCEDURE <proc_name>
[ (<argname> [ IN | IN OUT | OUT ] <argtype> [ DEFAULT <value> ] [, ...])
] ;
|
FUNCTION <func_name>
[ (<argname> [ IN | IN OUT | OUT ] <argtype> [ DEFAULT <value> ] [, ...])
]
RETURN <rettype> [ DETERMINISTIC ]; }]Parameters
パラメーター | 説明 |
package_name | パッケージの名前。 |
declaration | プライベート変数、型、カーソル、または |
forward_declaration | フォワード宣言。実際に定義される前にプロシージャまたは関数を宣言するために使用されます。 モジュールでは、複数のサブプログラムを作成できます。 これらのサブプログラムが互いにコールする場合、各サブプログラムはフォワード宣言を必要とする。 サブプログラムは、呼び出す前に宣言する必要があります。 特定の定義なしでフォワード宣言を使用してサブプログラムを宣言できます。 forward宣言と対応する定義は、同じコードブロック内にある必要があります。 |
proc_name | パブリックストアドプロシージャの名前。 |
func_name | パブリック関数の名前。 |
STRICT |
|
LEAKPROOF |
|
PARALLEL { UNSAFE | RESTRICTED | SAFE } |
|
execution_cost | 関数の推定実行コスト。 それは正の数でなければなりません。 単位は cpu_operator_cost です。 関数がセットを返す場合、返された各行のコストを示します。 デフォルト値は 0.0025 です。 |
result_rows | 関数が返すとプランナーが予想する行の推定数。 既定値は 1000 です。 |
SET | SET句を使用して、関数の期間のパラメーター値を指定できます。 有効な値:
|
program_body | 関数またはストアドプロシージャの本体を構成する |
argname | パラメータの名前。 |
IN | IN OUT | OUT | パラメーターのタイプ。 有効な値: |
argtype | プログラム引数のデータタイプ。 |
DEFAULT value | 入力引数のデフォルト値。 |
rettype | 返されるデータ型。 |
DETERMINISTIC | DETERMINISTIC を使用すると、同じ引数値が指定されている場合、関数が常に同じ結果を返すように指定できます。 DETERMINISTIC 関数はデータベースを変更しません。 |
文 |
|
例
次の例は、パッケージの作成方法と使用方法を示しています。
テストテーブルを作成します。
CREATE TABLE employees ( emp_id NUMBER PRIMARY KEY, first_name VARCHAR2(50), last_name VARCHAR2(50), salary NUMBER, department VARCHAR2(50) );パッケージヘッダーを作成します。
CREATE OR REPLACE PACKAGE Employee_Pkg AS -- Constant MAX_SALARY CONSTANT NUMBER := 100000; -- Procedure declaration PROCEDURE Add_Employee( p_emp_id IN NUMBER, p_first_name IN VARCHAR2, p_last_name IN VARCHAR2, p_salary IN NUMBER ); PROCEDURE Update_Salary( p_emp_id IN NUMBER, p_new_salary IN NUMBER ); -- Function declaration FUNCTION Get_Employee_Name( p_emp_id IN NUMBER ) RETURN VARCHAR2; FUNCTION Get_Employee_Department( p_emp_id IN NUMBER ) RETURN VARCHAR2; END Employee_Pkg;パッケージ本体を作成します。
CREATE OR REPLACE PACKAGE BODY Employee_Pkg AS -- Private variable g_total_employees NUMBER := 0; -- Procedure implementation PROCEDURE Add_Employee( p_emp_id IN NUMBER, p_first_name IN VARCHAR2, p_last_name IN VARCHAR2, p_salary IN NUMBER ) IS BEGIN INSERT INTO employees (emp_id, first_name, last_name, salary) VALUES (p_emp_id, p_first_name, p_last_name, p_salary); g_total_employees := g_total_employees + 1; END Add_Employee; PROCEDURE Update_Salary( p_emp_id IN NUMBER, p_new_salary IN NUMBER ) IS BEGIN IF p_new_salary > MAX_SALARY THEN RAISE_APPLICATION_ERROR(-20001, 'Salary exceeds maximum allowed.'); END IF; UPDATE employees SET salary = p_new_salary WHERE emp_id = p_emp_id; END Update_Salary; -- Function implementation FUNCTION Get_Employee_Name( p_emp_id IN NUMBER ) RETURN VARCHAR2 IS v_name VARCHAR2(100); BEGIN SELECT first_name || ' ' || last_name INTO v_name FROM employees WHERE emp_id = p_emp_id; RETURN v_name; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN 'Employee Not Found'; END Get_Employee_Name; FUNCTION Get_Employee_Department( p_emp_id IN NUMBER ) RETURN VARCHAR2 IS v_department VARCHAR2(100); BEGIN SELECT department INTO v_department FROM employees WHERE emp_id = p_emp_id; RETURN v_department; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN 'Not Assigned'; END Get_Employee_Department; END Employee_Pkg;パッケージを使用します。
DECLARE v_name VARCHAR2(100); v_department VARCHAR2(100); BEGIN Employee_Pkg.Add_Employee( p_emp_id => 1001, p_first_name => 'Jane', p_last_name => 'Smith', p_salary => 60000 ); Employee_Pkg.Add_Employee( p_emp_id => 1002, p_first_name => 'John', p_last_name => 'Doe', p_salary => 55000 ); Employee_Pkg.Update_Salary( p_emp_id => 1001, p_new_salary => 65000 ); v_name := Employee_Pkg.Get_Employee_Name(1001); v_department := Employee_Pkg.Get_Employee_Department(1001); DBMS_OUTPUT.PUT_LINE('NAME: ' || v_name); DBMS_OUTPUT.PUT_LINE('DEPARTMENT: ' || v_department); END;