Оператор слияния для удаления / обновления / вставки данных в Sql Server - PullRequest
0 голосов
/ 05 мая 2019

У меня есть файл Excel с тысячами строк, которые мне нужно использовать для удаления / обновления / вставки некоторых таблиц.Excel предоставляет следующие данные: provider_id , страна_имя , локаль , property1 , property2 .Таблицы, которые необходимо обновить: provider_country со столбцами: provider_country_id , provider_id , country_id , property1, property2 и provider_country_language со столбцами: provider_country_language_id , provider_country_id , language_id .Я также могу использовать таблицу страна со столбцами (для объединений): страна_ид , страна_имя .И таблица language со столбцами: language_id , locale , country_id .Поля, которые должны быть обновлены, это country_id, language_id, property1, property2 (from provider_country и provider_country_language)

Я создал временную таблицу со всеми данными из Excel:

CREATE TABLE #TempProviderCountryLanguage(
[provider_id] int NULL,
[country_name] nvarchar(50) NULL,
[locale] nvarchar(10) NULL,
[property1] int NULL,
[property2] decimal(5,2) NULL
) 

INSERT INTO #TempProviderCountryLanguage VALUES 
(1,N'Provider1',N'Brazil',N'en-br',4,NULL)
INSERT INTO #TempProviderCountryLanguage VALUES 
(1,N'Provider1',N'Brazil',N'pt-br',4,NULL)
INSERT INTO #TempProviderCountryLanguage VALUES 
(1,N'Provider1',N'Denmark',N'da-dk',4,12.21)
INSERT INTO #TempProviderCountryLanguage VALUES 
(2,N'Provider2',N'Denmark',N'da-dk',5,14.21)
......

MERGE [provider_country] AS TARGET
USING (
SELECT tb.provider_id
    ,c.country_id
    ,l.language_id
    ,tb.property1
    ,tb.property2
FROM #TempProviderCountryLanguage tb
INNER JOIN country c ON c.country_name = tb.country_name
INNER JOIN language l ON l.locale = l.locale
) AS SOURCE
ON (
        TARGET.provider_id = SOURCE.provider_id AND
        TARGET.country_id = SOURCE.country_id
        )
WHEN MATCHED
THEN
    UPDATE
    SET TARGET.country_id = SOURCE.country_id,
        TARGET.property1 = SOURCE.property1,
        TARGET.property2 = SOURCE.property2
WHEN NOT MATCHED BY TARGET
THEN
    INSERT (
        provider_id
        ,country_id
        ,property1
        ,property2
        )
    VALUES (
        SOURCE.provider_id
        ,SOURCE.country_id
        ,SOURCE.property1
        ,SOURCE.property2
        )
WHEN NOT MATCHED BY SOURCE THEN
DELETE;

Для provider_country_language я планирую сделать еще одно слияние.

Я пытаюсь обновить таблицы с помощью слияния, но у меня есть проблема, потому что я не могу сделать уникальный выбор здесь (каким-то образом мне также понадобится language_id):

ON (
TARGET.provider_id = SOURCE.provider_id AND
TARGET.country_id = SOURCE.country_id
)

И ошибка:

Оператор MERGE пытался ОБНОВИТЬ или УДАЛИТЬ одну и ту же строку более одного раза.Это происходит, когда целевая строка соответствует более чем одной исходной строке.Оператор MERGE не может ОБНОВИТЬ / УДАЛИТЬ одну и ту же строку целевой таблицы несколько раз.Уточните предложение ON, чтобы убедиться, что целевая строка соответствует не более чем одной исходной строке, или используйте предложение GROUP BY, чтобы сгруппировать исходные строки.

Как я могу заставить эту работу работать и убедиться, что все таблицыправильно обновлено?(только INSERT INTO будет выполняться тысячу раз ...)

...