简体   繁体   English

无论数量多少,都从t-sql中的XML节点获取信息

[英]Taking information from an XML node in t-sql no matter the amount

XML 101 - day 1 XML 101-第1天

I have a column with xml in each row. 我每一行都有一个带有xml的列。 Each piece of xml follows the same template. 每段xml都遵循相同的模板。 I wish to extract information from a node no matter how many entries there are in it. 我希望从节点中提取信息,无论其中有多少项。

Example: 例:

<CodeLists>
  <CodeList CodeListID="FAC8BFB9-7C41-4647-A6DC-DF359379B8C3">
    <Code Number="1">L1CCTT</Code>
    <Code Number="2">L2CCTT</Code>
    <Code Number="3">L3CCTT</Code>
  </CodeList>
  <CodeList CodeListID="F0328C4F-916B-414D-AA81-D59244A4F0E1">
    <Code Number="1">16 to 18</Code>
    <Code Number="2">19 to 25</Code>
    <Code Number="3">26 to 49</Code>
    <Code Number="4">50 plus</Code>
  </CodeList>

I wish only to return L1CCTT, L2CCTT, L3CCTT. 我只希望返回L1CCTT,L2CCTT,L3CCTT。

However it coule be that the xml on the second row has more or less than 3 codes. 但是,可以肯定的是,第二行上的xml具有多于或少于3个代码。

Example: 例:

<CodeLists>
  <CodeList CodeListID="DA730346-2425-439D-ABD0-7FFF1F16ED3E">
    <Code CodeNumber="1">L1CCA</Code>
    <Code CodeNumber="2">L2CCA</Code>
  </CodeList>
  <CodeList CodeListID="7B9731F5-C1B2-460D-B78F-F7C64A959022">
    <Code CodeNumber="1">16 to 18</Code>
    <Code CodeNumber="2">19 to 25</Code>
    <Code CodeNumber="3">26 to 49</Code>
    <Code CodeNumber="4">50 plus</Code>
  </CodeList>

Example: 例:

<CodeLists>
  <CodeList CodeListID="74E6C8E2-BD88-4CB6-B578-DD25EC532CAA">
    <Code Number="1">CIT33C</Code>
    <Code Number="2">CIT32C</Code>
    <Code Number="3">CIT31C</Code>
    <Code Number="4">CIT30C</Code>
  </CodeList>
  <CodeList CodeListID="C6957FC8-F3B4-4DAE-A8D0-F79A253C5790">
    <Code Number="1">16 to 18</Code>
    <Code Number="2">19 to 25</Code>
    <Code Number="3">26 to 49</Code>
    <Code Number="4">50 plus</Code>

I have produced something but I begin receive things from outside the code lists node and have had no luck with devising a where clause or node specific code. 我已经产生了一些东西,但是我开始从代码列表节点之外接收消息,并且对设计where子句或特定于节点的代码没有运气。

Columns: ProjectID, Data 列:ProjectID,数据

SELECT   [Data].value('(/CodeLists/CodeList/Code)[1]', 'varchar(4000)') [Code1]
        ,[Data].value('(/CodeLists/CodeList/Code)[2]', 'varchar(4000)') [Code2]
        ,[Data].value('(/CodeLists/CodeList/Code)[3]', 'varchar(4000)') [Code3]
        ,[Data].value('(/CodeLists/CodeList/Code )[4]', 'varchar(4000)') [Code4]
        ,[Data].value('(/CodeLists/CodeList/Code )[5]', 'varchar(4000)') [Code5]
FROM [dbo].Codes
WHERE  ProjectID = 1

Apologies if this is a simple task however any help would be greatly appreciated. 抱歉,如果这是一项简单的任务,则将不胜感激。

If I understand you correctly, you need the content of the first CodeList-Node. 如果我理解正确,则需要第一个CodeList-Node的内容。

You get this with CROSS APPLY on the nodes()-function with a filter on the first element (just paste into an empty query window and execute): 您可以在nodes()函数上使用CROSS APPLY并在第一个元素上使用过滤器来实现此目的(只需粘贴到一个空的查询窗口中并执行):

DECLARE @tbl TABLE(ID INT,Data XML);
INSERT INTO @tbl VALUES
 (1,
'<CodeLists>
  <CodeList CodeListID="FAC8BFB9-7C41-4647-A6DC-DF359379B8C3">
    <Code Number="1">L1CCTT</Code>
    <Code Number="2">L2CCTT</Code>
    <Code Number="3">L3CCTT</Code>
  </CodeList>
  <CodeList CodeListID="F0328C4F-916B-414D-AA81-D59244A4F0E1">
    <Code Number="1">16 to 18</Code>
    <Code Number="2">19 to 25</Code>
    <Code Number="3">26 to 49</Code>
    <Code Number="4">50 plus</Code>
  </CodeList>
</CodeLists>')
,(2,
'<CodeLists>
  <CodeList CodeListID="DA730346-2425-439D-ABD0-7FFF1F16ED3E">
    <Code Number="1">L1CCA</Code>
    <Code Number="2">L2CCA</Code>
  </CodeList>
  <CodeList CodeListID="7B9731F5-C1B2-460D-B78F-F7C64A959022">
    <Code CodeNumber="1">16 to 18</Code>
    <Code CodeNumber="2">19 to 25</Code>
    <Code CodeNumber="3">26 to 49</Code>
    <Code CodeNumber="4">50 plus</Code>
  </CodeList>
</CodeLists>')
,(3,
'<CodeLists>
  <CodeList CodeListID="74E6C8E2-BD88-4CB6-B578-DD25EC532CAA">
    <Code Number="1">CIT33C</Code>
    <Code Number="2">CIT32C</Code>
    <Code Number="3">CIT31C</Code>
    <Code Number="4">CIT30C</Code>
  </CodeList>
  <CodeList CodeListID="C6957FC8-F3B4-4DAE-A8D0-F79A253C5790">
    <Code Number="1">16 to 18</Code>
    <Code Number="2">19 to 25</Code>
    <Code Number="3">26 to 49</Code>
    <Code Number="4">50 plus</Code>
  </CodeList>
</CodeLists>');

SELECT tbl.ID,FirstCodeList.CodeNode.value('@Number','int') AS CodeNumber
             ,FirstCodeList.CodeNode.value('.','varchar(max)') AS Code
FROM @tbl AS tbl 
CROSS APPLY tbl.Data.nodes('/CodeLists/CodeList[1]/Code') As FirstCodeList(CodeNode)

The Result (I changed the attribut "CodeNumber" to "Number" in your second example, think this was a typo... Anyway you said, that you are interested in the node's content only...): 结果(在第二个示例中,我将属性“ CodeNumber”更改为“ Number”,认为这是一个错字……无论如何,您说,您仅对节点的内容感兴趣...):

ID  CodeNumber  Code
1   1           L1CCTT
1   2           L2CCTT
1   3           L3CCTT
2   1           L1CCA
2   2           L2CCA
3   1           CIT33C
3   2           CIT32C
3   3           CIT31C
3   4           CIT30C

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM