Question

I am using the MERGE statement within a database project to populate reference data from a static value set, such as the following below:

    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);

The problem comes in when I want to populate the secondary table based of content in other tables. For example, my UserPermission table contains user ID and role ID and I'd like my static value set to be something like ('me@somewhere.com', 'Admin') and be able to join to User and Permission to get the ID values for INSERTing. Not sure where do to that...

Edit:

User Table(ID, Username) 1, John Smith 2, Mark Wahlerg

Role Table(ID, RoleName) 1, Administrator 2, User 3, Guest

User-Role Table (User ID, Role ID)

I want the SQL for the MERGE statement to adjust the User-Role table such that I can do specify something like:

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

and it will join to determine the IDs, insert the combinations that dont exists (and maybe delete the ones that do, but aren't in the MERGE.

Solution:

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)
Was it helpful?

Solution

Merge supports CTEs so perhaps you can use this as your source, combining your static data and performing any joins within the cte.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top