我定义了一个函数如下

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
有人能帮忙吗?

最佳答案

简而言之:将查询放入FOR循环,而不是游标。
FOR循环记录如下:
[标签]
查询循环中的目标
声明
结束循环[标签];
其中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

关于postgresql - 用游标执行功能时出错,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25931418/

10-13 04:46