1

I have the following xml in an xml column in sql server, it is in a table along with a id column -

<ArrayOfExtVar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ExtVar>
    <Name xsi:type="xsd:string">Rate Code</Name>
    <Value xsi:type="xsd:string">E46</Value>
  </ExtVar>
  <ExtVar>
    <Name xsi:type="xsd:string">Middle Name</Name>
    <Value xsi:type="xsd:string">Henry</Value>
  </ExtVar>
</ArrayOfExtVar>

And I have the following XPath -

SELECT CustID, 
ExtVars.value('(/ArrayOfExtVar/ExtVar/Value)[1]', 'Nvarchar(max)') AS RateCode,
ExtVars.value('(/ArrayOfExtVar/ExtVar/Value)[2]', ''Nvarchar(max)') AS MiddleInitial 
FROM dbo.Customer

which is great but what I'd really like to do is query the xml by 'Name' rather than the index ([1]) as these may be stored in different orders from time to time.

Basically what I need to know is how can I query by the value of 'Name' something like -

'(/ArrayOfExtVar/ExtVar/Value)[Rate Code]'

Could I add an attribute to the ExtVars Node and query on that instead?

4

4 に答える 4

1

It sounds like you want

/ArrayOfExtVar/ExtVar[Name = 'Rate Code']/Value
于 2013-01-28T12:52:16.647 に答える
0

あなたはこのようなことをしようとしていますか?

DECLARE @input TABLE (ID INT, ExtVars XML)

INSERT INTO @input VALUES(1, '<ArrayOfExtVar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ExtVar>
    <Name xsi:type="xsd:string">Rate Code</Name>
    <Value xsi:type="xsd:string">E46</Value>
  </ExtVar>
  <ExtVar>
    <Name xsi:type="xsd:string">Middle Name</Name>
    <Value xsi:type="xsd:string">Henry</Value>
  </ExtVar>
</ArrayOfExtVar>')

SELECT
    Name = ExtVar.value('(Name)[1]', 'varchar(50)'),
    [Value] = ExtVar.value('(Value)[1]', 'varchar(50)')
FROM
    @input
CROSS APPLY
    ExtVars.nodes('/ArrayOfExtVar/ExtVar') AS XTbl(ExtVar)
WHERE   
    ID = 1

次のような出力を返します。

ここに画像の説明を入力してください

そしてもちろん、これに名前ベースのWHERE句を追加することもできます(結果を決定するためにXMLに「到達」します)。

SELECT
    Name = ExtVar.value('(Name)[1]', 'varchar(50)'),
    [Value] = ExtVar.value('(Value)[1]', 'varchar(50)')
FROM
    @input
CROSS APPLY
    ExtVars.nodes('/ArrayOfExtVar/ExtVar') AS XTbl(ExtVar)
WHERE   
    ExtVar.value('(Name)[1]', 'varchar(50)') LIKE 'Rate%'   -- or whatever you want
于 2013-01-28T12:29:47.007 に答える
0

I don't know if SQL Server's implementation of XPath supports the parent (..) operator, but you could try this instead:

/ArrayOfExtVar/ExtVar/Name[text()='Rate Code']/../Value

This finds the Name node that has an inner text of 'Rate Code', then navigates to its parent and from there it goes to the Value node underneath it.


If you could add Name as an attribute of the ExtVar node, that would make it a bit easier:

Sample XML:

...
<ExtVar name="Rate Code">
    <Value xsi:type="xsd:string">E46</Value>
</ExtVar>
...

XPath:

/ArrayOfExtVar/ExtVar[@name='Rate Code']/Value
于 2013-01-28T12:44:42.540 に答える
0

You can do axis steps in predicates, too.

//ExtVar[Name eq 'Rate Code']/Value
于 2013-01-28T12:49:33.417 に答える