PostgreSQL的存储过程简单入门 [url]http://blog.csdn.net/rachel_luo/article/details/8073458[/url]
存储过程事物 [url]http://www.php100.com/manual/PostgreSQL8/tutorial-transactions.html[/url]
PL/pgSQL - SQL存储过程语言 [url]https://wiki.postgresql.org/wiki/9.1%E7%AC%AC%E4%B8%89%E5%8D%81%E4%B9%9D%E7%AB%A0[/url]

postgreSQL存储过程写法示例[url]http://blog.sina.com.cn/s/blog_448574810101f64u.html[/url]
结构
PL/pgSQL是一种块结构的语言,比较方便的是用pgAdmin III新建Function,填入一些参数就可以了。基本上是这样的:

CREATE OR REPLACE FUNCTION 函数名(参数1,[整型 int4, 整型数组 _int4, ...])
RETURNS 返回值类型 AS
$BODY$
DECLARE
变量声明
BEGIN
函数体
END;
$BODY$
LANGUAGE ‘plpgsql’ VOLATILE;

变量类型
除了postgresql内置的变量类型外,常用的还有 RECORD ,表示一条记录。
赋值
赋值和Pascal有点像:“变量 := 表达式;”
有些奇怪的是连接字符串的是“||”,比如 sql := ‘SELECT * FROM’ || table || ‘WHERE …’;
判断
判断又和VB有些像:
IF 条件 THEN

ELSEIF 条件 THEN

ELSE

END IF;
循环
循环有好几种写法:
WHILE expression LOOP
statements
END LOOP;
还有常用的一种是:(从1循环到9可以写成FOR i IN 1..9 LOOP)
FOR name IN [ REVERSE ] expression .. expression LOOP
statements
END LOOP;
其他
还有几个常用的函数:
SELECT INTO record …; 表示将select的结果赋给record变量(RECORD类型)
PERFORM query; 表示执行query并丢弃结果
EXECUTE sql; 表示执行sql语句,这条可以动态执行sql语句(特别是由参数传入构造sql语句的时候特别有用)

[color=red][b]参数:[/b][/color]
传递给函数的参数都是用 $1,$2,等等这样的标识符。有时候为了增强可读性,我们可以为 $n 参数名声明别名。然后通过这个别名或者数字标识符可以指向这个参数值。
有两种方法创建一个别名。最好的方法是用CREATE FUNCTION命令给予这个参数一个名字,例如:

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

另一个方法是,在PostgreSQL 8.0之前唯一的方法,明确的用别名进行声明,用以下的语法进行声明:
[color=darkblue]name ALIAS FOR $n;[/color]
这个风格的同一个例子看起来像下面这样 :

   CREATE FUNCTION sales_tax(real) RETURNS real AS $$DECLAREsubtotal ALIAS FOR $1;BEGINRETURN subtotal * 0.06;END;$$ LANGUAGE plpgsql;

注意:这两个例子不是完全一样的。在第一种情况,subtotal可以用sales_tax.subtotal进行引用,但是在第二种情况下不能这么做。(如果我们给这个内部块附加了一个标签,subtotal能够替代这个标签)
一些更多的例子:

   CREATE FUNCTION instr(varchar, integer) RETURNS integer AS $$DECLAREv_string ALIAS FOR $1;index ALIAS FOR $2;BEGIN-- some computations using v_string and index hereEND;$$ LANGUAGE plpgsql;CREATE FUNCTION concat_selected_fields(in_t sometablename) RETURNS text AS $$BEGINRETURN in_t.f1 || in_t.f3 || in_t.f5 || in_t.f7;END;$$ LANGUAGE plpgsql

当一个PL/pgSQL函数用输出参数来进行声明时,给予这个输出参数$n名和一个任意的别名跟正常输入参数是同样的方法。即使这个输出参数以NULL开始时也是一个有效的变量,它应该在函数的执行过程中被分配。这个参数最好的值将被返回。例如,这个sales-tax例子也可以用这种方法完成:

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

注意:我们省略了RETURNS real---我们可以将它包括在内,但它是多余的。
当返回多个值的时候输出参数将非常有用,一个简单的例子是:

   CREATE FUNCTION sum_n_product(x int, y int, OUT sum int, OUT prod int) AS $$BEGINsum := x + y;prod := x * y;END;$$ LANGUAGE plpgsql;

如在Section 35.4.4中的讨论,这将为这个函数的结果创建一个匿名的记录类型。如果使用了RETURNS字句,那么必须给它指明RETURNS记录。
另外一种方法声明PL/pgSQL函数是用RETURNS TABLE,例如:

   CREATE FUNCTION extended_sales(p_itemno int)RETURNS TABLE(quantity int, total numeric) AS $$BEGINRETURN QUERY SELECT quantity, quantity * price FROM salesWHERE itemno = p_itemno;END;$$ LANGUAGE plpgsql;

这跟声明一个或者多个OUT参数和制定RETURNS SETOF这些类型是同样的方法。
当返回的PL/pgSQL函数的类型被声明为一个多态类型(anyelement, anyarray, anynonarray, 或者anyenum),特殊参数$0将被创建。它的数据类型将实际的返回函数的类型,从实际的输入类型返回(见Section 35.2.5)。这运行这个函数访问这个实际的返回类型如Section 39.3.3显示的那样。$0初始值为空并且能够被函数修改,如果需要,它可以用于保留返回值,虽然这不是必须的。$0也可以被给予一个别名。例如,这个函数能在任意一个有+操作符的数据类型上工作:

   CREATE FUNCTION add_three_values(v1 anyelement, v2 anyelement, v3 anyelement)RETURNS anyelement AS $$DECLAREresult ALIAS FOR $0;BEGINresult := v1 + v2 + v3;RETURN result;END;$$ LANGUAGE plpgsql

声明一个或者多个多态类型的输出参数也是同样的效果。这种情况下这个特殊的$0参数将不会被用到,这个输出参数本身也是同样的作用,例如:

   CREATE FUNCTION add_three_values(v1 anyelement, v2 anyelement, v3 anyelement,OUT sum anyelement)AS $$BEGINsum := v1 + v2 + v3;END;$$ LANGUAGE plpgsql;

[color=blue][b]39.3.2. 别名[/b][/color]
newname ALIAS FOR oldname;
这个ALIAS语法比以前的章节中介绍的更加普通:你可以为任意一个变量声明一个别名,不只是函数的参数。这实际的用途是用预定义的名字为变量定义不同的名字,如触发器过程中的NEW或者OLD。 例子:

   DECLAREprior ALIAS FOR old;updated ALIAS FOR new;

因此,ALIAS使同样的对象有两种不同的方式命名,如果不限制的使用,将会变得混乱。这种方法最好只用于覆盖预定义的名字。

最后,贴出解决上面这个问题的存储过程吧:

CREATE OR REPLACE FUNCTION message_deletes(ids "varchar", userid int8)RETURNS int4 AS
$BODY$
DECLAREr RECORD;del bool;num int4 := 0;sql "varchar";
BEGINsql := 'select id,receiveuserid,senduserid,senddelete,receivedelete from message where id in (' || ids || ')';FOR r IN EXECUTE sql LOOPdel := false;IF r.receiveuserid=userid and r.senduserid=userid THENdel := true;ELSEIF r.receiveuserid=userid THENIF r.senddelete=false THENupdate message set receivedelete=true where id = r.id;ELSEdel := true;END IF;ELSEIF r.senduserid=userid THENIF r.receivedelete=false THENupdate message set senddelete=true where id = r.id;ELSEdel := true;END IF;END IF;IF del THENdelete from message where id = r.id;num := num + 1;END IF;END LOOP;return num;
END;
$BODY$LANGUAGE 'plpgsql' VOLATILE;

下面的例子是要调用一个存储过程自动创建对应的一系列表:

CREATE OR REPLACE FUNCTION create_table_for_client(id int)
RETURNS integer AS
$BODY$
DECLARE
num int4 := 0;
sql "varchar";
BEGIN
sql := 'create table _' || id || '_company(id int, name text)';
EXECUTE sql;
sql := 'create table _' || id || '_employee(id int, name text)';EXECUTE sql;
sql := 'create table _' || id || '_sale_bill(id int, name text)';EXECUTE sql;
.......
return num;
END;
$BODY$ LANGUAGE plpgsql VOLATILE

自动创建序列
第一个例子

CREATE OR REPLACE FUNCTION auto_gen_seq() RETURNS bigint AS
$BODY$
DECLARE
rd RECORD;
num int4 := 0;
sql "varchar";
seq_sql varchar;
BEGIN    sql := 'SELECT tablename FROM pg_tables WHERE tablename NOT LIKE ''pg%'' AND tablename NOT LIKE ''sql_%'' ORDER BY tablename;';  FOR rd IN EXECUTE sql LOOP  seq_sql:='CREATE SEQUENCE SQ_'||rd.tablename||' START 1000000 CACHE 30;';     BEGINEXECUTE seq_sql;  EXCEPTIONWHEN TOO_MANY_ROWS THENRAISE EXCEPTION 'employee % not unique', seq_sql;WHEN OTHERS THENreturn -1;END;num := num + 1;    END LOOP;    return num;
END;
$BODY$
LANGUAGE plpgsql VOLATILE NOT LEAKPROOF
COST 100;

调用:

select auto_gen_seq()

第二个例子

-- Function: auto_gen_seq(character)-- DROP FUNCTION auto_gen_seq(character);CREATE OR REPLACE FUNCTION auto_gen_seq("tbName" character)RETURNS character varying AS
$BODY$/*调用示例:SELECT tablename as tableName,
'sq_'||REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(tablename, 'tb_am_', ''), 'tb_sm_', ''), 'tb_pm_', ''), 'tb_pc_', ''), 'tb_ps_', ''), 'rh_', ''), 'TB_', ''), 'RH_', '' ), 'tb_', '') AS sqName
,auto_gen_seq(tablename||'') as successFlag,current_date,current_time FROM pg_tables WHERE tablename NOT LIKE 'pg%' AND tablename NOT LIKE 'sql_%' ORDER BY successFlag,tablename;*/DECLARE
rd RECORD;
seq_sql varchar;
flag_str varchar;
sq_name varchar;
sq_datetime varchar;
BEGINseq_sql:='create table _sequence_table ( id SERIAL not null, code VARCHAR(200) null, increment_num INT8 null, minvalue_num INT8 null, maxvalue_num INT8 null, start_num INT8 null, cache_num INT8 null, cycle_flag VARCHAR(100) null,create_datetime timestamp without time zone,constraint PK__SEQUENCE_TABLE primary key (id) );CREATE UNIQUE INDEX INDEX__sequence_table ON _sequence_table (code);';BEGIN  EXECUTE seq_sql;    EXCEPTION  WHEN OTHERS THEN  flag_str:='失败';  END;--sq_name:=replace(replace($1, 'TB_', ''), 'RH_', '');--sq_name:=replace(replace(sq_name, 'tb_', ''), 'rh_', '');sq_name:='sq_'||REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE($1, 'tb_am_', ''), 'tb_sm_', ''), 'tb_pm_', ''), 'tb_pc_', ''), 'tb_ps_', ''), 'rh_', ''), 'TB_', ''), 'RH_', '' ), 'tb_', '');/*seq_sql:='drop SEQUENCE '||sq_name||';';       BEGIN  EXECUTE seq_sql;    EXCEPTION  WHEN OTHERS THEN  flag_str:='失败';  END; */  seq_sql:='CREATE SEQUENCE '||sq_name||' START 1000000 CACHE 30;';       BEGIN  EXECUTE seq_sql;    EXCEPTION  WHEN OTHERS THEN  return '失败,创建序列';  END;   sq_datetime:=to_timestamp(current_date||' '||current_time,'yyyy-mm-dd hh24:mi:ss') ;seq_sql:='INSERT INTO _sequence_table( code,increment_num,minvalue_num,start_num, cache_num,create_datetime) VALUES ( '''||sq_name||''',1,1000000,1000000, 30,'''||sq_datetime||''');';       BEGIN  EXECUTE seq_sql;    EXCEPTION  WHEN OTHERS THEN  return '失败,插入序列信息';  END; return '成功';
END;
$BODY$LANGUAGE plpgsql VOLATILE STRICTCOST 100;
ALTER FUNCTION auto_gen_seq(character)OWNER TO postgres;

调用

SELECT tablename as tableName,
'sq_'||REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(tablename, 'tb_am_', ''), 'tb_sm_', ''), 'tb_pm_', ''), 'tb_pc_', ''), 'tb_ps_', ''), 'rh_', ''), 'TB_', ''), 'RH_', '' ), 'tb_', '') AS sqName
,auto_gen_seq(tablename||'') as successFlag,current_date,current_time FROM pg_tables WHERE tablename NOT LIKE 'pg%' AND tablename NOT LIKE 'sql_%' ORDER BY successFlag,tablename;

数据库之postgreSQL存储过程写法示例相关推荐

  1. postgreSQL存储过程写法示例

    转载自:http://panyongzheng.iteye.com/blog/2194815 PostgreSQL的存储过程简单入门 http://blog.csdn.net/rachel_luo/a ...

  2. 【SQL Server】【存储过程】 存储过程写法示例

    公司做了一个需求,初期设想通过存储过程来初始化表数据,所以写了一个存储过程,如下: --CREATE PROCEDURE [dbo].[PROC_HANDLE_SHOPCAR_TXD_SR_TYPE] ...

  3. Mybatis调用PostgreSQL存储过程实现数组入参传递

    前言 项目中用到了Mybatis调用PostgreSQL存储过程(自定义函数)相关操作,由于PostgreSQL自带数组类型,所以有一个自定义函数的入参就是一个int数组,形如: CREATE OR ...

  4. 开源的数据库,PostgreSQL 基础入门实战

    PostgreSQL 简介与安装 实验介绍 大家好,本课程是关于 PostgreSQL 数据库的使用说明,细致讲解 PostgreSQL 的特性与使用方法,尽量做到描述朴实.深入浅出.示例充足.覆盖重 ...

  5. mysql workbench 存储过程_MySQL Workbench创建存储过程教程示例

    MySQL中的存储过程指的是存储在数据库中的SQL语句集合,当创建好存储过程后在运行时提供所需参数,存储过程就可以以代码指定的方式使用参数执行并返回值. 一.存储过程如何工作 首先要先创建一个存储过程 ...

  6. 在Mysql数据库里通过存储过程实现树形的遍历

    Oracle 循环递归遍历树结构查询 2015年10月27日 16:38:26 vrenzhuv 阅读数:2831 标签: oracle递归遍历 更多 个人分类: Oracle 在项目中经常会接触树结 ...

  7. php mysql存储过程写法_mysql存储过程写法

    都说不懂数据库的程序员不是合格的程序员,那么你知道MySQL存储过程应该怎么写吗? MySQL存储过程写法 可以使用 CREATE PROCEDURE 语句创建存储过程. 数据库存储过程语法格式如下: ...

  8. mysql过程的写法,存储过程写法是什么,mysql存储过程写法

    存储过程写法是什么存储过程的写作是什么,存储过程的编写如下:1 .用代码[创建进程名]创建一个存储过程:2.用[EXECSP _ NAME]代码调用存储过程. 操作环境:Windows7系统,微软vi ...

  9. php的存储过程怎么写,存储过程写法是什么

    存储过程写法是:1.创建存储过程,代码为[create proc sp_name]:2.调用存储过程,代码为[exec sp_name [参数名]]. 本文操作环境:Windows7系统,Micros ...

最新文章

  1. SDOI2014 LIS
  2. AIDL注意细节 简单Demo
  3. SQL Server分页查询方法整理
  4. SQL Server 2012 Always ON笔记
  5. 博图如何上载wincc程序_WINCC 博途 以太网下载方式
  6. java复习系列[5] - Java 中的设计模式
  7. 数据的中心值:均值、中位数、众数
  8. SpringCloud使用RabbitMQ报错Rabbit health check failed
  9. (二)洞悉linux下的Netfilteriptables:内核中的ip_tables小觑
  10. 南方cass10.1中文安装教程
  11. PowerDesigner 数据字典模板
  12. 简单实用的web打印方案-网页精准打印
  13. C语言图书购销管理系统流程图,图书销售管理系统C语言程序报告精选.doc
  14. 数值分析 |多项式插值、牛顿插值、样条插值
  15. 听说你不会用Lumion做通道图?
  16. 20年前的网文:我彷徨在唯物主义和唯心主义之间
  17. 巧除Word插入水印后页眉处的折线(转)
  18. C#简易计算器(加减乘除三角函数运算)
  19. Python中使用多个分隔符分隔字符串re.split
  20. 博客怎么写出好的文章吸引读者,只有7个基本的写作技巧

热门文章

  1. ata计算机考试试题以及答案,ata计算机统考第一套模拟练习题
  2. vb调用oracle 触发器,单片机VB编程实例_单片机控制的数字触发器
  3. jQuery右下角悬浮广告
  4. 如何防止黑客恶意扫描你的计算机
  5. 【原创】一个计算斗地主谁必赢谁必输的程序
  6. LED的电磁干扰问题探讨
  7. GREEN牛的骨牌[cowdom]
  8. Kinect Azure DK入门学习(三)——设置人体跟踪SDK + 生成第一个人体跟踪应用程序
  9. 解决go build 构建问题 go:build comment without // +build comment
  10. Bakery Algorithm的c#实现用于多线程互斥访问临界资源