PostgreSQL數據庫平常學習筆記12-函數(存儲過程)

舒適提示:本文中部分描述僅爲我的理解,存在描述誤差或錯誤,內容僅供參考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修煉之道 從小工到專家

注意:第二個參考連接中文和空格,建議複製地址到瀏覽器訪問

相關文章
相關標籤/搜索