postgresql中的存储过程

时间:2012-10-23 11:11:49

标签: postgresql plpgsql

我不知道如何在postgresql中编写存储过程。我试着写一个,但输出错误。

create or replace function getUserId() returns setof integer as 
$BODY$
Declare r integer;cnt integer;
BEGIN
for r in select distinct user_id from system_audit
loop
for cnt in select count(*) from system_audit where user_id=r
loop
return next cnt;
end loop;
return next r;
end loop;
return;
end;
$BODY$
language 'plpgsql';

当我通过输入以下内容检查输出时: -

select * from getUserId()

我将此作为输出: -

58 173 920 106 76 191 14413 1 2 242 1320 -1 2 249 1167 192 2 233 70 98 229 193 45 237 49 103 45735 115 10 201 28 167 308 96 1211 110 7 172 7 13 1614 22 16 178 21 170 7364 99 308 225 13 235 7 199 14 88 23566 118 359 4 9 231 98 165 174 212 21 149 14 105 77 97 416 180 1345 23 59 152 297 239 37 197 133 144

输出正确但问题是这是一个包含两列user_id和count的输出的列。我希望将输出视为两列,一列用于count,另一列用于user_id。请帮我找到解决方案。

提前致谢!

2 个答案:

答案 0 :(得分:4)

如果要获得真实的结果集,则需要将函数声明为returns table (...)

您的方法过于复杂,对于大型表来说会非常慢。整个结果可以使用单个SQL语句获得,该语句不需要使用游标循环:

select user_id, count(*)
from system_audit
group by user_id

这可以放入SQL函数(注意:不是plpgsql):

create or replace function getUserId() 
   returns table (user_id integer, user_count integer)
as   
$BODY$
    select user_id, count(*)
    from system_audit
    group by user_id
$BODY$
language sql;

请注意,不推荐使用引用的语言名称。你应该使用例如plpgsql代替'plpgsql'sql代替'sql'

答案 1 :(得分:0)

您可能希望使用两个out参数声明该函数并返回setof record,类似于(未经测试的):

create or replace function getUserId(user_id OUT integer, cnt OUT integer) returns setof record as 
$BODY$
DECLARE
  r integer;
  cnt integer;
BEGIN
  FOR r IN SELECT DISTINCT user_id FROM system_audit
  LOOP
    FOR cnt IN SELECT count(*) FROM system_audit WHERE user_id=r
    LOOP
      RETURN NEXT;
    END LOOP;
  END LOOP;
  RETURN;
END;
$BODY$
language 'plpgsql';

引用the manual

  

如果您使用输出参数声明了该函数,请只写RETURN   NEXT没有表达。输出参数的当前值   变量将被保存以便最终返回

请注意,您的设计也可怕效率低下;这可以通过带有子查询的单个常规SQL查询来完成,并且该表单将以更快的速度运行。