【问题标题】:SQL : How can I extract substring what I want from a long xml string?SQL:如何从长 xml 字符串中提取我想要的子字符串?
【发布时间】:2019-12-27 12:14:33
【问题描述】:

我的 SQL 表中有一个包含 XML 值的列。 我必须阅读这三个元素中的值:

<POSTN_ID>0000-0000H1-POS</POSTN_ID>
<ROLE_ID>0000-00002B-ROL</ROLE_ID>
<STATUS>1</STATUS>

在这种情况下哪些 SQL 方法可以帮助我?

<parameter name="OrgHierarchyDatasets_diffgram">
  <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
    <NewDataSet>
      <PositionRoles diffgr:id="PositionRoles1" msdata:rowOrder="0" diffgr:hasChanges="inserted">
          <POSTN_ID>0000-0000H1-POS</POSTN_ID>
          <ROLE_ID>0000-00002B-ROL</ROLE_ID>
          <STATUS>1</STATUS>
      </PositionRoles>
    </NewDataSet>
  </diffgr:diffgram>
</parameter>
<parameter name="ExistNodeCheck" type="System.Boolean">True</parameter>

【问题讨论】:

  • 看看 XQUERY。
  • 你处理什么版本的 SQL Server?

标签: sql sql-server tsql substring


【解决方案1】:

以下语法可以帮助您捕获您定义的对象并将它们带到表模型中。

DECLARE @xml xml = '
<parameter name="OrgHierarchyDatasets_diffgram">
  <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
    <NewDataSet>
      <PositionRoles diffgr:id="PositionRoles1" msdata:rowOrder="0" diffgr:hasChanges="inserted">
          <POSTN_ID>0000-0000H1-POS</POSTN_ID>
          <ROLE_ID>0000-00002B-ROL</ROLE_ID>
          <STATUS>1</STATUS>
      </PositionRoles>
    </NewDataSet>
  </diffgr:diffgram>
</parameter>
<parameter name="ExistNodeCheck" type="System.Boolean">True</parameter>'

SELECT  
       Tbl.Col.value('POSTN_ID[1]', 'nvarchar(50)') AS POSTN_ID,
       Tbl.Col.value('ROLE_ID[1]', 'nvarchar(50)') AS ROLE_ID,
       Tbl.Col.value('STATUS[1]', 'nvarchar(50)') AS STATUS
FROM   @xml.nodes('//PositionRoles') Tbl(Col) 

【讨论】:

  • 谢谢,它对我有帮助,但我还有另一个问题。我只需要具有 diffgr:hasChanges="inserted" 属性的 标记。我用过 ;WITH XMLNAMESPACES('inserted' as hasChanges) ,但没有用。
  • 我在 sql 查询中的条件:WHERE RESPONSE_PACKET.value('(/request-broker-message/request/parameter[@name="OrgHierarchyDatasets_diffgram"]//NewDataSet/hasChanges:PositionRoles/STATUS)[ 1]', 'varchar(1)') = '1'
【解决方案2】:

使用 xPath/xQuery:

select cast('<parameter name="OrgHierarchyDatasets_diffgram">
  <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
    <NewDataSet>
      <PositionRoles diffgr:id="PositionRoles1" msdata:rowOrder="0" diffgr:hasChanges="inserted">
          <POSTN_ID>0000-0000H1-POS</POSTN_ID>
          <ROLE_ID>0000-00002B-ROL</ROLE_ID>
          <STATUS>1</STATUS>
      </PositionRoles>
    </NewDataSet>
  </diffgr:diffgram>
</parameter>
<parameter name="ExistNodeCheck" type="System.Boolean">True</parameter>' as xml) as col
into #tab
go

select
  col,
  nod,
  nod.query('./POSTN_ID/text()'),
  nod.value('./ROLE_ID[1]','varchar(255)')
from (
  select
    *, col.query('//PositionRoles/node()') as nod
  from #tab
) x

【讨论】:

  • 谢谢,xpath 方法帮助了我。
猜你喜欢
  • 2020-07-02
  • 1970-01-01
  • 1970-01-01
  • 2023-01-10
  • 1970-01-01
  • 2011-11-17
  • 1970-01-01
  • 1970-01-01
  • 2012-10-24
相关资源
最近更新 更多