VPDは表を検索したときに、検索したユーザーごとに表示する行を変える機能です。
WHERE句の検索条件を自動的に付与することによって実現します。

[oracle@DB01 ~]$ sqlplus / as sysdba

SQL> CREATE USER USER01 IDENTIFIED BY USER01;

ユーザーが作成されました。

SQL> CREATE USER USER02 IDENTIFIED BY USER02;

ユーザーが作成されました。

SQL> GRANT CREATE SESSION TO USER01,USER02;

権限付与が成功しました。

SQL> GRANT SELECT,UPDATE,DELETE ON SCOTT.EMP TO USER01,USER02;

権限付与が成功しました。


今回、USER01、USER02というユーザーを作り、それぞれに表示を変えるVPDを作成します。
対象はscottのemp表で、USER01はDEPTNO=10のみを表示し、USER02はDEPTNO=20のみを表示します。

SQL> CREATE OR REPLACE CONTEXT CTX1 USING SCOTT.PAC1;

コンテキストが作成されました。


コンテキストを作成します。
このコンテキストに値をセットできるのはscottユーザーのパッケージPAC1のみです。

SQL> CREATE OR REPLACE PACKAGE SCOTT.PAC1
  2  IS
  3     PROCEDURE PROC1;
  4  END;
  5  /

パッケージが作成されました。


SCOTT.PAC1を作成します。
まずは仕様部分

CREATE OR REPLACE PACKAGE BODY SCOTT.PAC1
IS
   PROCEDURE PROC1
   IS
      V_DEPTNO VARCHAR2(10);
   BEGIN
      IF USER = 'USER01' THEN
         V_DEPTNO := '10';
      ELSIF USER = 'USER02' THEN
         V_DEPTNO := '20';
      ELSE
         V_DEPTNO := NULL;
      END IF;
      DBMS_SESSION.SET_CONTEXT('CTX1','DEPTNO',V_DEPTNO);
   END PROC1;
END PAC1;
/

パッケージ本体が作成されました。


次に本体部分
パッケージに含まれるプロシージャがPROC1になります。
このPROC1が実行されるとコンテキスト内のDEPTNOにユーザーに応じた値がセットされます。

SQL> CONNECT SCOTT/password
接続されました。
SQL> show user
ユーザーは"SCOTT"です。
SQL> GRANT EXECUTE ON SCOTT.PAC1 TO SYSTEM;

権限付与が成功しました。


次にログオントリガーを作成します。
ユーザーがログオンした時に先のPROC1が実行されるようにします。

SQL> CONNECT system/password
接続されました。
SQL> show user
ユーザーは"SYSTEM"です。

CREATE OR REPLACE TRIGGER LOG_ON_TRIG
AFTER LOGON
ON DATABASE
BEGIN
  SCOTT.PAC1.PROC1;
END;
/

トリガーが作成されました。


systemユーザーにログインし、ログオントリガーを作成します。

SQL> CONNECT USER01/USER01
接続されました。
SQL> show USER
ユーザーは"USER01"です。
SQL> SELECT SYS_CONTEXT('CTX1','DEPTNO') FROM DUAL;

SYS_CONTEXT('CTX1','DEPTNO')
--------------------------------------------------------------------------------
10

SQL> CONNECT USER02/USER02
接続されました。
SQL> show USER
ユーザーは"USER02"です。
SQL> SELECT SYS_CONTEXT('CTX1','DEPTNO') FROM DUAL;

SYS_CONTEXT('CTX1','DEPTNO')
--------------------------------------------------------------------------------
20

それぞれのユーザーでログインし、コンテキストに格納される値を確認します。

今回はここまで。
次回はこの値を実際にwhere句に格納する所から始めます。