loveyuqing 发表于 2013-08-15 10:57

IQ存储过程中使用游标时报Cursor not open的解决方法

最近一位网友问了我一个问题,他在一个项目中编写了一个存储过程,这个存储过程用于把一个用户下的所有表和存储过程授权给另一个用户。代码如下:

CREATE PROCEDURE P_ALL_GRANT
as
begin
   declare @S_SQL varchar(2000)
   declare DARECESL dynamic scroll cursor for
         select aa='grant select on LC_FJGS.' || name || ' to LC_FJGSYM' from sysobjects where uid = '109'
               and name <> 'SYSOPTIONDEFAULTS' and type in('U','V') union
         select aa='grant EXECUTE on LC_FJGS.' || proc_name || ' to LC_FJGSYM' from SYSPROCEDURE where creator = '109'
               and proc_name <> 'P_ALL_GRANT'
   open DARECESL
   fetch next DARECESL into @S_SQL
   while(@@sqlstatus = 0)
   begin
       print @S_SQL
       execute(@S_SQL)
       fetch next DARECESL into @S_SQL
   end
   close DARECESL
   deallocate cursor DARECESL
end;


      这个存储过程编译的时候没有问题,但是在执行时报如下错误:
Could not execute statement.
   Cursor not open
   SQLCODE=-180, ODBC 3 State="34000"
   Line 1, column 1
   execute P_ALL_GRANT

      我分析了一下他的存储过程代码,基本的写法没有什么大问题:这个存储过程使用了动态sql语句技术执行grant授权操作。由于grant语句是一种DDL语句,执行后IQ会自动提交事物。在缺省情况下,打开的游标会因为事物提交而自动关闭,所以会报cusor not open错误。

      找到原因解决方法也就不难了,需要在open cursor的时候加上with hold(即改为open DARECESL with hold),这样即使提交事物也不会关闭游标了。让网友按照上面的方法修改,问题解决!
页: [1]
查看完整版本: IQ存储过程中使用游标时报Cursor not open的解决方法