0

我不知道如何在 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 49 103 45735 115 115 115 10 2015 10 201 28 167 308 96 1211 110 7 172 7 172 7 172 7 172 7 172 7 1314 22 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。我想将我的输出视为两列,一列用于计数,另一列用于 user_id。请帮我找到解决方案。

提前致谢!

4

2 回答 2

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;

请注意,不推荐使用带引号的语言名称。您应该使用 egplpgsql代替'plpgsql'sql代替'sql'.

于 2012-10-23T11:33:39.663 回答
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';

引用手册

如果你用输出参数声明函数,只写 RETURN NEXT 不带表达式。输出参数变量的当前值将被保存以供最终返回

请注意,您的设计也非常低效;这可以通过带有子查询的单个常规 SQL 查询来完成,并且这种形式的运行速度会大大提高。

于 2012-10-23T11:32:55.090 回答