舒適提示:本文中部分描述僅爲我的理解,存在描述誤差或錯誤,內容僅供參考html
某些其它數據庫系統所定義活動數據庫規則,一般是存儲過程和觸發器。在PostgreSQL中,這些規則能夠經過函數和觸發器來實現。sql
PostgreSQL函數也稱爲PostgreSQL存儲過程。數據庫
首先咱們簡要介紹函數這個概念。PostgreSQL存儲過程具備如下優勢編程
減小應用與數據庫服務器通訊開銷,提高網絡性能。在某些大型業務系統中,大多須要使用多個存儲過程等,存儲過程等下降網絡通訊開銷就具備明顯優點瀏覽器
存儲過程存於數據庫服務器中,首次被調用後即被編譯,再調用時無需二次編譯,直接被服務器執行,能夠提升性能安全
存儲過程能夠重複使用,可以減小數據庫開發人員和管理人員工做量服務器
保護數據庫元信息。若是應用程序直接使用SQL語句查詢數據庫,會將數據庫表結構等信息暴露給應用程序,不利於數據庫訪問控制網絡
細粒度權限管理。直接控制用戶調用存儲過程,存儲過程能夠加強數據安全性函數
將業務實現與應用程序解耦。當業務需求更新時,只需更新存儲過程,無須要變更應用程序post
能夠經過其它語言並可及其它系統交互。PostgreSQL官方支持PL/pgSQL,PL/Tcl,PL/Perl,PL/Python,PL/Java,PL/PHP, PL/R,PL/Ruby,PL/Scheme,PL/sh等(編程)語言。
固然,PostgreSQL存儲過程也有調試不便和可移植性差等缺點。
變動存儲過程時,應用程序內須要同步加以修改,不一樣數據庫的存儲過程定義方式不一樣,支持的語言及語法不一樣,存在必定移植成本。
存儲過程可選聲明指定數據庫,函數主體functionbodyvariablename名稱可爲空。返回類型returndatatype 能夠是複合型數據。中括號部分爲可選部分。|爲二選一條件選擇,輸入結果要和指定返回結果數據類型相同,全部關鍵字都不區分大小寫,標識符被隱含地轉換成小寫字符,除非使用英文雙引號""。
---不完整存儲過程示例代碼 CREATE OR REPLACE FUNCTION functionname (arguments,[optionalparameters],[...]) RETURNS returndatatype AS $functionbodyvariablename$ [DECLARE declarations] BEGIN funcation body END; RETURN functionbodyvariablename | value, LANGUAGE plsupportlanguage;
下面貼出1個簡單示例函數
CREATE OR REPLACE FUNCTION add(a INTEGER, b NUMERIC) RETURNS NUMERIC AS $$ SELECT a+b; $$ LANGUAGE SQL;
下面咱們演示一個完整示例。咱們以餘額轉出爲例編寫代碼
---建立餘額表 create table accounts(owner text,balance numeric); --插入兩條測試數據 insert into accounts values('Bob',100); insert into accounts values('Mary',200); select owner,balance from accounts; --- ---查詢結果 postgres=# \c test 您如今已經鏈接到數據庫 "test",用戶 "postgres". test=# select owner,balance from accounts; owner | balance -------+--------- Mary | 256.00 Bob | 44.00 (2 行記錄) test=#
建立函數
---餘額函數(存儲過程) CREATE OR REPLACE FUNCTION transfer( i_payer TEXT, i_recipient TEXT, i_amount NUMERIC(15,2)) RETURNS TEXT AS $$ DECLARE payer_bal NUMERIC; BEGIN SELECT balance INTO payer_bal FROM accounts WHERE "owner" =i_payer FOR UPDATE; IF NOT FOUND THEN RETURN '轉出帳號不存在,請檢查!'; END IF; IF payer_bal <i_amount THEN RETURN '帳號餘額不足!'; END IF; UPDATE accounts SET balance = balance + i_amount WHERE "owner" =i_recipient; IF NOT FOUND THEN RETURN '轉入帳號不存在,請檢查!'; END IF; UPDATE accounts SET balance =balance - i_amount WHERE "owner" =i_payer; RETURN '轉帳操做成功!'; END; $$LANGUAGE plpgsql;
執行一個冊數查詢。
---轉出餘額14.00 test=# SELECT * FROM transfer('Bob','Mary',14.00); transfer ---------------- 轉帳操做成功! (1 行記錄) test=#
再次執行查詢餘額操做。
test=# select owner,balance from accounts; owner | balance -------+--------- Mary | 214.00 Bob | 86.00 (2 行記錄) test=#
若是咱們輸入帳號有問題呢?好比轉帳人信息錯誤,這裏假設轉帳人是Green,執行操做
test=# SELECT * FROM transfer('Green','Mary',14.00); transfer -------------------------- 轉出帳號不存在,請檢查! (1 行記錄) --轉入帳號不存在 test=# SELECT * FROM transfer('Bob','Bill',14.00); transfer -------------------------- 轉入帳號不存在,請檢查! (1 行記錄) test=# ---餘額不足 test=# SELECT * FROM transfer('Bob','Mary',10000.00); transfer ---------------- 帳號餘額不足! (1 行記錄) test=#
多個函數能夠共用一個名詞,但須要指定不一樣參數用以區分不一樣函數,也就是函數能夠重載。
刪除函數
---刪除函數列表 DROP FUNCTION transfer(i_payer TEXT,i_recipient TEXT,i_amount NUMERIC(15,2));
PostgreSQL函數支持重載,所以在刪除函數時,必須指定參數列表。
參考文獻與連接
http://www.cnblogs.com/lottu/p/7404722.html
http://www.jasongj.com/2015/12/27/SQL4_存儲過程_Store Procedure/
http://panyongzheng.iteye.com/blog/2194815
PostgreSQL修煉之道 從小工到專家
注意:第二個參考連接中文和空格,建議複製地址到瀏覽器訪問