最近一位网友问了我一个问题,他在一个项目中编写了一个存储过程,这个存储过程用于把一个用户下的所有表和存储过程授权给另一个用户。代码如下:
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),这样即使提交事物也不会关闭游标了。让网友按照上面的方法修改,问题解决!
阅读(6506) | 评论(0) | 转发(1) |