У меня есть список данных, которые я передаю в хранимую процедуру как XML. Данные представляют собой список Widget
, а виджет содержит список WidgetItem
(данные родительского ребенка). Я хотел бы сделать MERGE
на основе подмножества Widget
на основе ParentID
. Некоторые данные для ParentID
были обновлены, некоторые из них были удалены (так что отсутствует в xml), а некоторые данные являются новыми.SQL Объединить список родительских данных ребенка
Обновленные данные никогда не будут нуждаться в данных ребенка, обновленных, поскольку запись Widget
может быть отрегулирована, а не элементы (дочерние данные) внутри нее. Вставка всегда будет содержать одну или несколько дочерних записей (WidgetItems).
Я не могу понять, как это сделать в MERGE
, поскольку это похоже на лучший подход по сравнению с обработкой слияния в слое данных.
Вот что я до сих пор ... Я помещал комментарии, где я застрял:
CREATE PROCEDURE dbo.pWidgetsMerge
@Widgets XML
AS
/*
Assumed XML input @Widgets xml:
<Widgets>
<Widget>
<WidgetID>
<ParentID>
<StartDate>
<EndDate>
<Details>
<WidgetDetailItem>
<WidgetDetailItemID>
<WidgetID>
<SomeID>
<SomeData>
*/
MERGE
[dbo].[Widget] as w
USING
(
SELECT
'WidgetID' = P.value('WidgetID[1]', 'INT'),
'ParentID' = P.value('ParentID[1]', 'INT'),
'StartDate' = P.value('EffectiveStartDate[1]', 'DATETIME'),
'EndDate' = P.value('EffectiveEndDate[1]', 'DATETIME')
FROM
@Widgets.nodes('/Widgets/Widget') PROPERTYFEED(P)
)
AS xmlIn
(
[WidgetID],
[StartDate],
[EndDate]
)
ON
w.[WidgetID] = xmlIn.[WidgetID]
WHEN
NOT MATCHED
THEN
INSERT
(
[ParentID],
[StartDate],
[EndDate]
)
VALUES
(
xmlIn.[ParentID],
xmlIn.[StartDate],
xmlIn.[EndDate]
)
/*STUCK HERE: After the insert, need to put in the child
records into a new table [WidgetItems]. Maybe it's another
operation outside of the merge?*/
WHEN
MATCHED AND (
(w.[StartDate] <> xmlIn.[StartDate]) OR
(w.[EndDate] <> xmlIn.[EndDate]))
THEN
UPDATE SET
w.[StartDate] = xmlIn.[StartDate],
w.[EndDate] = xmlIn.[EndDate]
WHEN
NOT MATCHED BY SOURCE AND w.[ParentID] = xmlIn.[ParentID]
THEN
UPDATE SET
w.[DeletedDate] = GETDATE()
Кроме того, если я приближаюсь к этому неправильному альтернативное решение будет иметь в виду, или, может быть, мне нужно обрабатывать это на уровне данных.
Я делал кучу правок, вероятно, так как вы читаете вопрос, но следующее, я думаю, обращается к части, чтобы воздействовать на все записи (влияет только на удаление): 'КОГДА НЕ СООТВЕТСТВУЕТ ИСТОЧНИКОМ И w. [ParentID] = xmlIn. [ParentID] THEN UPDATE SET w. [DeletedDate] = GETDATE() ' – Kelsey
Не означает ли это, что он не сопоставляется в таблице базы данных, а идентификатор родительской таблицы базы данных должен соответствовать идентификатору родительского элемента XML? Если я правильно их читаю, источник MATCHED BY не будет срабатывать. Я поместил флаг в XML для записей, которые нужно удалить из базы данных. – Steven
Да, если 'NOT MATCHED' не имеет соответствия в ParentID, операция удаления будет проигнорирована. По крайней мере, это то, на что я надеюсь, поскольку я хочу сравнить только удаление с подмножеством данных на основе «ParentID». – Kelsey