変数および定数の宣言と値の割当て

パッケージ仕様で宣言された変数または定数は、このパッケージにアクセスしている任意のプログラムで使用可能です。パッケージ本体またはサブプログラムで宣言された変数または定数は、そのパッケージまたはサブプログラムに対してローカルです。定数を宣言する場合、その定数に初期値を割り当てる必要があります。

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ファンクションで変数および定数を宣言するステップ:

  1. 「接続」フレームのhr_connを開きます。

  2. スキーマ・オブジェクト・タイプのリスト内で、「パッケージ」を展開します

  3. パッケージのリストで、EMP_EVALを展開します。

  4. 選択肢のリストで、EMP_EVALの本体を右クリックします。

    選択リストが表示されます。

  5. 選択肢のリストで、「編集」を選択します。

    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;
    
  6. RETURN NUMBER ASBEGINの間に、これらの変数および定数の宣言を追加します。

     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
    
     The title of the EMP_EVAL Bodypane changes to italic font, indicating that the code is not saved in the database.
    
  7. 「ファイル」メニューから、「保存」をクリックします。

    Oracle Databaseは、変更されたパッケージ本体をコンパイルおよび保存します。EMP_EVAL本体ペインのタイトルは、イタリック・フォントではなくなりました。

関連情報:

変数、定数およびパラメータに正しいデータ型があることの確認

変数、定数およびパラメータのデータ型が正しいことを確認するには、これらを%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 (「表の作成」で作成)の値を表します。

このため、各変数、定数およびパラメータは、それぞれの対応する列と同じデータ型を持ちます。

列のデータ型が変更されたら、変数、定数およびパラメータのデータ型を同じデータ型に変える必要があります。そうでない場合、CALCULATE_SCOREファンクションが無効になります。

変数、定数およびパラメータのデータ型が常に列データ型と一致することを確認するには、これらを%TYPE属性で宣言します。%TYPE属性によって、表列または他の変数のデータ型が提供されます。これにより、正しいデータ型割当てが確認されます。

関連情報:

チュートリアル: %TYPE属性を使用した宣言の変更

このチュートリアルでは、「SQL Developer」ツールの「編集」を使用して、EMP_EVAL.CALCULATE_SCOREファンクションの変数、定数および仮パラメータの宣言を変更して%TYPE属性を使用する方法を示します。

EMP_EVAL.CALCULATE_SCOREファンクションは、「チュートリアル: サブプログラムでの変数および定数の宣言」に示されています。

CALCULATE_SCOREの宣言を変更して%TYPEを使用するには:

  1. 「接続」フレーム内で、hr_connを展開します。

  2. スキーマ・オブジェクト・タイプのリスト内で、「パッケージ」を展開します。

  3. パッケージのリストで、EMP_EVALを展開します。

  4. 選択肢のリストで、EMP_EVALの本体を右クリックします。

  5. 選択肢のリストで、「編集」を選択します。

    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;
    
  6. 関数のコードで、次の変更を行います。

     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;
    
  7. EMP_EVALを右クリックします。

  8. 選択肢のリストで、「編集」を選択します。

    「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;
    
  9. 関数のコードで、次の変更を行います。

     FUNCTION calculate_score(evaluation_id IN scores.evaluation_id%TYPE
                             , performance_id IN scores.performance_id%TYPE)
    
  10. EMP_EVALを右クリックします。

  11. 選択肢のリストで、「コンパイル」を選択します。

  12. EMP_EVAL Bodyを右クリックします。

  13. 選択肢のリストで、「コンパイル」を選択します。

変数への値の割当て

次の方法で、値を変数に代入できます。

関連情報:

代入演算子を使用した変数への値の割当て

代入演算子(:=)を使用すると、サブプログラムの宣言部または実行可能部の変数に式の値を割り当てることができます。

サブプログラムの宣言部で、変数の宣言時に初期値を変数に割り当てることができます。構文:

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である必要があります。)

関連情報:

例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;