我不知道如何在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。请帮我找到解决方案。
提前致谢!
答案 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查询来完成,并且该表单将以更快的速度运行。