SQL 检查游标中是否存在行

SQL check if row exists in cursor

我正在做一个 select returns 一个 table 的 roleId。 我一直在寻找一种迭代值的方法,并为每个行值 运行 删除或(存储过程)。在尝试了许多不同的建议之后,这就是我所拥有的:

BEGIN TRAN
DECLARE @RoleId bigint

DECLARE cur CURSOR FOR SELECT DISTINCT cr.RoleId
FROM ClientRole AS cr
INNER JOIN userRole AS ur ON cr.RoleId = ur.RoleId
AND cr.ClientId = 564564564

OPEN cur

FETCH NEXT FROM cur INTO @RoleId

WHILE @@FETCH_STATUS = 0 BEGIN

        --NEED TO CHECK IF RolePermissions ACTUALLY HAS THE PERMISSION
        DELETE  
        FROM RolePermissions
        WHERE RoleId = @RoleId
        AND PermissionId = 12341234

    FETCH NEXT FROM cur INTO @RoleId
END

CLOSE cur    
DEALLOCATE cur

ROLLBACK

当前,当尝试 "delete" 时会出现错误,因为对于某些 RoleId,它试图删除的行不存在。我尝试了 If, WHILE, CASE 但不确定我应该在这里做什么,因为我不知道如果没有行,如何传递 RoleId。似乎不推荐游标,但无法通过将其放在临时 table.

中来完成相同的工作

感谢任何建议

编辑::

最初我试图从游标 运行 存储过程: 最初我试图 运行 每个 roleId 上的存储过程:

    begin tran
    exec dbo.usp_DeleteRolePermission @RoleId = @RoleId,
    @PermissionId =  12341234,
    @PublishToCache = 1
commit

从您的示例中不清楚为什么您实际上需要遍历游标并单独删除每条记录。你不能只发出一个 DELETE 吗?有点像

DELETE  
FROM RolePermissions
WHERE RoleId IN (SELECT cr.RoleId
                 FROM ClientRole AS cr
                 INNER JOIN userRole AS ur ON cr.RoleId = ur.RoleId
                 AND cr.ClientId = 564564564)
AND PermissionId = 12341234

您可能不需要光标。像这样的单个语句可以很容易地转换为过程:

declare @ClientId     int = 564564564;
declare @PermissionId int = 12341234;

delete rp
from RolePermissions rp
where PermissionId = @PermissionId
  and exists (
    select 1
    from ClientRole as cr
      inner join userRole as ur 
        on cr.RoleId = ur.RoleId
      and cr.ClientId = @ClientId
      where ur.RoleId = rp.RoleId
      );