我将一个函数定义为以下
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
有人可以帮忙吗?
答案 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。