日期:2014-05-18  浏览次数:20414 次

可以在一个触发器中有两个游标吗?
当我触发一个触发器,在这个触发器中有两个游标:

----------------------------------------------------------
--每当系统日期表nowTime更新一次就对表中所有需要更新的数据更新一次
create trigger 刷新触发器 on nowTime
for insert
as 
begin
--------------------------------------------游标_reader
--读者表,如果卡的失效时间cardBlankOutTime时间超过系统时间的话将违约状态置为1
--创建一个游标,进行逐行对是否过期给出明确判断,然后修改errState的值
declare 游标_reader cursor for
select rNo,cardBlankOutTime,errState
from reader

open 游标_reader
begin
declare @cRno char(8),@cCardBlankOutTime datetime,@cErrState bit,@sysTime datetime
select @sysTime=now from nowTime
fetch 游标_reader into @cRno,@cCardBlankOutTime,@cErrState
while (@@fetch_status=0)
begin
if((@cCardBlankOutTime-@sysTime)<0 and @cErrState<>1)
update reader set errState=1
where current of 游标_reader
else if((@cCardBlankOutTime-@sysTime)>=0 and @cErrState<>0)
update reader set errState=0
where current of 游标_reader
fetch 游标_reader into @cRno,@cCardBlankOutTime,@cErrState
end
end
commit tran
close 游标_reader
deallocate 游标_reader

-------------------------------------------------------游标_RL
--读者借阅表信息更新,如果还书时间过期了,则把读者的违约状态errState改为1,禁止借书和续借,
--并自动把违约信息输入读者违约表
print'判断借阅表借阅图书是否超期' --记号
declare 游标_RL cursor for
select rNO,bNo,giveBackTime
from RL

open 游标_RL
begin
declare @RL_Rno char(8),@cBno int,@cGiveBackTime datetime,@RL_SysTime datetime
select @sysTime=now from nowTime
fetch 游标_RL into @RL_Rno,@cBno,@cGiveBackTime
while(@@fetch_status=0)
begin
if((@RL_SysTime-@cGiveBackTime)>0 and (select errState from reader where rNo=@RL_Rno)<>1)
begin
--把违约状态改为1
update reader set errState=1
where current of 游标_RL
--把违约信息插入违约表
insert into RR(rNo,bNo,ruleNo,breakRuleTime)
values(@RL_Rno,1,@cBno,@RL_SysTime)
--where current of 游标_RL
end
fetch 游标_RL into @cRno,@cBno,@cGiveBackTime
end
end
commit tran
close 游标_RL
deallocate 游标_RL
-----------------------------------------------------------
end
go 


但是运行时除了问题:
(所影响的行数为 1 行)

判断借阅表借阅图书是否超期
服务器: 消息 3902,级别 16,状态 1,过程 刷新触发器,行 60
COMMIT TRANSACTION 请求没有对应的 BEGIN TRANSACTION。
语句已终止。

是不是一个触发器中不能有两个游标?还是我的哪里出了问题?


还有一个问题:对于一个事件,假如往一个表中插入数据之后,能不能有建两个或更多个触发器?如果可以执行顺序怎么样?



------解决方案--------------------
这样会很慢的,想别的办法吧。
------解决方案--------------------
没有标记显式事务的开始——BEGIN TRANSACTION,怎么能COMMIT TRANSACTION。

隐式事务不需要COMMIT,系统自己会COMMIT或ROLLBACK。