SQL服务器XML字段-使用TSQL变量作为XML节点序列指示符

SQL Server XML field - using TSQL variable as XML node sequence indicator

为什么这样做?

SELECT
  XDocument
    .value('(/Book/Chapter[@verse="allo"])[2]',
      nvarchar(max)')
FROM XBiblos
WHERE Version = 666

但是为什么这不起作用?唯一的区别是 [2][sql:variable("@i")]

取代

导致错误消息 'value()' requires a singleton (or empty sequence), found operand of type 'xdt:untypedAtomic *'

DECLARE @i int;
SET @i = 2;

SELECT
  XDocument
    .value('(/Book/Chapter[@verse="allo"])[sql:variable("@i")]',
      nvarchar(max)')
FROM XBiblos
WHERE Version = 666

文档结构示例 ...

<XDocument name="DraXQueLah">
  <Book name="Worldymort">
    <Chapter verse="Forgot">Forgot so loved the world</Chapter >
    <Chapter verse="Icecream">That we were eternally creamed</Chapter >
    <Chapter verse="blah">blah blah</Chapter >    
    <Chapter verse="blah">blah blah</Chapter >    
    <Chapter verse="blah">blah blah</Chapter >    
    <Chapter verse="blah blah">blah blah blah</Chapter >    
  </Book>
</XDocument>

只需添加 [1] 即可强制使用单例。引擎知道 [2](这是位置),肯定会! - 只有一个(或 none)结果。但是引擎无法预测,您的表达式将导致一个结果:

DECLARE @i int;
SET @i = 2;

SELECT
  XDocument
    .value('(/Book/Chapter[@verse="allo"])[sql:variable("@i")][1]', --<--Here
      nvarchar(max)')
FROM XBiblos
WHERE Version = 666