今天有人问到在 PostgreSQL 函数中如何返回结果集的单列,返回结果集(多列)的方法很多,
那么如何返回结果集的单列呢,做了下测试,具体步骤如下:
**一 测试一:返回多条记录(单列)
--1 创建测试表并插入记录**
<table style="WHITE-SPACE: normal; WORD-SPACING: 0px; TEXT-TRANSFORM: none; COLOR: rgb(51,51,51); TEXT-ALIGN: left; FONT: 16px/28px 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; WIDOWS: 1; LETTER-SPACING: normal; BACKGROUND-COLOR: rgb(220,231,230); TEXT-INDENT: 0px; -webkit-text-stroke-width: 0px" cellspacing="1" cellpadding="1" width="80%" border="1"><tbody style="LINE-HEIGHT: 28px"><tr style="LINE-HEIGHT: 28px"><td style="LINE-HEIGHT: 28px"> skytf=> create table test_result1 (id integer,name varchar(32));<br style="LINE-HEIGHT: 28px"/>CREATE TABLE <p style="PADDING-BOTTOM: 0px; PADDING-TOP: 0px; PADDING-LEFT: 0px; MARGIN: 0px 0px 10px; LINE-HEIGHT: 28px; PADDING-RIGHT: 0px">skytf=> create table test_result2 (id integer,name varchar(32));<br style="LINE-HEIGHT: 28px"/>CREATE TABLE</p> <p style="PADDING-BOTTOM: 0px; PADDING-TOP: 0px; PADDING-LEFT: 0px; MARGIN: 0px 0px 10px; LINE-HEIGHT: 28px; PADDING-RIGHT: 0px">skytf=> insert into test_result1 select generate_series(1,10),'a';<br style="LINE-HEIGHT: 28px"/>INSERT 0 10</p> <p style="PADDING-BOTTOM: 0px; PADDING-TOP: 0px; PADDING-LEFT: 0px; MARGIN: 0px 0px 10px; LINE-HEIGHT: 28px; PADDING-RIGHT: 0px">skytf=> insert into test_result2 select generate_series(1,10),'b';<br style="LINE-HEIGHT: 28px"/>INSERT 0 10</p> <p style="PADDING-BOTTOM: 0px; PADDING-TOP: 0px; PADDING-LEFT: 0px; MARGIN: 0px 0px 10px; LINE-HEIGHT: 28px; PADDING-RIGHT: 0px">skytf=> select * From test_result1;<br style="LINE-HEIGHT: 28px"/> id | name<span class="Apple-converted-space"> </span><br style="LINE-HEIGHT: 28px"/>----+------<br style="LINE-HEIGHT: 28px"/> 1 | a<br style="LINE-HEIGHT: 28px"/> 2 | a<br style="LINE-HEIGHT: 28px"/> 3 | a<br style="LINE-HEIGHT: 28px"/> 4 | a<br style="LINE-HEIGHT: 28px"/> 5 | a<br style="LINE-HEIGHT: 28px"/> 6 | a<br style="LINE-HEIGHT: 28px"/> 7 | a<br style="LINE-HEIGHT: 28px"/> 8 | a<br style="LINE-HEIGHT: 28px"/> 9 | a<br style="LINE-HEIGHT: 28px"/> 10 | a<br style="LINE-HEIGHT: 28px"/>(10 rows)</p> <p style="PADDING-BOTTOM: 0px; PADDING-TOP: 0px; PADDING-LEFT: 0px; MARGIN: 0px 0px 10px; LINE-HEIGHT: 28px; PADDING-RIGHT: 0px">skytf=> select * From test_result2;<br style="LINE-HEIGHT: 28px"/> id | name<span class="Apple-converted-space"> </span><br style="LINE-HEIGHT: 28px"/>----+------<br style="LINE-HEIGHT: 28px"/> 1 | b<br style="LINE-HEIGHT: 28px"/> 2 | b<br style="LINE-HEIGHT: 28px"/> 3 | b<br style="LINE-HEIGHT: 28px"/> 4 | b<br style="LINE-HEIGHT: 28px"/> 5 | b<br style="LINE-HEIGHT: 28px"/> 6 | b<br style="LINE-HEIGHT: 28px"/> 7 | b<br style="LINE-HEIGHT: 28px"/> 8 | b<br style="LINE-HEIGHT: 28px"/> 9 | b<br style="LINE-HEIGHT: 28px"/> 10 | b<br style="LINE-HEIGHT: 28px"/>(10 rows)</p></td></tr></tbody></table>
**--2 方法一:返回多条记录( 单列)**
<table style="HEIGHT: 383px; WIDTH: 767px; WHITE-SPACE: normal; WORD-SPACING: 0px; TEXT-TRANSFORM: none; COLOR: rgb(51,51,51); TEXT-ALIGN: left; FONT: 16px/28px 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; WIDOWS: 1; LETTER-SPACING: normal; BACKGROUND-COLOR: rgb(220,231,230); TEXT-INDENT: 0px; -webkit-text-stroke-width: 0px" cellspacing="1" cellpadding="1" width="767" border="1"><tbody style="LINE-HEIGHT: 28px"><tr style="LINE-HEIGHT: 28px"><td style="LINE-HEIGHT: 28px"> CREATE OR REPLACE FUNCTION skytf.func_test_result_single ( in_id integer)<br style="LINE-HEIGHT: 28px"/> <strong style="LINE-HEIGHT: 28px"><font style="LINE-HEIGHT: 28px" color="#ff0000">RETURNS SETOF varchar</font></strong><span class="Apple-converted-space"> </span>as<br style="LINE-HEIGHT: 28px"/>$$<br style="LINE-HEIGHT: 28px"/>DECLARE<br style="LINE-HEIGHT: 28px"/> v_name varchar;<br style="LINE-HEIGHT: 28px"/>BEGIN<br style="LINE-HEIGHT: 28px"/> <span class="Apple-converted-space"> </span><br style="LINE-HEIGHT: 28px"/> for v_name in ( (select name from test_result1 where id = in_id) union (select name from test_result2 where id = in_id) )loop<br style="LINE-HEIGHT: 28px"/> RETURN NEXT v_name;<br style="LINE-HEIGHT: 28px"/> end loop;<br style="LINE-HEIGHT: 28px"/> return;<br style="LINE-HEIGHT: 28px"/>END;<br style="LINE-HEIGHT: 28px"/>$$<br style="LINE-HEIGHT: 28px"/>LANGUAGE PLPGSQL;</td></tr></tbody></table>
**--执行函数**
<table style="WHITE-SPACE: normal; WORD-SPACING: 0px; TEXT-TRANSFORM: none; COLOR: rgb(51,51,51); TEXT-ALIGN: left; FONT: 16px/28px 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; WIDOWS: 1; LETTER-SPACING: normal; BACKGROUND-COLOR: rgb(220,231,230); TEXT-INDENT: 0px; -webkit-text-stroke-width: 0px" cellspacing="1" cellpadding="1" width="80%" border="1"><tbody style="LINE-HEIGHT: 28px"><tr style="LINE-HEIGHT: 28px"><td style="LINE-HEIGHT: 28px"> skytf=> SELECT * FROM func_test_result_single(1) ;<br style="LINE-HEIGHT: 28px"/> func_test_result_single<span class="Apple-converted-space"> </span><br style="LINE-HEIGHT: 28px"/>-------------------------<br style="LINE-HEIGHT: 28px"/> b<br style="LINE-HEIGHT: 28px"/> a<br style="LINE-HEIGHT: 28px"/>(2 rows)</td></tr></tbody></table>
**--3 方法二:使用 reutrn query 返回多条记录( 单列)**
<table style="HEIGHT: 353px; WIDTH: 768px; WHITE-SPACE: normal; WORD-SPACING: 0px; TEXT-TRANSFORM: none; COLOR: rgb(51,51,51); TEXT-ALIGN: left; FONT: 16px/28px 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; WIDOWS: 1; LETTER-SPACING: normal; BACKGROUND-COLOR: rgb(220,231,230); TEXT-INDENT: 0px; -webkit-text-stroke-width: 0px" cellspacing="1" cellpadding="1" width="768" border="1"><tbody style="LINE-HEIGHT: 28px"><tr style="LINE-HEIGHT: 28px"><td style="LINE-HEIGHT: 28px"> CREATE OR REPLACE FUNCTION skytf.func_test_result_query_single ( in_id integer)<br style="LINE-HEIGHT: 28px"/> <strong style="LINE-HEIGHT: 28px"><font style="LINE-HEIGHT: 28px" color="#ff0000">RETURNS<span class="Apple-converted-space"> </span></font><font style="LINE-HEIGHT: 28px" color="#ff0000">SETOF varchar<span class="Apple-converted-space"> </span></font></strong>as<br style="LINE-HEIGHT: 28px"/>$$<br style="LINE-HEIGHT: 28px"/>DECLARE<br style="LINE-HEIGHT: 28px"/> v_rec RECORD;<br style="LINE-HEIGHT: 28px"/>BEGIN<br style="LINE-HEIGHT: 28px"/> <span class="Apple-converted-space"> </span><br style="LINE-HEIGHT: 28px"/> return query ( (select name from test_result1 where id = in_id) union (select name from test_result2 where id = in_id) ); <p style="PADDING-BOTTOM: 0px; PADDING-TOP: 0px; PADDING-LEFT: 0px; MARGIN: 0px 0px 10px; LINE-HEIGHT: 28px; PADDING-RIGHT: 0px"> return;<br style="LINE-HEIGHT: 28px"/>END;<br style="LINE-HEIGHT: 28px"/>$$<br style="LINE-HEIGHT: 28px"/>LANGUAGE PLPGSQL;</p></td></tr></tbody></table>
**--执行函数**
<table style="WHITE-SPACE: normal; WORD-SPACING: 0px; TEXT-TRANSFORM: none; COLOR: rgb(51,51,51); TEXT-ALIGN: left; FONT: 16px/28px 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; WIDOWS: 1; LETTER-SPACING: normal; BACKGROUND-COLOR: rgb(220,231,230); TEXT-INDENT: 0px; -webkit-text-stroke-width: 0px" cellspacing="1" cellpadding="1" width="80%" border="1"><tbody style="LINE-HEIGHT: 28px"><tr style="LINE-HEIGHT: 28px"><td style="LINE-HEIGHT: 28px"> skytf=> select func_test_result_query_single (1);<br style="LINE-HEIGHT: 28px"/> func_test_result_query_single<span class="Apple-converted-space"> </span><br style="LINE-HEIGHT: 28px"/>-------------------------------<br style="LINE-HEIGHT: 28px"/> b<br style="LINE-HEIGHT: 28px"/> a<br style="LINE-HEIGHT: 28px"/>(2 rows)</td></tr></tbody></table>
备注: 在返回指定 SETOF varchar 返回 varchar 类型单个字段,接下来介绍下返回多条记录多列的场景。
**二 测试二:返回多条记录(多列)
--2.1 使用游标和"RETURNS SETOF RECORD" 返回多条记录( 多列)**
<table style="HEIGHT: 383px; WIDTH: 761px; WHITE-SPACE: normal; WORD-SPACING: 0px; TEXT-TRANSFORM: none; COLOR: rgb(51,51,51); TEXT-ALIGN: left; FONT: 16px/28px 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; WIDOWS: 1; LETTER-SPACING: normal; BACKGROUND-COLOR: rgb(220,231,230); TEXT-INDENT: 0px; -webkit-text-stroke-width: 0px" cellspacing="1" cellpadding="1" width="761" border="1"><tbody style="LINE-HEIGHT: 28px"><tr style="LINE-HEIGHT: 28px"><td style="LINE-HEIGHT: 28px"> CREATE OR REPLACE FUNCTION skytf.func_test_result_muti ( in_id integer)<br style="LINE-HEIGHT: 28px"/> <strong style="LINE-HEIGHT: 28px"><font style="LINE-HEIGHT: 28px" color="#ff0000">RETURNS SETOF RECORD<span class="Apple-converted-space"> </span></font></strong>as<br style="LINE-HEIGHT: 28px"/>$$<br style="LINE-HEIGHT: 28px"/>DECLARE<br style="LINE-HEIGHT: 28px"/> v_rec RECORD;<br style="LINE-HEIGHT: 28px"/>BEGIN<br style="LINE-HEIGHT: 28px"/> <span class="Apple-converted-space"> </span><br style="LINE-HEIGHT: 28px"/> for v_rec in ( (select id , name from test_result1 where id = in_id) union (select id , name from test_result2 where id = in_id) )loop<br style="LINE-HEIGHT: 28px"/> RETURN NEXT v_rec;<br style="LINE-HEIGHT: 28px"/> end loop;<br style="LINE-HEIGHT: 28px"/> return;<br style="LINE-HEIGHT: 28px"/>END;<br style="LINE-HEIGHT: 28px"/>$$<br style="LINE-HEIGHT: 28px"/>LANGUAGE PLPGSQL;</td></tr></tbody></table>
**--执行函数**
<table style="WHITE-SPACE: normal; WORD-SPACING: 0px; TEXT-TRANSFORM: none; COLOR: rgb(51,51,51); TEXT-ALIGN: left; FONT: 16px/28px 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; WIDOWS: 1; LETTER-SPACING: normal; BACKGROUND-COLOR: rgb(220,231,230); TEXT-INDENT: 0px; -webkit-text-stroke-width: 0px" cellspacing="1" cellpadding="1" width="80%" border="1"><tbody style="LINE-HEIGHT: 28px"><tr style="LINE-HEIGHT: 28px"><td style="LINE-HEIGHT: 28px"> skytf=> SELECT * FROM func_test_result_muti(1) t(id integer,name varchar);<br style="LINE-HEIGHT: 28px"/> id | name<span class="Apple-converted-space"> </span><br style="LINE-HEIGHT: 28px"/>----+------<br style="LINE-HEIGHT: 28px"/> 1 | a<br style="LINE-HEIGHT: 28px"/> 1 | b<br style="LINE-HEIGHT: 28px"/>(2 rows) </td></tr></tbody></table>
**--2.2 使用 reutrn query 返回多条记录( 多列)**
<table style="WHITE-SPACE: normal; WORD-SPACING: 0px; TEXT-TRANSFORM: none; COLOR: rgb(51,51,51); TEXT-ALIGN: left; FONT: 16px/28px 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; WIDOWS: 1; LETTER-SPACING: normal; BACKGROUND-COLOR: rgb(220,231,230); TEXT-INDENT: 0px; -webkit-text-stroke-width: 0px" cellspacing="1" cellpadding="1" width="80%" border="1"><tbody style="LINE-HEIGHT: 28px"><tr style="LINE-HEIGHT: 28px"><td style="LINE-HEIGHT: 28px"> CREATE OR REPLACE FUNCTION skytf.func_test_result_query ( in_id integer)<br style="LINE-HEIGHT: 28px"/> <strong style="LINE-HEIGHT: 28px"><font style="LINE-HEIGHT: 28px" color="#ff0000">RETURNS SETOF RECORD</font></strong><span class="Apple-converted-space"> </span>as<br style="LINE-HEIGHT: 28px"/>$$<br style="LINE-HEIGHT: 28px"/>DECLARE<br style="LINE-HEIGHT: 28px"/> v_rec RECORD;<br style="LINE-HEIGHT: 28px"/>BEGIN<br style="LINE-HEIGHT: 28px"/> <span class="Apple-converted-space"> </span><br style="LINE-HEIGHT: 28px"/> <span class="Apple-converted-space"> </span><strong style="LINE-HEIGHT: 28px"><font style="LINE-HEIGHT: 28px" color="#ff0000">return query</font></strong> ( (select id , name from test_result1 where id = in_id) union (select id , name from test_result2 where id = in_id) ); <p style="PADDING-BOTTOM: 0px; PADDING-TOP: 0px; PADDING-LEFT: 0px; MARGIN: 0px 0px 10px; LINE-HEIGHT: 28px; PADDING-RIGHT: 0px"> return;<br style="LINE-HEIGHT: 28px"/>END;<br style="LINE-HEIGHT: 28px"/>$$<br style="LINE-HEIGHT: 28px"/>LANGUAGE PLPGSQL;</p></td></tr></tbody></table>
**--执行函数**
<table style="WHITE-SPACE: normal; WORD-SPACING: 0px; TEXT-TRANSFORM: none; COLOR: rgb(51,51,51); TEXT-ALIGN: left; FONT: 16px/28px 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; WIDOWS: 1; LETTER-SPACING: normal; BACKGROUND-COLOR: rgb(220,231,230); TEXT-INDENT: 0px; -webkit-text-stroke-width: 0px" cellspacing="1" cellpadding="1" width="80%" border="1"><tbody style="LINE-HEIGHT: 28px"><tr style="LINE-HEIGHT: 28px"><td style="LINE-HEIGHT: 28px"> skytf=> SELECT * FROM func_test_result_query(1) t(id integer,name varchar);<br style="LINE-HEIGHT: 28px"/> id | name<span class="Apple-converted-space"> </span><br style="LINE-HEIGHT: 28px"/>----+------<br style="LINE-HEIGHT: 28px"/> 1 | a<br style="LINE-HEIGHT: 28px"/> 1 | b<br style="LINE-HEIGHT: 28px"/>(2 rows)</td></tr></tbody></table>
**--2.3 使用 out 输出参数 返回多条记录( 多列)**
<table style="HEIGHT: 458px; WIDTH: 818px; WHITE-SPACE: normal; WORD-SPACING: 0px; TEXT-TRANSFORM: none; COLOR: rgb(51,51,51); TEXT-ALIGN: left; FONT: 16px/28px 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; WIDOWS: 1; LETTER-SPACING: normal; BACKGROUND-COLOR: rgb(220,231,230); TEXT-INDENT: 0px; -webkit-text-stroke-width: 0px" cellspacing="1" cellpadding="1" width="818" border="1"><tbody style="LINE-HEIGHT: 28px"><tr style="LINE-HEIGHT: 28px"><td style="LINE-HEIGHT: 28px"> CREATE OR REPLACE FUNCTION skytf.func_test_result_out ( in_id integer,out o_id integer,out o_name varchar)<br style="LINE-HEIGHT: 28px"/> RETURNS SETOF RECORD as<br style="LINE-HEIGHT: 28px"/>$$<br style="LINE-HEIGHT: 28px"/>DECLARE<br style="LINE-HEIGHT: 28px"/> v_rec RECORD;<br style="LINE-HEIGHT: 28px"/>BEGIN<br style="LINE-HEIGHT: 28px"/> <span class="Apple-converted-space"> </span><br style="LINE-HEIGHT: 28px"/> for v_rec in ( (select id , name from test_result1 where id = in_id) union (select id , name from test_result2 where id = in_id) )loop<br style="LINE-HEIGHT: 28px"/> o_id := v_rec.id;<br style="LINE-HEIGHT: 28px"/> o_name := v_rec.name;<br style="LINE-HEIGHT: 28px"/> RETURN NEXT ;<br style="LINE-HEIGHT: 28px"/> end loop;<br style="LINE-HEIGHT: 28px"/> return;<br style="LINE-HEIGHT: 28px"/>END;<br style="LINE-HEIGHT: 28px"/>$$<br style="LINE-HEIGHT: 28px"/>LANGUAGE PLPGSQL;</td></tr></tbody></table>
**--执行函数**
<table style="WHITE-SPACE: normal; WORD-SPACING: 0px; TEXT-TRANSFORM: none; COLOR: rgb(51,51,51); TEXT-ALIGN: left; FONT: 16px/28px 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; WIDOWS: 1; LETTER-SPACING: normal; BACKGROUND-COLOR: rgb(220,231,230); TEXT-INDENT: 0px; -webkit-text-stroke-width: 0px" cellspacing="1" cellpadding="1" width="80%" border="1"><tbody style="LINE-HEIGHT: 28px"><tr style="LINE-HEIGHT: 28px"><td style="LINE-HEIGHT: 28px"> skytf=> select skytf.func_test_result_out(1);<br style="LINE-HEIGHT: 28px"/> func_test_result_out<span class="Apple-converted-space"> </span><br style="LINE-HEIGHT: 28px"/>----------------------<br style="LINE-HEIGHT: 28px"/> (1,a)<br style="LINE-HEIGHT: 28px"/> (1,b)<br style="LINE-HEIGHT: 28px"/>(2 rows)</td></tr></tbody></table>
**三 总结:**
以上只是为了演示 PostgreSQL 函数的语法给出简单的例子,生产过程中的 function 会复杂很多。
- 数据表
- 模式Schema
- 表的继承和分区
- 常用数据类型
- 函数和操作符-一
- 函数和操作符-二
- 函数和操作符-三
- 索引
- 事物隔离
- 性能提升技巧
- 服务器配置
- 角色和权限
- 数据库管理
- 数据库维护
- 系统表
- 系统视图
- SQL语言函数
- PL-pgSQL过程语言
- PostgreSQL 序列(SEQUENCE)
- PostgreSQL的时间-日期函数使用
- PostgreSQL 查看数据库,索引,表,表空间大小
- 用以查询某表的详细 包含表字段的注释信息
- PostgreSQL 系统表查看系统信息
- postgre存储过程简单实用方法
- PostgreSQL实用日常维护SQL
- PostgreSQL的时间函数使用整理
- 命令
- pg_ctl控制服务器
- initdb 初始化数据库簇
- createdb创建数据库
- dropdb 删除数据库
- createuser创建用户
- dropuser 删除用户
- psql交互式工具
- psql命令手册
- pg_dump 数据库转储
- pg_restore恢复数据库
- vacuumdb 清理优化数据库
- reindexdb 数据库重创索引
- createlang 安装过程语言
- droplang 删除过程语言
- pg_upgrade 升级数据库簇
- 调试存储过程
- 客户端命令-一
- 客户端命令-二
- 使用技巧
- PostgreSQL删除重复数据
- postgresql 小技巧
- PostgreSQL的10进制与16进制互转
- PostgreSQL的汉字转拼音
- Postgres重复数据的更新一例
- PostgreSQL使用with一例
- PostgreSQL在函数内返回returning
- PostgreSQL中的group_concat使用
- PostgreSQL数据库切割和组合字段函数
- postgresql重复数据的删除
- PostgreSQL的递归查询(with recursive)
- PostgreSQL函数如何返回数据集
- PostgreSQL分区表(Table Partitioning)应用 - David_Tang - 博客园
- PostgreSQL: function 返回结果集多列和单列的例子
- 利用pgAgent创建定时任务
- 浅谈 PostgreSQL 类型转换类似Oracle
- postgresql在windows(包括win7)下的安装配置
- PostgreSQL简介、安装、用户管理、启动关闭、创建删除数据库 (2010-11-08 12-52-51)转载▼标签: 杂谈分类: PostgreSQL
- PostgreSQL的generate_series函数应用
- PostgreSQL 8.3.1 全文检索(Full Text Search)
- postgresql record 使用
- 备份恢复
- PostgreSQL基于时间点恢复(PITR)
- Postgresql基于时间点恢复PITR案例(二)
- Postgres逻辑备份脚本
- Postgres invalid command \N数据恢复处理