从 PostgreSQL 游标中获取行

5

我有光标代码:

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

你有什么想法,应该用什么代码替换它呢?

结果

非常感谢您的帮助!


我看不出你想要的与 SELECT * FROM cliente; 有什么不同,可能是因为我不理解 ms-sql-server。 - Jasen
实际上是一样的。不同之处在于我希望通过光标显示表格。 - Mike Pérez
那就使用一个for循环吧。 - Jasen
1
为什么要使用游标?它只会减慢查询速度。内联PL/pgSQL与PL/pgSQL函数一样在事务中运行。 - Jasen
我该如何使用循环@Jasen?感谢您的回答。我必须在PLPGSQL中使用游标来执行与SQL服务器语句块相同的操作。 - Mike Pérez
2个回答

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 将对您的会话保密。


@Jasen,你的解释太好了,讲得很清楚。感谢你的快速帮助! - Mike Pérez

1
如果您只想从查询中返回所有行,请使用
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类型,允许您通过文本名称使用游标。在我看来,这是最简单的方法(阅读更多)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接