Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
273 views
in Technique[技术] by (71.8m points)

sql server - XPath to fetch SQL XML value

Here is my problem: from the following XML that is within a column, I want to know if the value of a variable with the name 'Enabled' is equal to 'Yes' given a step Id and a component Id.

'<xml>
  <box stepId="1">
    <components>
      <component id="2">
        <variables>
          <variable id="3" nom="Server" valeur="DEV1" />
          <variable id="4" nom="Enabled" valeur="Yes" />
        </variables>
      </component>
      <component id="3">
        <variables>
          <variable id="3" nom="Server" valeur="DEV1" />
          <variable id="4" nom="Enabled" valeur="No" />
        </variables>
      </component>
    </components>
  </box>
  <box stepId="2">
    <components>
      <component id="2">
        <variables>
          <variable id="3" nom="Server" valeur="DEV2" />
          <variable id="4" nom="Enabled" valeur="Yes" />
        </variables>
      </component>
      <component id="3">
        <variables>
          <variable id="3" nom="Server" valeur="DEV2" />
          <variable id="4" nom="Enabled" valeur="No" />
        </variables>
      </component>
    </components>
  </box>
</xml>'
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Update

My recomendation would be to shred the XML into relations and do searches and joins on the resulted relation, in a set oriented fashion, rather than the procedural fashion of searching specific nodes in the XML. Here is a simple XML query that shreds out the nodes and attributes of interest:

select x.value(N'../../../../@stepId', N'int') as StepID
  , x.value(N'../../@id', N'int') as ComponentID
  , x.value(N'@nom',N'nvarchar(100)') as Nom
  , x.value(N'@valeur', N'nvarchar(100)') as Valeur
from @x.nodes(N'/xml/box/components/component/variables/variable') t(x)

However, if you must use an XPath that retrieves exactly the value of interest:

select x.value(N'@valeur', N'nvarchar(100)') as Valeur
from @x.nodes(N'/xml/box[@stepId=sql:variable("@stepID")]/
    components/component[@id = sql:variable("@componentID")]/
       variables/variable[@nom="Enabled"]') t(x)

If the stepID and component ID are columns, not variables, the you should use sql:column() instead of sql:variable in the XPath filters. See Binding Relational Data Inside XML Data.

And finaly if all you need is to check for existance you can use the exist() XML method:

select @x.exist(
  N'/xml/box[@stepId=sql:variable("@stepID")]/
    components/component[@id = sql:variable("@componentID")]/
      variables/variable[@nom="Enabled" and @valeur="Yes"]') 

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...