【发布时间】:2020-09-09 10:06:03
【问题描述】:
我正在尝试:
- 遍历包含 XML [MY_TABLE 中的MY_XML_COLUMN] 的列
- 对于每个 XML:
- 获取某种类型的所有节点 ([@type="myType"])
- 对于每个“myType”节点:
- 检查它是否包含一个子节点“myEvent”(注意 - 如果存在 - 只有一个)
- 如果是这样:
- 将所有值从该节点复制(更新)到另一个具有相同子节点的“myNewEvent”节点 像“myEvent”这样的节点
- 无论如何从所有“myType”节点中删除“myEvent”节点
例子:
<hubs>
<hubOne type="myType"> (myNewEvent should b updated as its of "myType" hub and has "myEvent" node)
<myEvent>
<subNodeOne> x <subNodeOne>
<subNodeTwo> y <subNodeTwo>
<subNodeThree> z <subNodeThree>
</myEvent>
<myNewEvent>
<subNodeOne> a <subNodeOne>
<subNodeTwo> b <subNodeTwo>
<subNodeThree> c <subNodeThree>
</myNewEvent>
</hubOne>
<hubTwo type="NOTmyType"> (myNewEvent should NOT b updated as its NOT of "myType" hub)
<myEvent>
<subNodeOne> x <subNodeOne>
<subNodeTwo> y <subNodeTwo>
<subNodeThree> z <subNodeThree>
</myEvent>
<myNewEvent>
<subNodeOne> a <subNodeOne>
<subNodeTwo> b <subNodeTwo>
<subNodeThree> c <subNodeThree>
</myNewEvent>
</hubTwo>
<hubThree type="myType"> (myNewEvent should NOT b updated as its of "myType" but no subnode "myEvent")
<myNewEvent>
<subNodeOne> x <subNodeOne>
<subNodeTwo> y <subNodeTwo>
<subNodeThree> z <subNodeThree>
</myNewEvent>
</hubThree>
<hubFour type="myType"> (myNewEvent should b updated as its of "myType" hub and has "myEvent" node)
<myEvent>
<subNodeOne> q <subNodeOne>
<subNodeTwo> w <subNodeTwo>
<subNodeThree> e <subNodeThree>
</myEvent>
<myNewEvent>
<subNodeOne> a <subNodeOne>
<subNodeTwo> b <subNodeTwo>
<subNodeThree> c <subNodeThree>
</myNewEvent>
</hubFour>
</hubs>
想要的结果:
<hubs>
<hubOne type="myType"> (myNewEvent updated and myEvent deleted)
<myNewEvent>
<subNodeOne> x <subNodeOne>
<subNodeTwo> y <subNodeTwo>
<subNodeThree> z <subNodeThree>
</myNewEvent>
</hubOne>
<hubTwo type="NOTmyType"> (myNewEvent NOT updated and myEvent deleted)
<myNewEvent>
<subNodeOne> a <subNodeOne>
<subNodeTwo> b <subNodeTwo>
<subNodeThree> c <subNodeThree>
</myNewEvent>
</hubTwo>
<hubThree type="myType"> (myNewEvent NOT updated)
<myNewEvent>
<subNodeOne> x <subNodeOne>
<subNodeTwo> y <subNodeTwo>
<subNodeThree> z <subNodeThree>
</myNewEvent>
</hubThree>
<hubFour type="myType"> (myNewEvent updated and myEvent deleted)
<myNewEvent>
<subNodeOne> q <subNodeOne>
<subNodeTwo> w <subNodeTwo>
<subNodeThree> e <subNodeThree>
</myNewEvent>
</hubFour>
</hubs>
到目前为止我尝试过的都没有成功:
-
google + 旧的堆栈溢出解决方案
-
代码示例:
DECLARE @ID INT;
DECLARE @HUB_ID UNIQUEIDENTIFIER;
DECLARE @NAME VARCHAR(MAX);
DECLARE PROFILES_CURSOR CURSOR
FOR
SELECT P.[ID] FROM [MY_TABLE] P WHERE P.DELETED=0;
OPEN SOME_CURSOR
FETCH NEXT FROM SOME_CURSOR INTO @ID
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE HUBS_CURSOR CURSOR
FOR
SELECT H.hub.value('(@name)', 'varchar(1024)') AS [NAME]
FROM MY_TABLE
CROSS APPLY MY_XML_COLUMN.nodes('/integration/hub[@type="myType"]') as H(hub)
WHERE PROFILE_ID=@ID
OPEN HUBS_CURSOR
FETCH NEXT FROM HUBS_CURSOR INTO @NAME
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE [MY_TABLE]
SET [INTEGRATION_XML].modify(some xquery code to deal all nodes at once?)
WHERE ANOTHER_COLUMN = @ID
AND (
SELECT [SOME_IDENTIFYING_COLUMN]
FROM MY_TABLE PS
WHERE PS.MY_XML_COLUMN.exist('/integration/hub[@name=sql:variable("@NAME" and @type="myType")]/events') = 1
AND PS.INTEGRATION_XML.exist('/integration/hub[@name=sql:variable("@NAME" and @type="myType")]/events/myEvent') = 1
AND PROFILE_ID=@ID
) IS NOT NULL
FETCH NEXT FROM HUBS_CURSOR INTO @NAME
END
CLOSE HUBS_CURSOR
DEALLOCATE HUBS_CURSOR
FETCH NEXT FROM PROFILES_CURSOR INTO @ID
END
CLOSE PROFILES_CURSOR
DEALLOCATE PROFILES_CURSOR
【问题讨论】:
-
(1) XML 似乎是手工制作的。它应该是格式良好的。 (2)
<hubOne>、<hubTwo>等XML元素命名的原因是什么?这是一个非常糟糕的命名约定。 -
@YitzhakKhabinsky 没错。它是手工制作和命名的,以避免泄露业务细节
标签: sql-server xml sql-server-2016