Обновление нескольких записей в таблице с помощью одного SQL Server MERGE (из XML)

Можно ли использовать SQL Server 2012 MERGE для обновления нескольких записей в таблице из потока XML?

Моя таблица выглядит следующим образом:

введите здесь описание изображения

Несколько раз в день я получаю следующий XML-конверт:

<WeatherForecastUpdate>
    <Location Temperature="67" Id="56">
        <Humidity>78%</Humidity>
        <Condition>Rain</Condition>
        <Wind>5mph</Wind>
    </Location>
    <Location Temperature="72" Id="783">
        <Humidity>51%</Humidity>
        <Condition>Clear</Condition>
        <Wind>5mph</Wind>   
    </Location>
</WeatherForecastUpdate>

Мне нужно обновить данные о погоде на основе LocationID из XML. Я знаю, как MERGE каждое отдельное сообщение (местоположение), но мне интересно, есть ли способ обновить все записи таблицы в пределах одного MERGE.


person Interface Unknown    schedule 03.09.2016    source источник
comment
Покажите, как вы это сделали, если это было одно сообщение (местоположение)...   -  person har07    schedule 03.09.2016
comment
Почему вы хотите использовать MERGE, когда хотите просто обновить записи. Используйте оператор UPDATE, чтобы сделать это   -  person Pரதீப்    schedule 03.09.2016


Ответы (1)


Да, ты можешь! Сначала конвертируйте xml в таблицу, затем MERGE:

DECLARE @x xml = N'<WeatherForecastUpdate>
    <Location Temperature="67" Id="56">
        <Humidity>78%</Humidity>
        <Condition>Rain</Condition>
        <Wind>5mph</Wind>
    </Location>
    <Location Temperature="72" Id="783">
        <Humidity>51%</Humidity>
        <Condition>Clear</Condition>
        <Wind>5mph</Wind>   
    </Location>
</WeatherForecastUpdate>'

;WITH cte AS (
    SELECT  t.v.value('@Temperature','int') Temperature,
            t.v.value('@Id','int') Id,
            t.v.value('(./Humidity)[1]','nvarchar(5)') Humidity,
            t.v.value('(./Condition)[1]','nvarchar(10)') Condition,
            t.v.value('(./Wind)[1]','nvarchar(10)') Wind
    FROM @x.nodes('/WeatherForecastUpdate/Location') as t(v)
)

MERGE YourTable as t
USING cte as s
ON t.LocationID = s.ID
WHEN MATCHED THEN
    UPDATE SET  Temp = s.Temperature,
                Humidity = s.Humidity,
                Wind = s.Wind

Другой способ использовать простое ОБНОВЛЕНИЕ:

UPDATE t
SET Temp = s.Temperature,
    Humidity = s.Humidity,
    Wind = s.Wind
FROM YourTable t
INNER JOIN cte s
    ON t.LocationID = s.ID
person gofr1    schedule 03.09.2016
comment
UPDATE это то, что мы должны использовать для этого. - person Pரதீப்; 03.09.2016
comment
Удивительно! Большое спасибо. Много раз я использовал предложение MERGE, но UPDATE чище и логичнее. - person Interface Unknown; 03.09.2016
comment
Собственно - в данном конкретном случае без разницы что использовать: слияние с апдейтом, или просто апдейт. Оба решения обеспечивают то, что вам нужно. - person gofr1; 03.09.2016