由于这个 XML,您无法正确解析它。您需要更改它 - 您应该将每个项目及其itemid
子项目放入一个单独的节点中 - 否则您的主节点下<item>
只有一个长长的节点列表<itemid>
,但您无法判断哪些节点属于一起.. ..<subitems>
<items>
<itemid>
<subitems>
您需要将 XML 更改为如下所示:
<job>
<jobid>4711</jobid>
<items>
<item>
<itemid>1</itemid>
<subitems>
<subitemid>1</subitemid>
<subitemid>2</subitemid>
</subitems>
</item>
<item>
<itemid>2</itemid>
<subitems>
......
</subitems>
</item>
... (possibly more <item> nodes) ....
</items>
</job>
那么您可以使用与您上一个问题基本相同的代码 - 扩展到涵盖三个级别:
CREATE PROCEDURE dbo.SaveJobs (@input XML)
AS BEGIN
;WITH JobsData AS
(
SELECT
JobID = JobNode.value('(jobid)[1]', 'int'),
ItemID = ItemNode.value('(itemid)[1]', 'int'),
SubItemID = SubItemNode.value('.', 'int')
FROM
@input.nodes('/jobs/job') AS TblJobs(JobNode)
CROSS APPLY
JobNode.nodes('items/item') AS TblItems(ItemNode)
CROSS APPLY
ItemNode.nodes('subitems/subitem') AS TblSubItems(SubItemNode)
)
INSERT INTO dbo.tblDummy(JobID, ItemID, SubItemID)
SELECT JobID, ItemID, SubItemID
FROM JobsData
END
基本上,您需要三个 XML 节点“列表”:
- 首先你需要所有
<jobs>/<job>
节点的列表来获取jobid
值
- 对于每个作业节点,您还需要获取它们的嵌套列表
<items>/<item>
以获取itemid
值
- 从每个节点,您还可以获得
<subitems>/<subitem>
这很可能会起作用 - 但很可能会相当慢(对.nodes()
函数的三个嵌套调用!)。
更新:
好的,所以第一个调用@input.nodes('/jobs/job') AS TblJobs(JobNode)
基本上创建了一个TblJobs
具有单列的“伪”表,JobNode
并且您的 XML 中的每个<job>
元素都被存储到该伪表中的一行中 - 所以第一行将在其JobNode
列中包含此 XML:
<job>
<jobid>4711</jobid>
<items>
<item>
<itemid>1</itemid>
<subitems>
<subitemid>1</subitemid>
<subitemid>2</subitemid>
</subitems>
</item>
<item>
<itemid>2</itemid>
<subitems>
......
</subitems>
</item>
... (possibly more <item> nodes) ....
</items>
</job>
并且每一行将包含<job>
内部每个后续元素的附加 XML 片段<jobs>
从这些 XML 片段中的每一个,第二个调用
CROSS APPLY JobNode.nodes('items/item') AS TblItems(ItemNode)
再次选择一个XML片段列表到一个伪TblItems
表(ItemNode
<item>
<job>
所以这个伪表的第一行包含:
<item>
<itemid>1</itemid>
<subitems>
<subitemid>1</subitemid>
<subitemid>2</subitemid>
</subitems>
</item>
第二行将包含
<item>
<itemid>2</itemid>
<subitems>
......
</subitems>
</item>
等等。
然后第三次调用——您已经猜到了——再次将 XML 元素列表作为行提取到伪表<subitem>
中——XML 片段中的每个节点都有一个条目。
更新#2:
我是“JobID = JobNode.value('(jobid)[1]', 'int')” 代码行的新手
好的 - 给定<Job>
您拥有的 XML 片段:
<job>
<jobid>4711</jobid>
<items>
......
</items>
</job>
该.value()
调用只是在那个 XML 上执行这个 XPath 表达式 ( jobid
) 并基本上取回<jobid>4711</jobid>
片段。然后它提取该节点的值(内部文本),.value()
调用的第二个参数定义将其解释为什么 SQL 数据类型 - 所以它基本上4711
从<jobid>
节点中获取 并将其解释为int