【发布时间】:2015-03-11 17:05:00
【问题描述】:
我有一个要作为 XML 传递给存储过程的数据列表。数据是Widget 的列表,小部件包含WidgetItem 的列表(父子数据)。我想做一个基于ParentID 的Widget 子集的MERGE。 ParentID 的一些数据已更新,一些已被删除(因此从 xml 中丢失)并且一些数据是新的。
更新的数据永远不需要更新子数据,因为Widget记录只能调整,不能调整其中的项目(子数据)。插入总是会有一个或多个子记录(WidgetItems)。
我似乎无法弄清楚如何在 MERGE 中执行此操作,因为与处理数据层中的合并相比,这似乎是最好的方法。
这是我到目前为止所拥有的……我在卡住的地方放了一个 cmets:
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()
另外,如果我遇到了这个错误,我们将不胜感激,或者我确实需要在数据层处理这个问题。
【问题讨论】:
标签: sql sql-server merge parent-child master-detail