sql查询在xml列中搜索值

时间:2018-01-27 22:25:45

标签: xml tsql xpath sql-server-2012 xquery

<MultiItems>
    <Items>
        <Profile>221</Profile>
        <Creator Company Name>pepsi</Creator Company Name>
        <Creator Contact Name>pepsico</Creator Contact Name>
        <SUPC>11</SUPC>
        <Keywords>beverages</Keywords>
    </Items>
</MultiItems>

这就是xml在文件中的样子 我的sql server数据库中有一个xml列。它包含有关产品的元数据信息。不同的标签是产品的不同元数据。我应该如何检索此xml中的所有值,包括创建者联系人姓名,supc以及如何返回其中没有值的标记的名称。

1 个答案:

答案 0 :(得分:0)

事先有些事情:

  • 您问题中发布的XML无效。我已经告诉过您了,您在问题下方的评论中发布了一些示例。
  • 我现在正在使用这些示例,尽管您发布的XML中有一些奇怪的字符,我必须删除它们。你找到它们,当你用光标单步执行文本并到达光标不会移动的位置时......
  • 您的最后一个示例没有正确的结束标记。

无论如何,我真的不知道,你想要什么。根据您的问题,您正在尝试读取值,但在您所说的评论中,您正在寻找没有值的节点。但是 - 我会同时展示:

DECLARE @tbl TABLE(ID INT IDENTITY, YourXmlColumn XML);
INSERT INTO @tbl VALUES
(N'<MultiItems>
  <Item>
    <Profile>211</Profile>
    <Metadatas>
      <Metadata>
        <Control>1ccf8d18-3‌​dd7-4a7e-a6ce-630bfd‌​8f3358</Control>
        <ControlTypeID>5ae9a004-‌​c0de-4692-a9bd-e8f73‌​926f4f3</ControlTypeID>
        <Name>Creator Company Name:</Name>
        <Value>SGS Test</Value>
        <ControlDatas />
      </Metadata>
    </Metadatas>
  </Item>
</MultiItems>')
,(N'<MultiItems>
  <Item>
    <Profile>234</Profile>
    <Metadatas>
      <Metadata>
        <Control>53c72c46-5‌​75b-426a-903d-2969bd‌​a4efcd</Control>
        <Name>Multi Lingual</Name>
        <Value />
        <ControlDatas />
      </Metadata>
    </Metadatas>
  </Item>
</MultiItems>');

- 值的查询

SELECT t.id
      ,t.YourXmlColumn.value(N'(/MultiItems/Item/Profile/text())[1]',N'int') AS [Profile]
      ,t.YourXmlColumn.value(N'(/MultiItems/Item/Metadatas/Metadata/Control/text())[1]',N'nvarchar(max)') AS [Control]
      ,t.YourXmlColumn.value(N'(/MultiItems/Item/Metadatas/Metadata/Name/text())[1]',N'nvarchar(max)') AS [Name]
      ,t.YourXmlColumn.value(N'(/MultiItems/Item/Metadatas/Metadata/Value/text())[1]',N'nvarchar(max)') AS [Value]
FROM @tbl AS t;

- 如果要查看<Metadata>内没有文字的所有节点,请尝试使用

SELECT t.id
      ,nd.value(N'local-name(.)',N'nvarchar(max)') AS EmptyNodeName
FROM @tbl AS t
CROSS APPLY t.YourXmlColumn.nodes(N'//Metadata/*[empty(text())]') AS A(nd)

更新

我的错误的答案是错误措辞的结果

  

想要返回没有值的标记的名称

没有价值的标签是没有价值的标签,而不是另一个......

试试这个

SELECT t.id
      ,nd.value(N'text()[1]',N'nvarchar(max)') AS EmptyNodeName
FROM @tbl AS t
CROSS APPLY t.YourXmlColumn.nodes(N'//Metadata[empty(Value/text())]/Name') AS A(nd);

如果<Name>为空,则会在<Metadata>下方找到Value/text()个节点。