使用游标执行函数时出错

时间:2014-09-19 10:08:00

标签: postgresql postgresql-9.1 plpgsql

我将一个函数定义为以下

CREATE OR REPLACE FUNCTION processActivityCommentTable() RETURNS INTEGER AS $$
DECLARE
activityCommentRow RECORD;
i RECORD;
activityId integer;
attachments text;
attachmentId integer;
cur1 CURSOR FOR SELECT ac.id, ac.attachments from activitycomment ac where ac.attachments is not null;

BEGIN
OPEN cur1;
FOR activityCommentRow in cur1
    LOOP
    RAISE NOTICE 'currently processing for %s ...', activityCommentRow.id;
        -- can do some processing here
    activityId = activityCommentRow.id;
    attachments = activityCommentRow.attachments;

    SELECT foo FROM regexp_split_to_table(attachments,E'{"id":') as foo;

    FOR i in select * from foo
    LOOP
     select regexp_replace(i,'(,"name").*','') into attachmentId;
        EXECUTE 'INSERT INTO attachment (activity_comment_id) values(' || attachmentId ||') where id= ' activityId; 
    END LOOP;

    END LOOP;
CLOSE cur1;
END;

$$ LANGUAGE plpgsql;
执行时

select processActivityCommentTable();

它给了我以下错误

错误:游标“cur1”已在使用中 SQL状态:42P03 上下文:PL / pgSQL函数processactivitycommenttable()第12行在FOR over cursor

有人可以帮忙吗?

2 个答案:

答案 0 :(得分:3)

简短回答:在FOR循环中放入查询,而不是游标。

FOR循环记录为:

  

[标签]
  对于目标IN查询LOOP
      声明
   END LOOP [标签];

其中query被描述为:

  

此类FOR语句中使用的查询可以是任何SQL命令   将行返回给调用者:SELECT是最常见的情况,但是   您还可以将INSERT,UPDATE或DELETE与RETURNING子句一起使用。   某些实用程序命令(如EXPLAIN)也可以使用。

它并不意味着光标的名称可能就在那里。

您可以为游标而不是游标提供SQL查询。

如果确实需要光标,则从光标读取结果的命令为FETCH,因此将接受此表单:

FOR activityCommentRow in FETCH ALL FROM cur1

FETCH的变体,例如,如果只需要3行:

FOR activityCommentRow in FETCH 3 FROM cur1

答案 1 :(得分:0)

当您使用FOR IN CURSOR语句时,则不应显式打开游标 -

  

游标变量必须在声明时绑定到某个查询,并且它不能打开。 FOR语句自动打开游标,并在循环退出时再次关闭游标。

只有当您使用某个通用表单并且通过语句FETCH从游标中读取数据时,才需要显式打开。详细信息位于doc