Я использую оператор MERGE в проекте базы данных для заполнения справочных данных из статического набора значений, например следующего ниже:
MERGE INTO dbo.[User] AS TARGET
USING (VALUES
('[email protected]', '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 содержит идентификатор пользователя и идентификатор роли, и я хотел бы, чтобы мое статическое значение было примерно таким ('[email protected]', 'Admin') и имело возможность присоединиться к Пользователю и Разрешению, чтобы получить Значения ID для INSERTing. Не знаю, где это сделать...
Редактировать:
Таблица пользователей (ID, имя пользователя) 1, Джон Смит 2, Марк Валерг
Таблица ролей (ID, имя роли) 1, администратор 2, пользователь 3, гость
Таблица ролей пользователей (идентификатор пользователя, идентификатор роли)
Я хочу, чтобы SQL для оператора MERGE корректировал таблицу User-Role, чтобы я мог указать что-то вроде:
USING(VALUES
('John Smith', 'Administrator'),
('Mark Wahlburg', 'User')
и он присоединится, чтобы определить идентификаторы, вставить комбинации, которых не существует (и, возможно, удалить те, которые существуют, но не находятся в 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)
INSERT ... SELECT
? Я не говорю, что вы не можете сделать это с помощьюMERGE
, но это кажется излишним для такой тривиальной операции. - person Aaron Bertrand   schedule 09.05.2012USING
. У вас просто есть жестко запрограммированные значения; вам нужно, чтобы он фактически использовалSELECT
, если вам нужно извлечь эти значения из таблицы. Также есть несколько довольно умных людей, которые могут помочь решить ваши проблемы, но они гораздо больше заинтересованы в решении вашей реальной проблемы - упрощение ее просто приводит к ненужным вопросам, подобным тому, который я задал. - person Aaron Bertrand   schedule 09.05.2012