
正文
包含postgresql存储过程的词条
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
postgresql存储过程怎么用
PostgreSQL有pldbgapi扩展,先安装此扩展。
首先,需要将debug的模组载入到PostgreSQL服务器中去。做法是: 在pgAdminIII中以管理员登录,然后选择菜单“工具-服务器配置-postgresql.conf”,
在配置窗口中,双击项目"shared_preload_libraries",
在其设定窗口中,将值设置成plugin_debugger的路径(Windows 9.3版本的为$libdir/plugin_debugger.dll, $libdir一般为PostgreSQL安装目录下的lib文件夹)。非Windows系统的后缀名会有所不同,可能为plugin_debugger.so。
注意,在做这一步时最好先备份配置文件,以防指定文件找不到而导致服务器不能启动。
在设定完成之后,重新启动PostgreSQL服务(以启动debug插件)。
然后在pgAdminIII中扩展安装时选择如下图项目,
这样在函数的右键菜单中就有调试选项了,
当然,最常用的调试方式就是自己直接调用函数来查看执行结果是否正确。
相关问答
Q1: PostgreSQL Oracle 兼容性之存储过程
在oracle中,函数和存储过程是经常使用到的,并且有所区别;而postgresql中函数和存储过程都是相同定义的。
1.定义:定义存储过程的关键字为procedure。
2.创建存储过程
例:
(无参数)
(有参有返)
总结 :
1.创建存储过程的关键字为procedure。
2.传参列表中的参数可以用in,out,in out修饰,参数类型一定不能写大小。列表中可以有多个输入输出参数。
3.存储过程中定义的参数列表不需要用declare声明,声明参数类型时需要写大小的一定要带上大小。
4.as可以用is替换。
5.调用带输出参数的过程必须要声明变量来接收输出参数值。
6.执行存储过程有两种方式,一种是使用execute,另一种是用begin和end包住。
1.定义:定义函数的关键字为function。
2.创建函数
总结 :
1.定义函数的关键字为function 。
2.必须有返回值,且声明返回值类型时不需要加大小。
3.函数中定义的参数列表不需要用declare声明,声明参数类型时需要写大小的一定要带上大小。
4.as可以用is替换。
5.执行存储过程有两种方式,一种是使用select,另一种是用begin和end包住。
不同点:
1.存储过程定义关键字用procedure,函数定义用function。
2.存储过程中不能用return返回值,但函数中可以,而且函数中必须有return子句。
3.执行方式略有不同,存储过程的执行方式有两种(1.使用execute2.使用begin和end),函数除了存储过程的两种方式外,还可以当做表达式使用,例如放在select中(select f1() form dual;)。
postgresql则将函数和存储过程合为一体,不再明确区分存储过程与函数。
1.定义:定义函数(存储过程 )的关键字为function。
2.创建
例:
1.必须有有returns(注意是returns不是return)子句,无返回值时returns viod
2.执行时,有返回值用select,无返回值时用perform
3.必须指定语言LANGUAGE
Q2: Postgres-存储过程 return 详解
如果返回一个 数字或者字符 比较简单,那么多行多列怎么办呢,分为以下几种情况【东西很多,这里只做简单列举】
返回多行单列
又分为几种方式
1. return next,用在 for 循环中
CREATEORREPLACEFUNCTIONfuncname ( in_idinteger)RETURNSSETOFvarcharas $$DECLARE v_name varchar;BEGINforv_namein( (selectnamefromtest_result1whereid=in_id)union(selectnamefromtest_result2whereid= in_id) ) loop
RETURNNEXT v_name;
end loop;
return;END;
$$
LANGUAGE PLPGSQL;
注意
1. 循环外还有个 return
2. 需要实现声明 v_name
2. return query,无需 for 循环
CREATEORREPLACEFUNCTIONfuncname ( in_idinteger)RETURNSSETOFvarcharas $$DECLARE v_rec RECORD;BEGINreturnquery ( (selectnamefromtest_result1whereid=in_id)union(selectnamefromtest_result2whereid= in_id) );
return;END;$$LANGUAGE PLPGSQL;
注意:如果 返回类型为 setof,最好用如下方法
RETURNQUERYEXECUTESQL
不要这么用
executesqlinto out;returnout;
返回多行多列
也有多种方式
1. 使用 return next 和 setof record ,需要 for 循环
CREATEORREPLACEFUNCTIONfuncname ( in_idinteger)RETURNSSETOF RECORDas $$DECLARE v_rec RECORD; BEGINforv_recin( (selectid , namefromtest_result1whereid=in_id)union(selectid , namefromtest_result2whereid= in_id) )loop
RETURNNEXT v_rec;
end loop;
return;END;
$$
LANGUAGE PLPGSQL;
注意
1. 读取表的整行数据时才能用 record
2. 如果读取的数据不是整行,需要自定义 复合数据类型,否则会报如下错误
ERROR: acolumndefinition listisrequiredforfunctions returning "record"
定义复合类型 ,示例如下
createtype myout2as (
road_num int,
freq bigint);createorreplacefunctiontest(cartext, time1text, time2text)returnssetof myout2as $$declare
array1 text[];
array2 text[];
len1 integer;
len2 integer;
x integer;
y integer;
road_str text;
car_str text;
sql text;
i myout2;
begin-- vin 号拼接selectregexp_split_to_array(car,',')into array2;
selectarray_length(array2,1)into len2;
car_str :='';
y :=1;
whiley= len2 loop
car_str :=car_str||quote_literal(array2[y])||',';
y :=y+1;
end loop;
-- sql 拼接sql :='select road_number, sum(frequency) from heat_map where date_key = '''|| time1
||'-01'' and date_key ='''|| time2
||'-20'' and vin in ('||rtrim(car_str,',')
||')group by road_number;';
--execute sql into out;foriinexecute sql loop
returnnext i;
end loop;
return;end$$ language plpgsql;
在执行时可能会报如下错误
ERROR:set-valuedfunctioncalledincontext that cannot accept aset
解决方法
select funcname(arg);--改为select*fromfuncname(arg);
2. return query,无需 for 循环
CREATEORREPLACEFUNCTIONfuncname ( in_idinteger)RETURNSSETOF RECORDas $$DECLARE v_rec RECORD;BEGINreturnquery ( (selectid , namefromtest_result1whereid=in_id)union(selectid , namefromtest_result2whereid= in_id) );
return;END;
$$
LANGUAGE PLPGSQL;
3. 使用 out 输出参数
CREATEORREPLACEFUNCTIONfuncname ( in_idinteger,out o_idinteger,out o_namevarchar)
RETURNSSETOF RECORDas $$DECLARE v_rec RECORD;BEGINforv_recin( (selectid , namefromtest_result1whereid=in_id)union(selectid , namefromtest_result2whereid= in_id) )loop
o_id := v_rec.id;
o_name := v_rec.name;
RETURNNEXT ;
end loop;
return;END;
$$
LANGUAGE PLPGSQL;
总结 - return next return query
我们可以看到上面无论是单列多行还是多列多行,都用到了 return next 和 return query 方法
在 plpgsql 中,如果存储过程返回 setof sometype,则返回值必须在 return next 或者 return query 中声明,然后有一个不带参数的 retrun 命令,告诉函数执行完毕;【setof 就意味着 多行】
用法如下
RETURNNEXT expression;RETURN QUERY query;RETURNQUERYEXECUTEcommand-string[ USING expression [, ... ]];
return next 可以用于标量和复合类型数据;
return query 命令将查询到的一条结果追加到函数的结果集中;
二者在单一集合返回函数中自由混合,在这种情况下,结果将被级联。【有待研究】
return query execute 是 return query 的变形,它指定 sql 将被动态执行;
returnqueryselectroad_number,sum(frequency)fromheat_mapgroupbyroad_number;--这样可以sql :='select road_number, sum(frequency) from heat_map group by road_number';returnquery sql;--这样不行
参考资料:
自定义类型并返回数组
return next return query
function返回多列多行
返回结果集多列和单列的例子
PostgreSQL存储过程(1)-基于SQL的存储过程
动态SQL
postgresql, pgadmin error RETURN cannot have a parameter in function returning set
存储过程输出参数
PostgreSQL存储过程(3)-流程控制语句
Q3: postgresql 怎样对存储过程进行调试
PostgreSQL有pldbgapi扩展,先安装此扩展。
首先,需要将debug的模组载入到PostgreSQL服务器中去。做法是: 在pgAdminIII中以管理员登录,然后选择菜单“工具-服务器配置-postgresql.conf”,
在配置窗口中,双击项目"shared_preload_libraries",
在其设定窗口中,将值设置成plugin_debugger的路径(Windows 9.3版本的为$libdir/plugin_debugger.dll, $libdir一般为PostgreSQL安装目录下的lib文件夹)。非Windows系统的后缀名会有所不同,可能为plugin_debugger.so。
注意,在做这一步时最好先备份配置文件,以防指定文件找不到而导致服务器不能启动。
在设定完成之后,重新启动PostgreSQL服务(以启动debug插件)。
然后在pgAdminIII中扩展安装时选择如下图项目,
这样在函数的右键菜单中就有调试选项了,
当然,最常用的调试方式就是自己直接调用函数来查看执行结果是否正确。







