我有光标代码:
BEGIN;
DECLARE cliente_cursor
CURSOR FOR SELECT * FROM cliente;
我想阅读表格' cliente'
中的所有内容
使用游标。 我有代码适用于SQL Server:
DECLARE cliente_cursor CURSOR
FOR SELECT * FROM cliente
OPEN cliente_cursor
FETCH NEXT FROM cliente_cursor;
While @@FETCH_STATUS=0
BEGIN
FETCH NEXT FROM cliente_cursor;
End
CLOSE cliente_cursor
DEALLOCATE cliente_cursor
我希望有一个适用于PostgreSQL的代码。
我一直在寻找解决方案&看到人们通常建议使用功能。我想知道这个PostgreSQL DBMS中是否有任何方法可以创建与SQL Server中的代码类似的东西。
我写过这段代码:
CREATE OR REPLACE FUNCTION MyFunction()
RETURNS setof cliente AS $$
DECLARE
cursor_cliente CURSOR FOR SELECT * FROM cliente;
rec cliente%ROWTYPE;
BEGIN
OPEN cursor_cliente;
loop
--fetch the table row inside the loop
FETCH cursor_cliente INTO rec;
-- check if there is no record
--exit from loop when record not found
if not found then
exit ;
end if;
end loop;
RETURN;
END;
$$ LANGUAGE plpgsql;
但是当我运行它时,我只能得到:
select MyFunction();
知道代码应该是什么?
任何帮助都会受到很多赞赏!
答案 0 :(得分:5)
CREATE OR REPLACE FUNCTION foo() RETURNS setof cliente
language plpgsql AS $$
DECLARE
x cliente%rowtype ;
BEGIN
FOR x IN SELECT * FROM cliente loop
RETURN NEXT x;
END loop;
END $$;
SELECT * FROM foo();
也可以使用显式游标来完成。
CREATE OR REPLACE FUNCTION foo() RETURNS setof cliente
language plpgsql as $$
DECLARE
x cliente%rowtype ;
cliente_cursor CURSOR FOR SELECT * FROM cliente;
BEGIN
FOR x IN cliente_cursor loop
RETURN NEXT x;
END loop;
END $$;
SELECT * FROM foo();
该函数将继续存在,因此要么给它一个有用的名称并保留它或在完成后删除它。
如果您希望功能pg_temp.foo
的私人名称对您的会话是私有的。
答案 1 :(得分:0)
如果只想返回查询中的所有行,请使用
RETURN QUERY
SELECT ...
和RETURNS TABLE(column1 type1, column2 type2, ...)
作为函数的类型。
或者对于光标:
RETURN QUERY
FETCH ALL FROM cliente_cursor;
要对每一行进行操作,请使用
FOR _record IN
SELECT ...
LOOP
<action1>;
<action2>;
...
END LOOP;
来自this answer。
或者对于光标:
FOR _record IN
FETCH ALL FROM ...
LOOP
<action1>;
<action2>;
...
END LOOP;
用于光标。
请注意,PostgreSQL具有refcursor
类型,该类型允许您使用游标的文本名称。恕我直言,这是最简单的方法(read more)