PostgreSQL數據庫平常學習筆記16-觸發器函數

PostgreSQL觸發器是一組動做或數據庫回調函數,用於表或視圖等執行指定數據庫事件,即INSERT,UPDATE,DELETE或TRUNCAT等語句時自動運行。 觸發器用於驗證輸入數據,執行業務規則,保持審計跟蹤等。html

觸發器函數返回類型是trigger, 若是須要給觸發器函數傳入參數, 須要定義到觸發器函數外部參數列表, 須要經過其餘方式傳入。.sql

觸發器語法示例以下:數據庫

CREATE [ CONSTRAINT ] TRIGGER name { BEFORE | AFTER | INSTEAD OF } { event [ OR ... ] }
    ON table_name
    [ FROM referenced_table_name ]
    [ NOT DEFERRABLE | [ DEFERRABLE ] [ INITIALLY IMMEDIATE | INITIALLY DEFERRED ] ]
    [ REFERENCING { { OLD | NEW } TABLE [ AS ] transition_relation_name } [ ... ] ]
    [ FOR [ EACH ] { ROW | STATEMENT } ]
    [ WHEN ( condition ) ]
    EXECUTE PROCEDURE function_name ( arguments )

where event can be one of:

    INSERT
    UPDATE [ OF column_name [, ... ] ]
    DELETE
    TRUNCATE

建立測試學生表student 和分數表score 。函數

CREATE TABLE student ( 
		studentno INT PRIMARY KEY ,
		studentname TEXT ,
		studentbirthday DATE DEFAULT CURRENT_DATE
);
CREATE TABLE score ( 
		studentno INT ,
		chinaesescore INT ,
		mathscore INT ,
		testdate DATE 
);

咱們但願刪除學生表時,可以同時刪除該學生考試成績,觸發器能夠實現實現相似功能。post

插入測試數據。測試

---測試數據
INSERT INTO student VALUES(1,'王小虎'),(2,'李逍遙'),(3,'景天'),(4,'雲天河');
INSERT INTO score VALUES (1,92,87,'2017-1-18'),(1,90,83,'2017-7-14'),(2,69,74,'2017-1-18'),(2,75,83,'2017-7-14'),(3,92,87,'2017-1-18'),(3,92,87,'2017-7-14');

執行查詢操做。.net

---查詢student表
test=# select studentno,studentname,studentbirthday from student;
 studentno | studentname | studentbirthday
-----------+-------------+-----------------
         1 | 王小虎      | 2017-11-02
         2 | 李逍遙      | 2017-11-02
         3 | 景天        | 2017-11-02
         4 | 雲天河      | 2017-11-02
(4 行記錄)

---查詢score表
test=#

test=# select studentno,chinaesescore,mathscore,testdate from score;
 studentno | chinaesescore | mathscore |  testdate
-----------+---------------+-----------+------------
         1 |            92 |        87 | 2017-01-18
         1 |            90 |        83 | 2017-07-14
         2 |            69 |        74 | 2017-01-18
         2 |            75 |        83 | 2017-07-14
         3 |            92 |        87 | 2017-01-18
         3 |            92 |        87 | 2017-07-14
(6 行記錄)


test=#

建立觸發器前,須要定義觸發器函數,函數帶任何參數,返回值的類型必須是trigger。觸發器函數定義完成後,能夠用命令CREATE TRIGGER建立觸發器。多個觸發器可使用一個觸發器函數。postgresql

下面演示建立觸發器執行函數。code

CREATE OR REPLACE FUNCTION deletestudentafterscore()
RETURNS TRIGGER AS
$$
BEGIN 
DELETE FROM score WHERE studentno =OLD.studentno;
RETURN OLD;
END;
$$
LANGUAGE plpgsql;

建立觸發器。htm

CREATE TRIGGER deletestudent AFTER DELETE ON student FOR EACH ROW EXECUTE PROCEDURE deletestudentandscore();

刪除學號爲3學生。

---刪除景天
test=# delete from student where studentno=3;
#DELETE 1

再次執行查詢語句。

test=# select studentno,studentname,studentbirthday from student;
 studentno | studentname | studentbirthday
-----------+-------------+-----------------
         1 | 王小虎      | 2017-11-02
         2 | 李逍遙      | 2017-11-02
         4 | 雲天河      | 2017-11-02
(3 行記錄)


test=# select studentno,chinaesescore,mathscore,testdate from score;
 studentno | chinaesescore | mathscore |  testdate
-----------+---------------+-----------+------------
         1 |            92 |        87 | 2017-01-18
         1 |            90 |        83 | 2017-07-14
         2 |            69 |        74 | 2017-01-18
         2 |            75 |        83 | 2017-07-14
(4 行記錄)


test=#

---刪除李逍遙
test=# delete from student where studentno=2;
#DELETE 1
test=# select studentno,studentname,studentbirthday from student;
 studentno | studentname | studentbirthday
-----------+-------------+-----------------
         1 | 王小虎      | 2017-11-02
         4 | 雲天河      | 2017-11-02
(2 行記錄)


test=# select studentno,chinaesescore,mathscore,testdate from score;
 studentno | chinaesescore | mathscore |  testdate
-----------+---------------+-----------+------------
         1 |            92 |        87 | 2017-01-18
         1 |            90 |        83 | 2017-07-14
(2 行記錄)


test=#

PostgreSQL支持兩種觸發器,一種是數據行級觸發器,另一種是語句級觸發器,修改0行數據也會致使觸發匹配觸發器,一次性更新多條數據觸發器也只會被觸發一次。對於數據行級觸發器,觸發觸發器語句在每操做一個數據行,就會被執行一次。語句級觸發器只會被執行一次,即具備一次性。

補全已刪除數據。

test=# INSERT INTO student VALUES(2,'王小虎'),(3,'景天');
INSERT 0 2
test=# INSERT INTO score VALUES (2,69,74,'2017-1-18'),(2,75,83,'2017-7-14'),(3,92,87,'2017-1-18'),(3,92,87,'2017-7-14');
INSERT 0 4

---根據學生編號排序
test=# select studentno,studentname,studentbirthday from student order by studen
tno;
 studentno | studentname | studentbirthday
-----------+-------------+-----------------
         1 | 王小虎      | 2017-11-02
         2 | 王小虎      | 2017-11-02
         3 | 景天        | 2017-11-02
         4 | 雲天河      | 2017-11-02
(4 行記錄)


test=# select studentno,chinaesescore,mathscore,testdate from score;
 studentno | chinaesescore | mathscore |  testdate
-----------+---------------+-----------+------------
         1 |            92 |        87 | 2017-01-18
         1 |            90 |        83 | 2017-07-14
         2 |            69 |        74 | 2017-01-18
         2 |            75 |        83 | 2017-07-14
         3 |            92 |        87 | 2017-01-18
         3 |            92 |        87 | 2017-07-14
(6 行記錄)


test=#

當PL / pgSQL函數被調用爲觸發器時,會在頂級塊中自動建立若干特殊變量。分別是NEW、OLD、TG_NAME、TG_WHEN、TG_LEVEL、TG_OP、TG_RELID、TG_RELNAME、TG_TABLE_NAME、TG_TABLE_SCHEMA、TG_NARGS、TG_ARGV[]等。上文中觸發器函數deletestudentafterscore已經練習使用過OLD變量。

一個表或視圖上能夠建立多個觸發器, 調用順序和觸發器類型有關.若是存在多個同類觸發器, 調用順序則和觸發器名稱有關, 按照名字英文排序調用(a-z)。

一個觸發器函數能夠屢次被觸發器調用。

參考連接

http://blog.csdn.net/neo_liu0000/article/details/6255623

https://www.postgresql.org/docs/10/static/sql-createtrigger.html

https://www.postgresql.org/docs/current/static/plpgsql-trigger.html#plpgsql-trigger-example

參考書籍

postgresql修煉之道 從小工到專家 P173-P186

相關文章
相關標籤/搜索