5

現在、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 に更新すると、重複する値が作成される可能性があります。したがって、新しい値がまだ存在しない場合にのみ更新する必要があります。それ以外の場合は、この値を削除するだけです

4

4 に答える 4

3

これを試してください(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
于 2013-01-25T12:08:29.727 に答える
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;
于 2013-01-25T12:36:45.700 に答える
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

そして、ここに Fiddleがあります。

于 2013-01-25T12:17:30.520 に答える