トリガーってエラーになると、引き金になった処理も失敗する。
ほとんどの場合、例外を呼び出す文がトリガーによって実行され、その例外が例外ハンドラによって処理されないと、データベースは、トリガーとそのトリガーを呼び出す文の両方の影響をロールバックします。
ただし例外もあります。詳しくはマニュアル参照。
で、この挙動を利用して接続を制御するためのトリガーを作ってみた。
こんな感じで作成。めずらしく 12.1 で検証。
CREATE OR REPLACE TRIGGER LOGON_TRIG
AFTER LOGON ON DATABASE
BEGIN
IF
UPPER(sys_context('USERENV','IP_ADDRESS')) != '192.168.56.21'
THEN
RAISE_APPLICATION_ERROR(-20500, 'User can not logon!' );
END IF;
END ;
/
この場合は、クライアントの IP address が 192.168.56.21 以外は接続できない。
クライアントの IP address が 192.168.56.21 で接続すると接続可能。
SQL> conn g/g
Connected.
192.168.56.21 以外から接続するとエラー。エラーはこんな感じ。
SQL> CONNECT g/g
ERROR:
ORA-04088: error during execution of trigger 'G.LOGON_TRIG'
ORA-00604: error occurred at recursive SQL level 1
ORA-20500: User can not logon!
ORA-06512: at line 8
ちなみに、システム権限 ADMINISTER DATABASE TRIGGER を持っていると、引き金になった処理が失敗しない。なので、DBA権限をもっていると接続できてしまう。
(ログイントリガー自体は、sys や DBA権限持ちにも効く)
ログオントリガーによるセキュリティ対応は推奨されていなので、ご利用は自己責任でお願いします。
そりゃ、そうだ。