Sql server SQL Server合并+连接其他表

Sql server SQL Server合并+连接其他表,sql-server,tsql,merge,common-table-expression,sql-merge,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

我在数据库项目中使用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“,并能够加入到用户和权限中,以获取用于插入的ID值。不知道该怎么办

编辑:

用户表ID,用户名 约翰·史密斯 马克·沃勒格

角色表ID,RoleName 1、管理员 2、用户 3、客人

用户角色表用户ID,角色ID

我希望MERGE语句的SQL调整用户角色表,以便我可以指定如下内容:

USING(VALUES
 ('John Smith', 'Administrator'),
 ('Mark Wahlburg', 'User')
它将加入以确定ID,插入不存在的组合,或者删除存在但不在合并中的组合

解决方案:

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)

Merge支持cte,因此您可以将其用作源,合并静态数据并在cte中执行任何连接。

只是好奇,为什么您在这里使用Merge而不是更简单的插入。。。选择我并不是说你不能用MERGE来做这件事,但对于这样一个琐碎的操作来说,这似乎有些过分。@AaronBertrand,这是一个简单的例子,通常我有多行,并使用MERGE的更新和删除功能。我试图找出问题所在。问题出在你的USING子句中。你只是有硬编码的值;如果需要从表中绘制这些值,则需要实际使用SELECT。还有一些非常聪明的人可以帮你解决问题,但是他们对解决您的实际问题更感兴趣-将其简化只会导致不必要的问题,如我所问的问题。我看不出有什么理由不通过将“values…”行删除到“select”来更改insert,该行包括您的静态字段,并连接到其他表以查找相关id。这些值是本来是硬编码的,但问题是我不想插入那些特定的值,而是基于硬编码值从其他表中插入ID。这是一个现在起作用的例子。问题是采取下一步,也就是后面描述的问题。这就是诀窍。我使用CTE和表值构造函数的经验有点弱,因此我不知道它们可以在哪里一起使用。