zoukankan      html  css  js  c++  java
  • 使用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 (01NOT 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 (01NOT 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
  • 相关阅读:
    JSON 操作
    生成下面的模块时,启用了优化或没有调试信息
    Emacs
    Integration rules
    Testing tools
    软件架构(读书笔记1)
    依赖于自己做计算
    POJO
    软件架构(读书笔记2)
    设计得不好
  • 原文地址:https://www.cnblogs.com/chenjunbiao/p/1760240.html
Copyright © 2011-2022 走看看