不存在的 TSQL 循环
Posted
技术标签:
【中文标题】不存在的 TSQL 循环【英文标题】:TSQL loop WHERE NOT EXISTS 【发布时间】:2012-09-07 12:32:59 【问题描述】:我有一个角色和权限表,其中包含一个名为 role_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
【问题讨论】:
【参考方案1】:您不需要循环。您可以在一个插入语句中执行此操作。
;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
【讨论】:
【参考方案2】:好吧,在这里做一些假设,但我相信你可以这样做:
获取没有权限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
【讨论】:
【参考方案3】: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))
【讨论】:
您的NOT EXISTS
子查询与外部查询没有任何关联。【参考方案4】:
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);
【讨论】:
以上是关于不存在的 TSQL 循环的主要内容,如果未能解决你的问题,请参考以下文章