使用WHILE代替游标的遍历操作

         游标操作会锁住被遍历的表,容易引起死锁,应当尽量避免使用。

原游标代码:
     DECLARE   @tbTargetPermissions      table (TargetPermissionId  uniqueidentifier   NOT   NULL   PRIMARY   KEY )
    
INSERT   INTO   @tbTargetPermissions  
        
SELECT   [ TargetPermissionId ]  
        
FROM   [ ps_RolePermissions ]  
        
WHERE   [ TargetId ]   =   @TargetId   AND   [ RoleId ]   =   @RoleId
    
    
DECLARE   @TargetPermissionId   uniqueidentifier ;

    
-- 定义游标
     DECLARE  TargetPermissions_ByRoleId_Cursor  CURSOR   FOR  
        
SELECT   [ TargetPermissionId ]   FROM   @tbTargetPermissions  

    
-- 打开游标
     OPEN  TargetPermissions_ByRoleId_Cursor

    
-- 读取游标第一条记录
     FETCH   NEXT   FROM     TargetPermissions_ByRoleId_Cursor  INTO   @TargetPermissionId

    
-- 检查@@FETCH_STATUS的值,以便进行循环读取
     WHILE   @@FETCH_STATUS   =   0
    
BEGIN
        
EXEC  ps_TargetPermissionEntity_Select  @TargetPermissionId ;

        
FETCH   NEXT   FROM     TargetPermissions_ByRoleId_Cursor  INTO   @TargetPermissionId ;
    
END

    
-- 关闭游标
     CLOSE  TargetPermissions_ByRoleId_Cursor
    
DEALLOCATE  TargetPermissions_ByRoleId_Cursor

改用While后仍然可以遍历执行存储过程 ps_TargetPermissionEntity_Select
     -- 把合符条件的目标权限Id加载到一个临时表变量中
     DECLARE   @tbTargetPermissions      table (IndexId  int   IDENTITY  ( 0 1 NOT   NULL   PRIMARY   KEY , TargetPermissionId  uniqueidentifier   NOT   NULL )
    
INSERT   INTO   @tbTargetPermissions  
        
SELECT   [ TargetPermissionId ]  
        
FROM   [ ps_RolePermissions ]  
        
WHERE   [ TargetId ]   =   @TargetId   AND   [ RoleId ]   =   @RoleId

    
DECLARE   @MaxIndexId   int ;
    
SELECT    @MaxIndexId   =   MAX ( [ IndexId ] FROM   @tbTargetPermissions -- 计算最大记录序号,用于遍历列表

    
WHILE   @MaxIndexId   >   - 1
    
BEGIN
        
DECLARE   @TargetPermissionId   uniqueidentifier ;
        
SELECT   @TargetPermissionId   =   [ TargetPermissionId ]   FROM   @tbTargetPermissions   WHERE   [ IndexId ]   =   @MaxIndexId ;

        
EXEC  ps_TargetPermissionEntity_Select  @TargetPermissionId ;

        
-- 删除最大记录项,重新判断记录项是否大于-1,以此判断是否遍历完列表
         DELETE   @tbTargetPermissions   WHERE   [ IndexId ]   =   @MaxIndexId ;
        
SELECT    @MaxIndexId   =   MAX ( [ IndexId ] FROM   @tbTargetPermissions  
        
-- SELECT @MaxIndexId--测试(倒序)
     END

执行效果相同,就是这里的while与上一方法的排序是相反的,如果对排序顺序有要求的,可以改变一下算法。 
按顺序排列的代码如下:
     -- 把合符条件的目标权限Id加载到一个临时表变量中
     DECLARE   @tbTargetPermissions      table (IndexId  int   IDENTITY  ( 0 1 NOT   NULL   PRIMARY   KEY , TargetPermissionId  uniqueidentifier   NOT   NULL )
    
INSERT   INTO   @tbTargetPermissions  
        
SELECT   [ TargetPermissionId ]  
        
FROM   [ ps_RolePermissions ]  
        
WHERE   [ TargetId ]   =   @TargetId   AND   [ RoleId ]   =   @RoleId

    
DECLARE   @MinIndexId   int ;
    
DECLARE   @MaxIndexId   int ;
    
SELECT    @MinIndexId   =   MIN ( [ IndexId ] FROM   @tbTargetPermissions -- 计算最小记录序号,用于遍历列表
     SELECT    @MaxIndexId   =   MAX ( [ IndexId ] FROM   @tbTargetPermissions -- 计算最大记录序号,用于遍历列表

    
WHILE   @MinIndexId   <=   @MaxIndexId
    
BEGIN
        
-- SELECT @MinIndexId,@MaxIndexId--测试(顺序)
         DECLARE   @TargetPermissionId   uniqueidentifier ;
        
SELECT   @TargetPermissionId   =   [ TargetPermissionId ]   FROM   @tbTargetPermissions   WHERE   [ IndexId ]   =   @MinIndexId ;

        
EXEC  ps_TargetPermissionEntity_Select  @TargetPermissionId ;

        
-- 删除最小记录项,重新判断最小记录项是否小于等于最大记录项,以此判断是否遍历完列表
         DELETE   @tbTargetPermissions   WHERE   [ IndexId ]   =   @MinIndexId ;
        
SELECT    @MinIndexId   =   MIN ( [ IndexId ] FROM   @tbTargetPermissions
    
END
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值