从游标PostgreSQL中获取行

时间:2015-01-18 00:23:53

标签: postgresql cursor

我有光标代码:

BEGIN;
DECLARE cliente_cursor 
CURSOR FOR SELECT * FROM cliente;

我想阅读表格' cliente'

中的所有内容

Table 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();

知道代码应该是什么?

Results

任何帮助都会受到很多赞赏!

2 个答案:

答案 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