変数および定数の宣言と値の割当て
パッケージ仕様で宣言された変数または定数は、このパッケージにアクセスしている任意のプログラムで使用可能です。パッケージ本体またはサブプログラムで宣言された変数または定数は、そのパッケージまたはサブプログラムに対してローカルです。定数を宣言する場合、その定数に初期値を割り当てる必要があります。
PL/SQLのSQLに対する1つの大きな利点は、PL/SQLでは変数および定数の宣言および使用が可能なことです。
パッケージ仕様で宣言された変数または定数は、このパッケージにアクセスしている任意のプログラムで使用可能です。パッケージ本体またはサブプログラムで宣言された変数または定数は、そのパッケージまたはサブプログラムに対してローカルです。
variableは、特定のデータ型の値を保持します。ご使用のプログラムで、実行時に値を変更できます。constantは、変更できない値を保持します。
変数または定数には、任意のPL/SQLデータ型を指定できます。変数を宣言する場合、その変数に初期値が割り当てられます。値を宣言しない場合、初期値はNULLになります。定数を宣言する場合、その定数に初期値を割り当てる必要があります。初期値を変数または定数に割り当てるには、代入演算子(:=)を使用します。
ヒント:変更しないすべての値を定数として宣言します。この方法によって、コンパイル済コードが最適化され、ソース・コードのメンテナンスが簡単になります。
関連項目:変数および定数の一般情報は、Oracle Database PL/SQL言語リファレンスを参照してください
チュートリアル: サブプログラム内の変数および定数の宣言
このチュートリアルでは、SQL Developerの編集ツールを使用してEMP_EVAL.CALCULATE_SCOREファンクションで変数および制約を宣言する方法を示します。(このチュートリアルは、パッケージ本体を変更する例でもあります。)
EMP_EVAL.CALCULATE_SCOREファンクションは、「チュートリアル: パッケージ仕様部の作成」で指定されています。
CALCULATE_SCOREファンクションで変数および定数を宣言するステップ:
-
「接続」フレームのhr_connを開きます。
-
スキーマ・オブジェクト・タイプのリスト内で、「パッケージ」を展開します
-
パッケージのリストで、EMP_EVALを展開します。
-
選択肢のリストで、EMP_EVALの本体を右クリックします。
選択リストが表示されます。
-
選択肢のリストで、「編集」を選択します。
EMP_EVAL本体ペインが表示され、パッケージ本体のコードが表示されます:
CREATE OR REPLACE PACKAGE BODY EMP_EVAL AS PROCEDURE eval_department ( dept_id IN NUMBER ) AS BEGIN -- TODO implementation required for PROCEDURE EMP_EVAL.eval_department NULL; END eval_department; FUNCTION calculate_score ( evaluation_id IN NUMBER , performance_id IN NUMBER) RETURN NUMBER AS BEGIN -- TODO implementation required for FUNCTION EMP_EVAL.calculate_score RETURN NULL; END calculate_score; END EMP_EVAL; -
RETURN NUMBER ASとBEGINの間に、これらの変数および定数の宣言を追加します。n_score NUMBER(1,0); -- variable n_weight NUMBER; -- variable max_score CONSTANT NUMBER(1,0) := 9; -- constant, initial value 9 max_weight CONSTANT NUMBER(8,8) := 1; -- constant, initial value 1The title of the EMP_EVAL Bodypane changes to italic font, indicating that the code is not saved in the database. -
「ファイル」メニューから、「保存」をクリックします。
Oracle Databaseは、変更されたパッケージ本体をコンパイルおよび保存します。EMP_EVAL本体ペインのタイトルは、イタリック・フォントではなくなりました。
関連情報:
-
変数および定数の宣言の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。
変数、定数およびパラメータに正しいデータ型があることの確認
変数、定数およびパラメータのデータ型が正しいことを確認するには、これらを%TYPE属性で宣言します。
「チュートリアル: サブプログラム内の変数および定数の宣言」の後のEMP_EVAL.CALCULATE_SCORE関数のコードは、次のとおりです。
FUNCTION calculate_score ( evaluation_id IN NUMBER
, performance_id IN NUMBER )
RETURN NUMBER AS
n_score NUMBER(1,0); -- variable
n_weight NUMBER; -- variable
max_score CONSTANT NUMBER(1,0) := 9; -- constant, initial value 9
max_weight CONSTANT NUMBER(8,8) := 1; -- constant, initial value 1
BEGIN
-- TODO implementation required for FUNCTION EMP_EVAL.calculate_score
RETURN NULL;
END calculate_score;
関数の変数、定数およびパラメータは、表SCORESおよびPERFORMANCE_PARTS (「表の作成」で作成)の値を表します。
-
変数n_scoreは、SCORE.SCORES列の値を保持し、定数max_scoreは、この値と比較されます。
-
変数n_weightは、PERFORMANCE_PARTS.WEIGHT列の値を保持し、定数max_weightは、それらの値と比較されます。
-
パラメータevaluation_idは、SCORE.EVALUATION_ID列の値を保持します。
-
パラメータperformance_idは、SCORE.PERFORMANCE_ID列の値を保持します。
このため、各変数、定数およびパラメータは、それぞれの対応する列と同じデータ型を持ちます。
列のデータ型が変更されたら、変数、定数およびパラメータのデータ型を同じデータ型に変える必要があります。そうでない場合、CALCULATE_SCOREファンクションが無効になります。
変数、定数およびパラメータのデータ型が常に列データ型と一致することを確認するには、これらを%TYPE属性で宣言します。%TYPE属性によって、表列または他の変数のデータ型が提供されます。これにより、正しいデータ型割当てが確認されます。
関連情報:
-
%TYPE属性の詳細は、Oracle Database PL/SQL言語リファレンスを参照してください。 -
%TYPE属性の構文は、『Oracle Database PL/SQL言語リファレンス』を参照してください。
チュートリアル: %TYPE属性を使用した宣言の変更
このチュートリアルでは、「SQL Developer」ツールの「編集」を使用して、EMP_EVAL.CALCULATE_SCOREファンクションの変数、定数および仮パラメータの宣言を変更して%TYPE属性を使用する方法を示します。
EMP_EVAL.CALCULATE_SCOREファンクションは、「チュートリアル: サブプログラムでの変数および定数の宣言」に示されています。
CALCULATE_SCOREの宣言を変更して%TYPEを使用するには:
-
「接続」フレーム内で、hr_connを展開します。
-
スキーマ・オブジェクト・タイプのリスト内で、「パッケージ」を展開します。
-
パッケージのリストで、EMP_EVALを展開します。
-
選択肢のリストで、EMP_EVALの本体を右クリックします。
-
選択肢のリストで、「編集」を選択します。
EMP_EVAL本体が表示され、パッケージ本体のコードが表示されます。
CREATE OR REPLACE PACKAGE BODY emp_eval AS PROCEDURE eval_department ( dept_id IN NUMBER ) AS BEGIN -- TODO implementation required for PROCEDURE EMP_EVAL.eval_department NULL; END eval_department; FUNCTION calculate_score ( evaluation_id IN NUMBER , performance_id IN NUMBER ) RETURN NUMBER AS n_score NUMBER(1,0); -- variable n_weight NUMBER; -- variable max_score CONSTANT NUMBER(1,0) := 9; -- constant, initial value 9 max_weight CONSTANT NUMBER(8,8) := 1; -- constant, initial value 1 BEGIN -- TODO implementation required for FUNCTION EMP_EVAL.calculate_score RETURN NULL; END calculate_score; END emp_eval; -
関数のコードで、次の変更を行います。
FUNCTION calculate_score ( evaluation_id IN SCORES.EVALUATION_ID%TYPE , performance_id IN SCORES.PERFORMANCE_ID%TYPE) RETURN NUMBER AS n_score SCORES.SCORE%TYPE; n_weight PERFORMANCE_PARTS.WEIGHT%TYPE; max_score CONSTANT SCORES.SCORE%TYPE := 9; max_weight CONSTANT PERFORMANCE_PARTS.WEIGHT%TYPE := 1; -
EMP_EVALを右クリックします。
-
選択肢のリストで、「編集」を選択します。
「EMP_EVAL」ペインが開いて、パッケージを作成したCREATE PACKAGE文が表示されます。
CREATE OR REPLACE PACKAGE EMP_EVAL AS PROCEDURE eval_department(dept_id IN NUMBER); FUNCTION calculate_score(evaluation_id IN NUMBER , performance_id IN NUMBER) RETURN NUMBER; END EMP_EVAL; -
関数のコードで、次の変更を行います。
FUNCTION calculate_score(evaluation_id IN scores.evaluation_id%TYPE , performance_id IN scores.performance_id%TYPE) -
EMP_EVALを右クリックします。
-
選択肢のリストで、「コンパイル」を選択します。
-
EMP_EVAL Bodyを右クリックします。
-
選択肢のリストで、「コンパイル」を選択します。
変数への値の割当て
次の方法で、値を変数に代入できます。
-
代入演算子を使用して、変数に式の値を割り当てます。
-
SELECT INTO文またはFETCH文を使用して、値を表から割り当てます。
-
変数をOUTまたはIN OUTパラメータとしてサブ プログラムに渡した後、サブプログラム内で値を割り当てます。
-
変数を値にバインドします。
関連情報:
-
変数への値の割当ての詳細は、Oracle Database PL/SQL言語リファレンスを参照してください。
-
変数のバインドの詳細は、『Oracle Database 2日間でJava開発者ガイド』を参照してください。
代入演算子を使用した変数への値の割当て
代入演算子(:=)を使用すると、サブプログラムの宣言部または実行可能部の変数に式の値を割り当てることができます。
サブプログラムの宣言部で、変数の宣言時に初期値を変数に割り当てることができます。構文:
variable_name data_type := expression;
サブプログラムの実行可能部で、代入文で値を変数に割り当てることができます。構文:
variable_name := expression;
例5-1では、EMP_EVAL.CALCULATE_SCOREファンクションに対して行う変更が太字表示されて、変数running_totalが追加され、この新しい変数の値がファンクションの戻り値として使用されます。代入演算子は、ファンクションの宣言部と実行可能部の両方に表示されます。(running_totalのデータ型は、異なる精度およびスケールを持つ2つのNUMBER値の積を保持するため、SCORES.SCORE%TYPEまたはPERFORMANCE_PARTS.WEIGHT%TYPEではなく、NUMBERである必要があります。)
関連情報:
-
変数宣言の構文は、Oracle Database PL/SQL言語リファレンスを参照してください。
-
割当て文の構文はOracle Database PL/SQL言語リファレンスを参照
例5-1 代入演算子を使用した変数への値の割当て
FUNCTION calculate_score(evaluation_id IN SCORES.EVALUATION_ID%TYPE
, performance_id IN SCORES.PERFORMANCE_ID%TYPE)
RETURN NUMBER AS
n_score SCORES.SCORE%TYPE;
n_weight PERFORMANCE_PARTS.WEIGHT%TYPE;
running_total NUMBER := 0;
max_score CONSTANT SCORES.SCORE%TYPE := 9;
max_weight CONSTANT PERFORMANCE_PARTS.WEIGHT%TYPE:= 1;
BEGIN
running_total := max_score * max_weight;
RETURN running_total;
END calculate_score;
SELECT INTO文を使用した変数への値の割当て
サブプログラムまたはパッケージの表の値を使用するには、これらをSELECT INTO文で変数に割り当てる必要があります。例5-2では、表の値からrunning_totalを計算させるためにEMP_EVAL.CALCULATE_SCOREファンクションに対して加えられる変更を太文字で示しています。
例5-3に示すADD_EVALプロシージャは、EVALUATIONS表への行挿入に、EMPLOYEES表の対応する行の値を使用する場合の例です。ADD_EVALプロシージャをEMP_EVALパッケージの本体に追加しますが、仕様には行いません。仕様内にはないので、ADD_EVALはパッケージに対してローカルであり、パッケージ内の他のサブプログラムによってのみ起動でき、パッケージ外部からは呼出しできません。
関連項目: SELECT INTO文の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。
例5-2 SELECT INTOを使用した変数への表の値の割当て
FUNCTION calculate_score ( evaluation_id IN scores.evaluation_id%TYPE
, performance_id IN scores.performance_id%TYPE )
RETURN NUMBER AS
n_score scores.score%TYPE;
n_weight performance_parts.weight%TYPE;
running_total NUMBER := 0;
max_score CONSTANT scores.score%TYPE := 9;
max_weight CONSTANT performance_parts.weight%TYPE:= 1;
BEGIN
SELECT s.score INTO n_score
FROM SCORES s
WHERE evaluation_id = s.evaluation_id
AND performance_id = s.performance_id;
SELECT p.weight INTO n_weight
FROM PERFORMANCE_PARTS p
WHERE performance_id = p.performance_id;
running_total := n_score * n_weight;
RETURN running_total;
END calculate_score;
例5-3 他の表からの値を使用した表の行の挿入
PROCEDURE add_eval ( employee_id IN EMPLOYEES.EMPLOYEE_ID%TYPE
, today IN DATE )
AS
job_id EMPLOYEES.JOB_ID%TYPE;
manager_id EMPLOYEES.MANAGER_ID%TYPE;
department_id EMPLOYEES.DEPARTMENT_ID%TYPE;
BEGIN
INSERT INTO EVALUATIONS (
evaluation_id,
employee_id,
evaluation_date,
job_id,
manager_id,
department_id,
total_score
)
SELECT
evaluations_sequence.NEXTVAL, -- evaluation_id
add_eval.employee_id, -- employee_id
add_eval.today, -- evaluation_date
e.job_id, -- job_id
e.manager_id, -- manager_id
e.department_id, -- department_id
0 -- total_score
FROM employees e;
IF SQL%ROWCOUNT = 0 THEN
RAISE NO_DATA_FOUND;
END IF;
END add_eval;