2014-09-19 97 views
1

執行的函數我定義的函數如下錯誤,而與光標

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 FOR over光標

任何人都可以請幫忙嗎?

回答

3

簡短回答:將查詢放在FOR循環中,而不是光標。

[ label ]
FOR target IN query LOOP
statements
END LOOP [ label ];

query被描述爲:

The query used in this type of FOR statement can be any SQL command that returns rows to the caller: SELECT is the most common case, but you can also use INSERT, UPDATE, or DELETE with a RETURNING clause. Some utility commands such as EXPLAIN will work too.

這並不意味着一個遊標的名稱可能是有

FOR環路進行了說明。

您可以爲它提供遊標而不是遊標的SQL查詢。

如果遊標確實需要在那裏,從一個光標讀取結果的命令是FETCH,所以這種形式將被接受:

FOR activityCommentRow in FETCH ALL FROM cur1 

FETCH變體,例如,如果只有3行需要:

FOR activityCommentRow in FETCH 3 FROM cur1 
0

當您使用FOR IN CURSOR聲明,那麼你不應該顯式地打開遊標 -

The cursor variable must have been bound to some query when it was declared, and it cannot be open already. The FOR statement automatically opens the cursor, and it closes the cursor again when the loop exits.

只有當您使用某種通用形式並且您通過語句FETCH從光標讀取數據時才需要顯式打開。詳情請見doc