| PostgreSQL | ||
|---|---|---|
| 上一頁 | 下一頁 | |
CREATE RULE ─ 定義一個新規則
CREATE RULE name AS ON event
TO object [ WHERE condition ]
DO [ INSTEAD ] [ action | NOTHING ]
Postgres 規則系統 允許我們在從資料庫或表中更新,插入或刪除東西時定義一個可選的動作來執行。目前,規則用於實現表視圖。
規則的語意是在一個單獨的記錄正被訪問,更新,插入或刪除時,將存在一個當前記錄(用於檢索,更新和刪除)和一個新記錄(用於更新和追加)。如果在 ON 語句裡所聲明的 event 和在 WHERE 語句裡面所聲明的 condition 對於當前記錄都為真,那麼action 部分的規則就被執行。但是,當前記錄的各字段值和/或新記錄將先用 current.attribute-name 和 new.attribute-name 取代。
規則 action 部分執行時的命令和事務標識與激活該規則的用戶命令相同。
一個關於 SQL 規則的注意事項是順序。如果相同的表名或記錄變數出現在規則的 event,condition 和 action 部分。它們將會被認為是不同的記錄變數。更準確地說,只有 new 和 current 在這些子句中共享記錄變數。比如,下面兩條規則有相同的語意:
ON UPDATE TO emp.salary WHERE emp.name = "Joe"
DO UPDATE emp ( ... ) WHERE ...
ON UPDATE TO emp-1.salary WHERE emp-2.name = "Joe"
DO UPDATE emp-3 ( ... ) WHERE ...
每條規則都可以有可選的標記 INSTEAD。沒有這個標記,action 將在規則的條件(condition )部分的事件(event )發生時作為用戶命令的附加部分執行。否則,動作( action )部分將取代用戶命令執行。對於後者,action 可以是關鍵字 NOTHING。
當為一個具體的規則應用在重寫 (rewrite)和實例 (instance)規則系統之間做選擇時,請記住在重寫(rewrite)系統裡,current 指的是關系/表和一些條件,而在實例(instance)系統裡它指的是一條記錄。
特別要指出的是重寫(rewrite)規則系統既不檢測也不執行循環規則。例如,盡管下面兩條規則都被Postgres 所接受,檢索命令將導致 Postgres 的崩潰:
例 14-1. 循環重寫(rewrite)規則組合.
CREATE RULE bad_rule_combination_1 AS
ON SELECT TO emp
DO INSTEAD SELECT TO toyemp;
CREATE RULE bad_rule_combination_2 AS
ON SELECT TO toyemp
DO INSTEAD SELECT TO emp;
下面試圖從 EMP 中檢索將導致 Postgres 崩潰。
SELECT * FROM emp;
你必須具有對某個表進行規則定義的權限,這樣才能在其上面定義規則。使用 GRANT 和 REVOKE 更改權限。
一條 SQL 規則裡的對像不能是一個數組引用和不能有參數。
除了 "oid" 字段,一個規則裡任何地方都不能引用系統表屬性。這意味著在規則裡任何地方都不能調用實例/記錄函數 (比如, "foo(emp)" 這裡 "emp" 是一個表)。
規則系統將規則文本和查詢規划按文本(text)屬性儲存。這意味著當創建的規則加上各種其內部表達式超過一次儲存頁面請求的值(8KB)時,規則創建可能失敗。
令 Sam 獲得與 Joe 一樣的薪水調整:
CREATE RULE example_1 AS
ON UPDATE emp.salary WHERE current.name = "Joe"
DO UPDATE emp (salary = new.salary)
WHERE emp.name = "Sam";
當 Joe 獲得薪水調整後,事件將為真以及Joe的當前記錄和提供的新記錄可被執行程序獲得。因此,他的新薪水將代入動作部分,隨後動作部分被執行。這樣Sam的薪水就會和Joe的一樣了。
當Bill訪問資料庫(薪水)時,令 Bill 獲得 Joe 薪水的資訊。
CREATE RULE example_2 AS
ON SELECT TO EMP.salary
WHERE current.name = "Bill"
DO INSTEAD
SELECT (emp.salary) from emp
WHERE emp.name = "Joe";
拒絕 Joe 訪問雇員的薪水,當他在鞋部時 (current_user 返回當前用戶的名稱):
CREATE RULE example_3 AS
ON SELECT TO emp.salary
WHERE current.dept = "shoe" AND current_user = "Joe"
DO INSTEAD NOTHING;
創建一個玩具部工作的雇員視圖。
CREATE toyemp(name = char16, salary = int4);
CREATE RULE example_4 AS
ON SELECT TO toyemp
DO INSTEAD
SELECT (emp.name, emp.salary) FROM emp
WHERE emp.dept = "toy";
所有新雇員收入必須少於5,000
CREATE RULE example_5 AS
ON INERT TO emp WHERE new.salary > 5000
DO UPDATE NEWSET salary = 5000;
CREATE RULE 語句是 Postgres 語言的擴展。在 SQL92 裡沒有 CREATE RULE 語句。
| 上一頁 | 首頁 | 下一頁 |
| CREATE OPERATOR | 開頭 | CREATE SEQUENCE |