【问题标题】:Insert XML nodes in order defined by the XML structure按 XML 结构定义的顺序插入 XML 节点
【发布时间】:2014-04-11 08:15:37
【问题描述】:

我有一个包含后续列的表变量:

[ID] TINYINT
[XML] XML

XML 结构如下所示:

 <conditions>

    <condition type='expresion'>
        ...
    </condition>
    <condition type='operand'>
        ...
    </condition>
    <condition type='expresion'>
        ...
    </condition>
    <condition type='operand'>
        ...
    </condition>
    <condition type='expresion'>
        ...
    </condition>

</conditions>

我需要提取上面的信息并使用以下结构填充表格:

[ID]
[ConditionID]
[ConditionXML]

其中ConditionID 将是数字列,ConditonXML 将从原始XML 中提取。

对我来说非常重要的是生成ConditionID 值以表示原始XML 结构中的顺序。

have read 认为这可以使用ROW_NUMBER 来完成,如下所示:

SELECT [ID]
        ,ROW_NUMBER() OVER (PARTITION BY [ID] ORDER BY T.c) AS T
        ,T.c.query('.')
FROM @Test
CROSS APPLY [CondtionsXML].nodes('conditions/condition') T(c)
ORDER BY [ID], T

但是在official documentation 中是这样说的:

无法保证查询返回的行使用 ROW_NUMBER() 的顺序将与每次执行完全相同 除非满足以下条件:

  1. 分区列的值是唯一的。
  2. ORDER BY 列的值是唯一的。
  3. 分区列和 ORDER BY 列的值的组合 是独一无二的。

由于我的operand 节点可能相同,我担心我可能会遇到一些问题。另外,如果我删除 PARTITON BY 子句,事情就会出错。

我可以使用的其他方法是使用 INDENTITY 列创建一个单独的故事,并像这样将值插入其中:

DECLARE @TEST1 TABLE
(
     [ID] SMALLINT IDENTITY(1,1)
    ,[ParentID] TINYINT
    ,[XML] XML
)

INSERT INTO @TEST1 ([ParentID], [XML])
SELECT [ID]
      ,T.c.query('.')
FROM @Test
CROSS APPLY [CondtionsXML].nodes('conditions/condition') T(c)

谁能说这是否是按照XML 结构器中表示的顺序在表中插入XML 节点的方法。

【问题讨论】:

    标签: sql-server xml tsql sql-server-2012 nodes


    【解决方案1】:

    我认为文档有误,我无法向您展示其他支持我的文档。

    这是我认为应该的。我强调了变化。

    无法保证查询返回的行使用 ROW_NUMBER() 将在每次执行时编号完全相同 除非其中一个满足以下条件:

    1.分区列的值是唯一的。

    如果此条件为真,则 row_number() 将为所有行返回 1。它总是会这样做,并且没有任何东西可以改变这种行为,因此仅此条件就可以保证每次执行的结果都是相同的。

    2。 ORDER BY 列的值是唯一的。

    如果 order by 中的值是唯一的,并且您没有 partition by 子句,则 row_number() 返回的每个值在结果集中都是唯一的,并且每次执行都将返回完全相同的值的查询。

    3.分区列和 ORDER BY 列的值组合是唯一的。

    在这种情况下,您有一个 partition by 子句和一个 order by 子句。 row_number() 对于每个分区从一个开始,如果 order by 子句中使用的值在分区内是唯一的,则每次执行的编号都是相同的。

    【讨论】:

    • 所以,在我的情况下,因为我的values 不是唯一的,即使使用partion by clause(正如我所说的一些 xml 节点是相同的)它不会是正确的使用ROW_NUMBER。你能告诉我如果我使用table with indentity column solution,结构顺序将被保留吗?
    • 是的,但是当我使用cross apply 时,我以多行结尾,ID 相同,XMLs 不同。
    • @gotqn T.c 是被cross apply 分解的节点的内部整数表示。然后你会在上面的情况 3 中结束。分区列和按列排序的组合是唯一的。 XML 中的节点是否相同并不重要。
    • 谢谢,我明白了。只是好奇,你知道table solition 是否会产生相同的结果吗?
    【解决方案2】:

    您可以使用(select 1) 构造。它说按原样对结果集进行排序。

    select [ID]
        , row_number() over (partition by [ID] order by (select 1) ) as T
        , T.c.query('.')
    from @Test
    cross apply [XML].nodes ('/conditions[1]/condition')T(c)
    

    【讨论】:

    • 谢谢,但您能否提供指向文档、文章或其他内容的链接来证实这一点?
    • 我只能提供这个 SO 问题:stackoverflow.com/questions/17748012/…
    • select 1 in the order by 不保证每次执行查询时生成的数字都相同。
    猜你喜欢
    • 2023-01-11
    • 2022-08-18
    • 2019-01-27
    • 2020-07-14
    • 1970-01-01
    • 2012-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多