1. 程式人生 > >(十二)PL/SQL觸發器

(十二)PL/SQL觸發器

-s 一些事 lar err 示例 cut erro color new

觸發器是存儲程序,它會自動執行或發射當一些事件發生。觸發器,事實上,寫入響應於以下任一事件將被執行:
  數據庫操作(DML)語句(DELETE,INSERT,UPDATE或)
  數據庫定義(DDL)語句(CREATE,ALTER或DROP)
  數據庫操作(SERVERERROR,登錄,註銷,啟動或關機)
觸發器可以在表,視圖,模式或數據庫與該事件相關聯上定義。


觸發器的優點
自動生成一些派生列值
實施參照完整性
事件日誌和對表的訪問存儲信息
審計
表的同步復制
實行安全許可
防止非法交易


一、創建觸發器
創建觸發器的語法:
  CREATE [OR REPLACE ] TRIGGER trigger_name


  {BEFORE | AFTER | INSTEAD OF }
  {INSERT [OR] | UPDATE [OR] | DELETE}
   [OF col_name]
   ON table_name
   [REFERENCING OLD AS o NEW AS n]
   [FOR EACH ROW]
   WHEN (condition)
   DECLARE
   Declaration-statements
   BEGIN
   Executable-statements
   EXCEPTION
   Exception-handling-statements

   END;
那麽,
  CREATE [OR REPLACE] TRIGGER trigger_name: 創建或替換現有的觸發器:trigger_name
  {BEFORE | AFTER | INSTEAD OF} : 指定當觸發將被執行。在INSTEAD OF子句用於在視圖中創建觸發器
  {INSERT [OR] | UPDATE [OR] | DELETE}: 指定DML操作
   [OF col_name]: 指定將被更新的列名
   [ON table_name]: 指定觸發器相關聯的表的名稱
  [REFERENCING OLD AS o NEW AS n]: 可以參考新舊值的各種DML語句,如INSERT,UPDATE和DELETE

   [FOR EACH ROW]: 指定的行級觸發器,即觸發器將每一行受到影響執行。否則,當執行SQL語句,這被稱為表級觸發器觸發將執行一次
  WHEN (condition): 觸發器將觸發的條件。此子句僅適用於行級觸發器有效

示例:
首先使用CUSTOMERS表:
Select * from customers;
+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2000.00 |
| 2 | Khilan | 25 | Delhi | 1500.00 |
| 3 | kaushik | 23 | Kota | 2000.00 |
| 4 | Chaitali | 25 | Mumbai | 6500.00 |
| 5 | Hardik | 27 | Bhopal | 8500.00 |
| 6 | Komal | 22 | MP | 4500.00 |
+----+----------+-----+-----------+----------+

下面的程序創建了customers表中,將觸發INSERT或UPDATE或DELETE在Customers表進行操作的行級觸發。觸發器將顯示工資的舊值和新值之間的差額:

CREATE OR REPLACE TRIGGER display_salary_changes
BEFORE DELETE OR INSERT OR UPDATE ON customers
FOR EACH ROW
WHEN (NEW.ID > 0)
DECLARE
   sal_diff number;
BEGIN
   sal_diff := :NEW.salary  - :OLD.salary;
   dbms_output.put_line(‘Old salary: ‘ || :OLD.salary);
   dbms_output.put_line(‘New salary: ‘ || :NEW.salary);
   dbms_output.put_line(‘Salary difference: ‘ || sal_diff);
END;
/
當上述代碼在SQL提示符執行時,它產生了以下結果:
Trigger created.

這裏以下兩點是重要的,應小心註意:
  OLD和NEW引用是不可用於表級觸發器,而不可以使用它們的創紀錄級別的觸發器。
  如果想查詢表中相同的觸發,那麽應用應該使用AFTER關鍵字,因為觸發器可以查詢該表,或再次改變它最初的變化僅適用後的表是回到一致的狀態。
  上述觸發已經寫在這樣一種方式,它會在任何DELETE、INSERT或UPDATE操作在表上之前執行,但可以奪觸發器上編寫一個或多個操作,例如BEFORE DELETE,這將會觸發每當一個記錄將使用在表上刪除操作被刪除。



二、觸發一個觸發器
讓我們在CUSTOMERS表執行某些DML操作。這裏有一個INSERT語句,這將在表中創建一個新的記錄:
INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY) VALUES (7, ‘Kriti‘, 22, ‘HP‘, 7500.00 );
當記錄在CUSTOMERS表中創建,上面創建觸發器display_salary_changes將被觸發,它會顯示以下結果:
  Old salary:
  New salary: 7500
  Salary difference:
因為這是一個新的記錄,因此基本工資不可用及以上的結果來為空(null)。現在,讓我們對CUSTOMERS表進行多一個DML操作。這裏有一個UPDATE語句,該語句將更新表中現有的記錄:
  UPDATE customers
   SET salary = salary + 500
  WHERE id = 2;
當記錄在CUSTOMERS表更新,上面創建觸發器display_salary_changes將被觸發,它會顯示以下結果:
  Old salary: 1500
  New salary: 2000
  Salary difference: 500

(十二)PL/SQL觸發器