舒适提示:本文中部分描述仅为我的理解,存在描述误差或错误,内容仅供参考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修炼之道 从小工到专家
注意:第二个参考连接中文和空格,建议复制地址到浏览器访问