无法在SQL Server中遍历XML节点遍历中的索引

问题描述

在使用xml.value遍历XML时,我无法使用索引进行迭代。 在下面的代码中,您可以看到我正在尝试迭代xml并尝试在Detail节点下打印Value。但是,如果我对索引进行硬编码,则可以很好地工作,但是我需要从while循环增量中传递索引。我不确定如何传递总是失败的索引

DECLARE @myXml XML = '
<EmployeeConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="
http://www.w3.org/2001/XMLSchema">
  <Employee>
    <Detail Id="100" Name="John">
        <Type>Permanent</Type>
        <Value>U2tpbGw=</Value>
    </Detail>
  </Employee>
  <Employee>
    <Detail Id="200" Name="Rachel">
        <Type>Contract</Type>
        <Value>RXhwZXJpZW5jZQ==</Value>
     </Detail>
  </Employee>
  <Employee>
    <Detail Id="300" Name="Danny">
    <Type>Permanent</Type>
    <Value>U2tpbGw=</Value>
    </Detail>
  </Employee>
</EmployeeConfiguration>'

SELECT @myXml
DECLARE @count INT,@i INT;
DECLARE @Value varchar(max);

SELECT @count = @myXml.query('<e>
                                { count(/EmployeeConfiguration/Employee/Detail) }
                              </e>').value('e[1]','int')
SELECT @count   -- Returns count as 3

SET @i=1

WHILE @i < = @count 
BEGIN

    -- SELECT @Value = @myXml.value('(/EmployeeConfiguration/Employee/Detail/Value)[2]','nvarchar(max)') -- This code works if Hardcode the index and returns correct value (RXhwZXJpZW5jZQ==) in this case

    -- This does not work and I get this error    
    --  Msg 2389,Level 16,State 1,Line 39  
    -- XQuery [value()]: 'value()' requires a singleton (or empty sequence),-- found operand of type 'xdt:untypedAtomic *'
    SELECT @Value = @myXml.value('(/EmployeeConfiguration/Employee/Detail/Value) [@i]','nvarchar(max)') 


    -- This is also not working      
    SELECT @Value = @myXml.value('(/EmployeeConfiguration/Employee/Detail/Value)[sql:variable(@i)]','nvarchar(max)')

    SELECT @Value

    SET @i = @i + 1
END

解决方法

DECLARE @myXml XML = '
<EmployeeConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="
http://www.w3.org/2001/XMLSchema">
  <Employee>
    <Detail Id="100" Name="John">
        <Type>Permanent</Type>
        <Value>U2tpbGw=</Value>
    </Detail>
  </Employee>
  <Employee>
    <Detail Id="200" Name="Rachel">
        <Type>Contract</Type>
        <Value>RXhwZXJpZW5jZQ==</Value>
     </Detail>
  </Employee>
  <Employee>
    <Detail Id="300" Name="Danny">
    <Type>Permanent</Type>
    <Value>U2tpbGw=</Value>
    </Detail>
  </Employee>
</EmployeeConfiguration>'


declare @i int = 2;
--RXhwZXJpZW5jZQ==
SELECT  @myXml.value('(EmployeeConfiguration/Employee/Detail/Value)[sql:variable("@i")][1]','nvarchar(max)');

set @i = 3;
--U2tpbGw=
SELECT  @myXml.value('(EmployeeConfiguration/Employee/Detail/Value)[sql:variable("@i")][1]','nvarchar(max)');