SQL Server MERGE +加入其他表

时间:2012-05-09 19:30:51

标签: sql-server tsql merge common-table-expression sql-merge

我在数据库项目中使用MERGE语句来填充静态值集中的引用数据,如下所示:

    MERGE INTO dbo.[User] AS TARGET
USING (VALUES
    ('me@somewhere.com', 'My Name'))
AS SOURCE(UserName, FullName)
ON SOURCE.UserName = TARGET.UserName
WHEN NOT MATCHED BY TARGET THEN
    INSERT (UserId, UserName, FullName)
    VALUES (NEWID(), UserName, FullName);

当我想根据其他表中的内容填充辅助表时,会出现问题。例如,我的UserPermission表包含用户ID和角色ID,我希望我的静态值设置为(' me@somewhere.com',' Admin')并且能够加入User和Permission以获取INSERTing的ID值。不知道该怎么做......

编辑:

用户表(ID,用户名) 1,约翰史密斯 2,Mark Wahlerg

角色表(ID,RoleName) 1,管理员 2,用户 3,嘉宾

用户角色表(用户ID,角色ID)

我希望MERGE语句的SQL调整User-Role表,以便我可以指定类似的内容:

USING(VALUES
 ('John Smith', 'Administrator'),
 ('Mark Wahlburg', 'User')

并且它将连接以确定ID,插入不存在的组合(并且可能删除那些但不在MERGE中的组合。

解决方案:

WITH CTE AS
(
   SELECT UserId, RoleId
   FROM (VALUES
      ('John Smith', 'Administrator'),
      ('Mark Wahlburg', 'User'))
      AS SOURCE(UserName, RoleName)
   INNER JOIN User ON SOURCE.UserName = User.UserName
   INNER JOIN Role ON SOURCE.RoleName = Role.RoleName
)
MERGE INTO UserRole AS TARGET
USING CTE
ON CTE.UserId = TARGET.UserID AND CTE.RoleId = TARGET.UserId
WHEN NOT MATCHED BY TARGET THEN
  INSERT(UserId, RoleId)
  VALUES(UserId, RoleId)

1 个答案:

答案 0 :(得分:9)

Merge支持CTE,所以你可以将它作为你的源,结合你的静态数据并在cte中执行任何连接。