ref: https://www.postgresql.org/docs/9.6/static/plpgsql-structure.html

一. 函数结构

CREATE FUNCTION somefunc(integer, text) RETURNS integer
AS 'function body text'
LANGUAGE plpgsql;

PL/pgSQL是块结构(block-structured)语言,上面示例里的function body必须是一个块(block),块结构如下

[ <<label>> ]
[ DECLARE
declarations ]
BEGIN
statements
END [ label ];

块可以嵌套,嵌套块里可以通过外层块的标签来调用外层块的同名变量,示例:

 CREATE FUNCTION somefunc() RETURNS integer AS $$
<< outerblock >>
DECLARE
quantity integer := 30;
BEGIN
RAISE NOTICE 'Quantity here is %', quantity; -- Prints 30
quantity := 50;
--
-- Create a subblock
--
DECLARE
quantity integer := 80;
BEGIN
RAISE NOTICE 'Quantity here is %', quantity; -- Prints 80
RAISE NOTICE 'Outer quantity here is %', outerblock.quantity; -- Prints 50
END; RAISE NOTICE 'Quantity here is %', quantity; -- Prints 50 RETURN quantity;
END;
$$ LANGUAGE plpgsql;

* PL/pgSQL的BEGIN/END与事务无关,只起分隔块的作用;

* Function和trigger不能发起或提交一个事务,只能运行在外部查询发起的事务里,因为其没有事务的上下文;

* EXCEPTION表达式可以处理存储过程里的错误,类似Java里的catch(see: PLPGSQL-ERROR-TRAPPING

二. 变量声明(Declarations)

1. 块声明域

name [ CONSTANT ] type [ COLLATE collation_name ] [ NOT NULL ] [ { DEFAULT | := | = } expression ];

示例:

i integer;
quantity numeric(5);
quantity integer DEFAULT 32;
url varchar := 'http://mysite.com';
id_user CONSTANT integer := 10;

2. 函数形参

函数形参主要有两种方式调用

1) 命名参数,如:

CREATE FUNCTION sales_tax(subtotal real) RETURNS real AS $$
BEGIN
RETURN subtotal * 0.06;
END;
$$ LANGUAGE plpgsql;

2) 通过$n调用,如

CREATE FUNCTION sales_tax(real) RETURNS real AS $$
DECLARE
subtotal ALIAS FOR $1;
BEGIN
RETURN subtotal * 0.06;
END;
$$ LANGUAGE plpgsql;

如上的函数形参传参方式都是值传递,可以通过OUT关键字将形参设置为引用传递,示例:

CREATE FUNCTION sales_tax(subtotal real, OUT tax real) AS $$
BEGIN
tax := subtotal * 0.06;
END;
$$ LANGUAGE plpgsql;

这里跟前面示例的sales_tax功能一样,只是前面是作为返回值返回,而这里将计算结果记录在了引用传递的参数里,外部可以在调用函数后访问tax变量获取函数计算结果。这就像C里的指针变量一样,也类似C#里参数的ref关键字。

3.  Alias

可以给变量赋予别名

newname ALIAS FOR oldname;

示例

DECLARE
prior ALIAS FOR old;
updated ALIAS FOR new;

4. 复制数据类型(Copying Types)

variable%TYPE

%TYPE能获取一个变量或列的数据类型。要声明一个跟表users的列id_user同样数据类型的变量,可以通过如下方式实现:

id_user users.id_user%TYPE;

通过复制数据类型的方式,我们可以在不知道引用对象数据类型的情况下就进行引用,更关键的是当引用对象的数据类型改变时,我们的引用代码并不需要跟着改动。

5. 复制列(Row Types)

name table_name%ROWTYPE;
table_name%ROWTYPE可以复制整个表所有用户定义的列(非OID或者其他表系统列)

示例

    CREATE FUNCTION merge_fields(t_row table1) RETURNS text AS $$
DECLARE
t2_row table2%ROWTYPE;
BEGIN
SELECT * INTO t2_row FROM table2 WHERE ... ;
RETURN t_row.f1 || t2_row.f3 || t_row.f5 || t2_row.f7;
END;
$$ LANGUAGE plpgsql; SELECT merge_fields(t.*) FROM table1 t WHERE ... ;

postgresql PL/pgSQL—存储过程结构和变量声明的更多相关文章

  1. PostgreSQL存储过程(2)-基于PL/PgSQL的存储过程

    介绍 PL/pgSQL 是PostgreSQL 数据库系统的一个可加载的过程语言. PL/pgSQL 的设计目标是创建一种可加载的过程语言,可以 用于创建函数和触发器过程, 为SQL 语言增加控制结构 ...

  2. PL/pgSQL学习笔记之四

    http://www.postgresql.org/docs/9.1/static/plpgsql-structure.html 39.2. PL/pgSQL 的结构 PL/pgSQL是一种块式结构的 ...

  3. PL/pgSQL学习笔记之三

    http://www.postgresql.org/docs/9.1/static/plpgsql-overview.html 39.1.2. Supported Argument and Resul ...

  4. 用PL/pgSQL写postgreSQL的存储过程[转]

    http://blog.chinaunix.net/uid-7591044-id-1742967.html 今天学会了用 PL/pgSQL 写 postgreSQL 的存储过程,网上资料实在少得可怜, ...

  5. sql:sql server,MySQL,PostgreSQL的表,视图,存储过程结构查询

    sql server 2005: --SQL SERVER 2005 生成代码需要知道的SQL语句 use LibrarySystem --查询当前数据库所有表和其的主键字段,字段类型,长度,是否为空 ...

  6. 【PLSQL】变量声明,结构语句,cursor游标

    ************************************************************************   ****原文:blog.csdn.net/clar ...

  7. PL/SQL存储过程编程

    PL/SQL存储过程编程 /**author huangchaobiao *Email:huangchaobiao111@163.com */ PL/SQL存储过程编程(上) 1. Oracle应用编 ...

  8. PL/pgSQL学习笔记之七

    http://www.postgresql.org/docs/9.1/static/plpgsql-declarations.html 如果一个PL/pgSQL函数声明了输出参数,输出参数被赋予$n名 ...

  9. PL/pgSQL学习笔记之五

    http://www.postgresql.org/docs/9.1/static/plpgsql-declarations.html 39.3. 声明 块中使用的所有的变量必须在块的声明节中进行声明 ...

随机推荐

  1. pyDay15

    内容来自廖雪峰的官方网站. 1.Python提供的sum()函数可以接受一个list并求和,请编写一个prod()函数,可以接受一个list并利用reduce()求积. from functools ...

  2. Linux学习笔记之Linux启动级别

    对于绝大多数Linux程序员来说,进入Linux系统后一般看到的是黑乎乎的界面(开发模式),因为系统如果启动选择开发模式,会减少启动时间,优化内存等.但是通常我们刚安装完Linux系统,然后进去以后是 ...

  3. SQL学习笔记四之MySQL数据操作

    阅读目录 一 介绍 二 插入数据INSERT 三 更新数据UPDATE 四 删除数据DELETE 五 查询数据SELECT 六 权限管理 一 介绍 MySQL数据操作: DML =========== ...

  4. P1136 迎接仪式

    P1136 迎接仪式 $O(n^{2}k)$:$f[i][k]$表示到第$i$个字符为止,交换$k$次,得到的最多子串数 那么枚举位置$j$,状态可以从$f[j][k-1]+1$转移过来 $O(nk^ ...

  5. 20145333《网络对抗》Exp2 后门原理与实践

    20145333<网络对抗>Exp2 后门原理与实践 1.基础问题回答 (1)例举你能想到的一个后门进入到你系统中的可能方式? 通过邮件发送,邮箱里经常受到一些陌生人发来的链接. 误入了一 ...

  6. Python3基础 三元运算符 简单示例

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  7. Cannot perform runtime binding on a null reference

    一个方法的参数是dynamic  obj 方法内调用了obj.Header 但是外部传递进来的obj是null,然后就会报这个错.

  8. UVa 11374 机场快线

    https://vjudge.net/problem/UVA-11374 题意: 机场快线分为经济线和商业线两种,线路.速度和价格都不同.你有一张商业线车票,可以坐一站商业线,而其他时候只能乘坐经济线 ...

  9. python 作用域,命名空间

    def scope_test(): def do_local(): spam = "local spam" def do_nonlocal(): nonlocal spam spa ...

  10. redis事务和脚本

    事务,简单理解就是,一组动作,要么全部执行,要么就全部不执行.从而避免出现数据不一致的情况. redis提供了简单的事务功能,将一组需要的命令放到multi和exec两个命令之间.multi代表事务开 ...