How to pass a variable into XPath of XQuery in an SQL statement

那年仲夏 提交于 2019-12-12 12:32:13

问题


Scenario: I have an xml column in MSSQL database which I have to parse the XML data of that cell using XQuery .

     Xml content : <AnchoredXml xmlns="urn:schema:Microsoft.Rtc.Management.ScopeFramework.2008" SchemaWriteVersion="2">
  <Key ScopeClass="Global">
    <SchemaId Namespace="urn:schema:Microsoft.Rtc.Management.Deploy.Topology.2008" ElementName="Topology" />
    <AuthorityId Class="Host" InstanceId="00000000-0000-0000-0000-000000000000" />
  </Key>
  <Dictionary Count="1">
    <Item>
      <Key />
      <Value Signature="b1ac04f7-d8f0-4300-86cf-fb2b3383536c">
        <Topology xmlns="urn:schema:Microsoft.Rtc.Management.Deploy.Topology.2008">
          <InternalDomains AllowAllDomains="false" DefaultDomain="ocsqa.com">
            <InternalDomain Name="ocsqa.com" Authoritative="false" AllowSubDomains="false" />
          </InternalDomains>
          <Sites>
            <CentralSite SiteId="1">
              <Name>LyncSite</Name>
              <Location />
            </CentralSite>
          </Sites>
          <Clusters>

This is a piece of data of the xml content in that one cell.

I am using below query to traverse the nodes of above xml:

select @cluster = @Items.query('/DocItemSet/DocItem/Data/*[@SchemaWriteVersion="2"]/*[2]/*[1]/*[2]/*[1]/*[3]') 

Output of the above query is :

    <p1:Cluster xmlns:p1="urn:schema:Microsoft.Rtc.Management.Deploy.Topology.2008" RequiresReplication="true" RequiresSetup="true" Fqdn="XXXX.ocsqa.com">
  <p1:ClusterId SiteId="1" Number="1" />
  <p1:Machine OrdinalInCluster="1" Fqdn=" XXXX.ocsqa.com">
    <p1:NetInterface InterfaceSide="Primary" InterfaceNumber="1" IPAddress="0.0.0.0" />
    <p1:NetInterface InterfaceSide="External" InterfaceNumber="1" IPAddress="0.0.0.0" />
    <p1:NetInterface InterfaceSide="Pstn" InterfaceNumber="1" IPAddress="0.0.0.0" />
  </p1:Machine>
</p1:Cluster>
<p2:Cluster xmlns:p2="urn:schema:Microsoft.Rtc.Management.Deploy.Topology.2008" RequiresReplication="true" RequiresSetup="true" Fqdn=" XXXX2.ocsqa.com">
  <p2:ClusterId SiteId="1" Number="2" />
  <p2:Machine OrdinalInCluster="1" Fqdn=" XXXX2.ocsqa.com">
    <p2:NetInterface InterfaceSide="Primary" InterfaceNumber="1" IPAddress="0.0.0.0" />
    <p2:NetInterface InterfaceSide="External" InterfaceNumber="1" IPAddress="0.0.0.0" />
    <p2:NetInterface InterfaceSide="Pstn" InterfaceNumber="1" IPAddress="0.0.0.0" />
  </p2:Machine>
</p2:Cluster>
<p3:Cluster xmlns:p3="urn:schema:Microsoft.Rtc.Management.Deploy.Topology.2008" RequiresReplication="true" RequiresSetup="true" Fqdn=" XXXX2.ocsqa.com">
  <p3:ClusterId SiteId="1" Number="3" />
  <p3:Machine OrdinalInCluster="1" Fqdn=" XXXX2.ocsqa.com" />
</p3:Cluster>

Now using query mentioned as below :

select @fqdn = @cluster.value('(./*/*/@Fqdn)[1]','nvarchar(20)') Select @fqdn

Note the highlighted index no in above query. Using this query we will be able to achieve the first Cluster available in xml, similarly I wanted to look for other Clusters as well.

So I wanted to use this query in while loop. For which I have to pass a variable instead of hardcoded int value. Something similar as below :

select @fqdn = @cluster.value('(./*/*/@Fqdn)[sql:variable("@test")]','nvarchar(20)')

I have referred some posts How to use XPath with a variable in Oracle XMLTable? http://www.jasonstrate.com/2011/01/xquery-for-the-non-expert-variable-use/

but I am getting error as below :

Msg 2389, Level 16, State 1, Line 35 XQuery [value()]: 'value()' requires a singleton (or empty sequence), found operand of type 'xdt:untypedAtomic *' How to pass a variable into a XQuery of SQL statement?


回答1:


You need to tell SQL Server that you are only interested in the a single node. Add a [1] at the end.

@cluster.value('(./*/*/@Fqdn)[sql:variable("@test")][1]','nvarchar(20)')


来源:https://stackoverflow.com/questions/18743212/how-to-pass-a-variable-into-xpath-of-xquery-in-an-sql-statement

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!