PostgreSQL 游标

12

我正在尝试学习使用PostgreSQL的基本光标。这是我的脚本:

DECLARE cur_employees CURSOR FOR
  SELECT *
  FROM   employee

CLOSE cur_employees 

我想遍历这个列表并输出其中处于激活状态的元素。我应该从哪里开始?


1
首先添加一个WHERE子句,选择活动的条目。 - aib
2
阅读手册中关于游标的章节 - Erwin Brandstetter
我按照你告诉我的做了:DECLARE cur_employees CURSOR FOR SELECT * FROM employee where active = 'active'CLOSE cur_employees 但是我得到了以下错误: - Karl
错误:在“CLOSE”附近的语法错误 第6行:CLOSE cur_employees ^********** 错误 **********错误:在“CLOSE”附近的语法错误 SQL状态:42601 - Karl
@Karl:你的问题是关于SQL语言的游标还是pl/pgsql语言的游标? - A.H.
据我所知,当我在没有关闭或打开的情况下声明游标时,SQL语言会给我返回此错误:ERROR: DECLARE CURSOR只能在事务块中使用。 - Karl
2个回答

27

在PostgreSQL中,即使在使用plpgsql处理查询结果时,通常也很少需要显式地使用游标。这与许多其他SQL数据库形成了鲜明的对比,那里几乎总是使用游标。

在plpgsql中,你可以简单地编写如下代码:

DECLARE
  emp employee%rowtype;
BEGIN
  FOR emp IN SELECT * FROM employee LOOP
    IF emp.active THEN
      RAISE INFO 'Active: %', emp.employee_id
    END IF;
  END LOOP;
END
在上述代码中,plpgsql语言处理程序负责打开、绑定、获取和关闭自身(更多关于声明控制结构的内容)。
从PostgreSQL 9.0开始,你可以通过“DO”块简单地执行plpgsql。对于之前的版本,你需要创建一个函数并选择它。如果你正在寻找与在SQL Server上使用光标迭代结果的PostgreSQL等价物,那就是它。请注意,迭代等操作不是SQL语言方言的一部分,只是plpgsql(或其他嵌入式语言)的一部分。
在SQL级别上,“DECLARE CURSOR xxx”语法可以用于这样的情况:
DECLARE cur_employees CURSOR FOR SELECT * FROM employee;
FETCH NEXT FROM cur_employees;
// etc..
CLOSE cur_employees;

这可以用来仔细地获取查询结果集的一部分。然而,使用这些是不寻常的,因为通常您的客户端驱动程序会提供某种功能来实现这一点(例如,在JDBC中可滚动的结果集)。您还可以从类似于Oracle的函数中返回游标,尽管这也是一个相对罕见的用例。


1
记住,人们试图使用光标处理的90%以上内容都可以通过基于集合的操作更好地处理。你几乎永远不应该考虑循环遍历数据集,除了有经验的数据库管理员之外,没有人应该考虑编写光标。这是一种技术,直到你非常资深并且知道何时适用才应该学习。如果你刚开始学习SQL,请跳过这个技术,等大约十年后再来学习。 - HLGEM
我想进一步谈谈使用游标的评论。如果您正在使用游标,那么您可能做错了。SQL是建立在集合之上的,并且DBMS是针对此进行优化的;它尝试使用整个数据集进行操作,您必须有一个非常好的理由才能强制其逐行处理。除了数据库维护的奇特情况外,如果一行数据确实依赖于前一行中的值,那么您可以考虑使用游标,但这可能是一个设计不良的表。否则,使用游标的程序员可能不理解SQL哲学。 - Manngo

0
通常,我们需要为游标声明一个DECLARE,然后打开游标(这将实现结果集),多次使用FETCH操作单独检索结果集中的行,最后关闭游标。
您似乎是在DECLARE之后直接进行了CLOSE操作。因此出现了语法错误,因为您从未执行OPEN操作。

嗯,Karl没有提到他是想在SQL还是pl/pgsql中使用游标。对于SQL来说,没有OPEN命令,因为这个操作在DECLARE语句中已经隐式完成了。 - A.H.

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