不存在的TSQL循环

不存在的TSQL循环,tsql,while-loop,exists,Tsql,While Loop,Exists,我有角色和权限表,其中有一个名为role\u permissions的联接表 对于每个角色,如果该角色尚未拥有该权限,我希望插入一个新权限。我的循环的问题是,只更新了一行(角色)。循环似乎没有在每个循环上正确地重新计算子查询(查找第一个没有权限的角色) DECLARE @role_id INT SET @role_id = (SELECT TOP 1 role_id FROM p_role_permissions WHERE NOT EXISTS (SELECT NULL FROM p_rol

我有角色和权限表,其中有一个名为role\u permissions的联接表

对于每个角色,如果该角色尚未拥有该权限,我希望插入一个新权限。我的循环的问题是,只更新了一行(角色)。循环似乎没有在每个循环上正确地重新计算子查询(查找第一个没有权限的角色)

DECLARE @role_id INT

SET @role_id = (SELECT TOP 1 role_id FROM p_role_permissions WHERE NOT EXISTS (SELECT NULL FROM p_role_permissions WHERE permission_id = 57))

WHILE @role_id IS NOT NULL
BEGIN

INSERT INTO p_role_permissions (role_id, permission_id) VALUES(@role_id, 57)
-- does not appear to evaluate correctly (works only on the first loop)
SET @role_id = (SELECT TOP 1 role_id FROM p_role_permissions WHERE NOT EXISTS (SELECT NULL FROM p_role_permissions WHERE permission_id = 57))

END

你不需要一个循环。您可以在一个insert语句中执行此操作

;WITH RolesToAdd
     AS (SELECT role_id
         FROM   p_role_permissions /*Would be better to use a roles table here */
         EXCEPT
         SELECT role_id
         FROM   p_role_permissions
         WHERE  permission_id = 57)
INSERT INTO p_role_permissions
            (role_id,
             permission_id)
SELECT role_id,
       57
FROM   RolesToAdd 

好的,在这里做一些假设,但我相信你可以这样做:

获取没有权限的角色57:

INSERT INTO p_role_permissions (role_id, permission_id)
   SELECT
       rp.Id,
       57
   FROM
       (SELECT
            r.Id
         FROM roles as r
         LEFT OUTER JOIN p_role_permissions as rp
         ON r.Id = rp.Role_Id AND rp.Permission_Id = 57

         WHERE r.Id IS NULL) as nr

您的
不存在
子查询与外部查询没有任何关联。
INSERT INTO p_role_permissions (role_id, permission_id) (SELECT role_id, 57 FROM p_role_permissions WHERE NOT EXISTS (SELECT NULL FROM p_role_permissions WHERE permission_id = 57))
MERGE INTO p_role_permissions 
USING (SELECT DISTINCT roleid, 57 FROM p_role_permissions) AS src  
ON (p_role_permissions)  
WHEN NOT MATCHED THEN   
    INSERT p_role_permissions (role_id, permission_id)
    VALUES (role_id, 57);