我目前正在尝试编写一个脚本,将用户的角色更改为另一个,而不会在SQL Server数据库中创建重复项。
例如:
User_ID Role_ID
---------------------
A X
A Z
B Y
C X
C Y
D Y
用户可能有多个角色。
我想更改它,以便角色Y中的所有用户现在都是角色X的成员,角色Y将不再存在:
User_ID Role_ID
---------------------
A X
A Z
B X
C X
D X
通过将所有Y角色更新为X,这可能会创建重复值;因此,我只需要更新新值是否已经存在,否则只需删除此值
答案 0 :(得分:2)
试试这个(SQL DEMO)
--Delete records with X if same user has Y
delete t1
from userRoles t1 join (
select * from userRoles t2 where t2.role_id = 'y') t3
on t1.user_id = t3.user_Id
where t1.role_id = 'x'
--Update all Y records to X
update userRoles set role_id = 'X'
where role_id = 'y'
select * from userRoles
--RESULTS
USER_ID ROLE_ID
A X
A Z
B X
C X
D X
答案 1 :(得分:2)
您可以在一个MERGE
语句中执行此操作(它提供了优化锁定):
MERGE tbl2
USING (
-- Create the desired data (together with duplicates)
SELECT User_ID,
CASE WHEN Role_ID = 'Y' THEN 'X' ELSE Role_ID END Role_ID
FROM tbl2
) new ON tbl2.User_ID = new.User_ID AND tbl2.Role_ID = new.Role_ID
WHEN NOT MATCHED THEN
-- Insert the updated data
INSERT(User_ID, Role_ID) VALUES(User_ID, Role_ID)
WHEN NOT MATCHED BY SOURCE THEN
-- Filter out the 'X'-s
DELETE;
这是 SQL Fiddle
答案 2 :(得分:1)
可以使用MERGE
:
DECLARE @T TABLE (User_ID CHAR(1), Role_ID CHAR(1));
INSERT @T (User_ID, Role_ID)
VALUES ('A', 'X'), ('A', 'Z'), ('B', 'Y'), ('C', 'X'), ('C', 'Y'), ('D', 'Y');
SELECT *
FROM @T;
WITH Y AS
( SELECT *,
[d] = COUNT(*) OVER(PARTITION BY User_ID)
FROM @T
WHERE Role_ID IN ('Y', 'X')
), X AS
( SELECT *
FROM @T
WHERE Role_ID = 'X'
)
MERGE INTO Y
USING X ON X.User_ID = Y.User_ID
WHEN MATCHED AND Y.Role_ID = 'Y' AND d > 1 THEN DELETE
WHEN NOT MATCHED BY SOURCE THEN UPDATE
SET Role_ID = 'X';
SELECT *
FROM @T;
答案 3 :(得分:0)
首先必须清理你的桌子:
DECLARE
@originalRole char(1) = 'Y',
@newRole char(1) = 'X'
DELETE [r1]
FROM [Roles] [r1]
WHERE [r1].[Role_ID] = @originalRole
AND EXISTS(SELECT *
FROM [Roles] [r2]
WHERE [r2].[User_ID] = [r1].[User_ID] AND [r2].[Role_ID] = @newRole)
然后,更新剩下的行,如果有的话:
UPDATE [Roles]
SET [Role_ID] = @newRole
WHERE [Role_ID] = @originalRole
这是the Fiddle。