[ Oracle PL/SQL ] Package 変数や関数のアクセスレベル

Pocket

PL/SQL でパッケージを使用する際に SQL や PL/SQL から参照可能な変数やファンクション(プロシージャ)と参照できない変数やファンクションを作成するサンプルコードを掲載しています。詳細はコメントを参照ください。

スポンサーリンク

パッケージの仕様(宣言)
CREATE OR REPLACE PACKAGE TEST_PKG AS 

   -- パッケージ外から参照できるパブリック変数の宣言
   publicNumber  number := 100;
   
   -- パッケージ外から参照できるパブリック関数の宣言
   function publicFunction(p1 number) return number;

END;
パッケージの本体
CREATE OR REPLACE PACKAGE BODY TEST_PKG AS 

   /*
    * パッケージ外から参照できないプライベート変数
    * 
    */
   privateNumber number := 100;

   /*
    * プライベート関数の宣言
    * この宣言を書かない場合は、publicFunction関数の実装よりも
    * 先にprivateFunction関数の実装を記述しておかなくてはコンパイルエラーとなる
    */
   function privateFunction(p1 number) return number;
   
   /*
    * パッケージ外から参照できるパブリック関数の実装
    */
   function publicFunction(p1 number) return number
   is
   begin
       /*
        * プライベート関数の呼び出し
        */
       return privateFunction(p1);
   end;

   /*
    * パッケージ外から参照できないプライベート関数
    * 同一パッケージ内の関数やプロシージャからのみアクセスできる
    */
   function privateFunction(p1 number) return number
   is
     addNumber number := 30;
   begin
     return (p1 + privateNumber + addNumber); -- p1 + 100 + 30
   end;

END;

実行結果

以下のように、宣言部で記述したファンクションのみ参照できることがわかります。

select test_pkg.publicFunction(100) as ret from dual
/*
 * ret
 * --------------------
 * 230
 */

select test_pkg.privateFunction(100) from dual
/*
 * ORA-00911: 文字が無効です
 */
パブリック変数の参照結果

パブリック変数は、以下のように SQL からは参照することはできません。

select test_pkg.publicNumber as ret from dual
/*
 * ORA-06553: PLS-221 'test_pkg.publicNumber' がプロシージャでないか、または未定義です
 */
PL / SQL からパブリック変数にアクセス

パブリック変数は SQL から直接アクセスすることはできませんでしたが、PL/SQL からはアクセス可能です。

CREATE OR REPLACE FUNCTION TEST_FUNC RETURN NUMBER-- 戻り値のデータ型
IS
BEGIN

  -- 現在値を出力
  dbms_output.put_line('test_pkg.publicNumber'); -- 100

  -- 値を変更する
  test_pkg.publicNumber := 200;

  -- 変更した値を出力
  dbms_output.put_line('test_pkg.publicNumber'); -- 200

  return test_pkg.publicNumber;
END;
select TEST_FUNC() as ret from dual
/*
 * ret
 * --------------------
 * 200
 */
参考

 

スポンサーリンク


Pocket

Leave a Comment

Your email address will not be published. Required fields are marked *