日期:2014-05-17  浏览次数:20698 次

帮忙分析下这个游标
小弟对数据库知识水平甚缺,请教各位高手,这个游标会不会在多用户使用的时候,造成死锁,如果发生死锁,是怎么处理游标中的数据呢?
SQL code


    declare curn cursor for
    select ActionId,ItemId,GroupID
                ,Medicare,MedicareRate,BeginTime
                ,[Name],[Type],Category
                ,Code,Usage,TotalDosage
                ,TotalDosageUnit,OneDosageUnit,Frequency
                ,PackQty,OneDosage,BaseQty
                ,Drugstore,AdviceItem,ChildrenRate
                ,CurDoctorId,CurDoctorName,Remark,AdviceId
             from  emrPrescribe 
            where PatientNo=@PatientNo 
                    and ExecuteTime=@ExecuteTime
    open curn
    fetch next from curn into     @Actionid,@ItemId,@GroupID
                                ,@Medicare,@MedicareRate,@BeginTime
                                ,@Name,@Type,@Category
                                ,@Code,@Usage,@TotalDosage
                                ,@TotalDosageUnit,@OneDosageUnit,@Frequency
                                ,@PackQty,@OneDosage,@BaseQty
                                ,@Drugstore,@AdviceItem,@ChildrenRate
                                ,@CurDoctorId,@CurDoctorName,@Remark,@AdviceId
    WHILE (@@fetch_status = 0)
        begin            
                    exec submitToLis --@Actionid   
                                            @lisid
                                            ,@Code
                                            ,@AdviceItem
                                            ,@BaseQty
                                            ,@AdviceCount
                                            ,@zd
                        
                    exec  submitDrugsToHis @PatientNo
                                    ,@Actionid
                                    ,@tmpGroupid
                                    ,@DeptName
                                    ,@Name
                                    ,@Code
                                    ,@Quantity
                                    ,@Unit
                                    ,@DrugstoreType
                                    ,@DCAType
                end

    fetch next from curn into     @Actionid,@ItemId,@GroupID
                                ,@Medicare,@MedicareRate,@BeginTime
                                ,@Name,@Type,@Category
                                ,@Code,@Usage,@TotalDosage
                                ,@TotalDosageUnit,@OneDosageUnit,@Frequency
                                ,@PackQty,@OneDosage,@BaseQty
                                ,@Drugstore,@AdviceItem,@ChildrenRate
                                ,@CurDoctorId,@CurDoctorName,@Remark,@AdviceId
    end 
    close curn
    deallocate curn



------解决方案--------------------
from emrPrescribe with (nolock)
where PatientNo=@PatientNo

查询时可用脏读或用快照隔离处理,看看调用处理的逻辑

------解决方案--------------------
执行先后顺序不一致也可能出现死锁,
索引太多或者没有索引导致锁升级也容易发生死锁,
事务太长也会出现死锁,
最好的方法先检查出哪一个位置发生死锁,再进一步分析
------解决方案--------------------
如果不涉及对这个表的数据修改的话,应该没关系,读锁是可以共享的。如果涉及到数据的修改的话,这个要看你对数据一致性的要求了,如果要求不高,为了追求效率,可以再执行的时候不加锁,方法见1楼
------解决方案--------------------
LZ是2K8以上的话,可以分步调试看看。 如果不涉及到修改数据的话,读锁是共享的。 当然阻塞也是比较烦人,LZ可以监控一下看看实际效果。 

另外,除非一些特殊的情景,一般的操作,都可以用其他算法,来替代游标。毕竟游标的效率实在是堪忧。 LZ可以换个思路看看。 或许可更好解决。

参考