原始代码如下:
begin
DECLARE
@SQL_STMT NVARCHAR(300),
@V_CLIENT_ID INT,
@V_PGNAME VARCHAR(1000),
@V_LOGID INT;
DECLARE C2 CURSOR FOR SELECT PGNAME,CLIENT_ID FROM GPGLOBAL.GPLOG;
OPEN C2
FETCH NEXT FROM C2 into @V_PGNAME , @V_CLIENT_ID
WHILE(@@FETCH_STATUS=0)
BEGIN
EXEC GETNEXTSEQUENCENUMBER @V_LOGID OUT,'GPLOG_SEQ';
SET @SQL_STMT='UPDATE GPGLOBAL.GPLOG SET LOG_ID='+CAST(@V_LOGID AS VARCHAR)+' WHERE PGNAME='''+@V_PGNAME+''' AND
CLIENT_ID='+CAST(@V_CLIENT_ID AS VARCHAR);
EXEC SP_EXEC_WITH_LOG 'DB-1216',@SQL_STMT;
FETCH NEXT FROM C2 INTO @V_PGNAME , @V_CLIENT_ID
END
CLOSE C2
DEALLOCATE C2
END
上面的这个存储过程会无限执行,主要原因是游标C2是基于表 GPGLOBAL.GPLOG,在游标C2进行循环的时候,循环里的代码改变了GPGLOBAL.GPLOG的数据,
这会导致,C2看到新的改变过的记录,一次循环下去,一直在执行,无法停下来。只要给C2 定义成 static 就可以了。它只会看到游标打开时候的记录,相当于是那个时候的一个snapshot。
DECLARE C2 CURSOR STATIC FOR SELECT PGNAME,CLIENT_ID FROM GPGLOBAL.GPLOG;