代码之家  ›  专栏  ›  技术社区  ›  Denis Valeev

如何创建一个绑定到模式的函数来计算xml中的节点数,然后将结果持久化到列中

  •  0
  • Denis Valeev  · 技术社区  · 15 年前

    我有一个xml列,我想在相邻的列中保留一个节点计数。

    a 所以我想输出它。

    但是,我遇到的问题是,我无法创建一个通用的绑定到模式的函数,该函数将接受@xml和@nodeName,以便返回指定节点的计数。

    create function dbo.fnXmlCount_a (@xml xml) 
    returns int with schemabinding
    as begin
    return (@xml.value('count(//a)', 'int'))
    end
    
    declare @xml xml;
    set @xml = '
    <r>
     <a></a>
     <b></b>
     <a></a>
     <c>
      <a></a> 
     </c>
    </r>'
    
    select dbo.fnXmlCount_a(@xml) aCount
    

    最后一次操作的结果是:

    aCount
    3
    

    然后在该表上创建一个列,其中包含如下xml字段:

    alter table [XmlTable] add column [aCount] as (dbo.fnXmlCount_a([xml])) persisted
    

    alter table [XmlTable] add column [aCount] as (dbo.fnXmlNodeCount([xml], 'a')) persisted
    

    更新:

    我们都知道 // 它的速度非常慢,所以如果您能够找出如何传递此路径以在另一个变量中搜索,那就太好了;默认情况下,此搜索路径是 // .

    2 回复  |  直到 15 年前
        1
  •  5
  •   Daniel Renshaw    15 年前

    干得好:

    create function dbo.fnXmlCount (@xml xml, @name nvarchar(max))  
    returns int with schemabinding 
    as begin 
    declare @count int
    select @count = count(*)
    from @xml.nodes('//*') as t(c)
    where t.c.value('local-name(.)', 'nvarchar(max)') = @name
    return @count
    end 
    
        2
  •  1
  •   Denis Valeev    15 年前

    我已经提出了一个更好的解决方案,但是这个方法和danielrenshaw类似。

    create function [dbo].[fnXmlCount] (@xml xml, @nodeName nvarchar(max))  
    returns int with schemabinding 
    as begin 
    return @xml.value('count(//*[local-name() = sql:variable("@nodeName")])', 'int')
    end 
    

    计算xml表上的节点数大约需要20秒。

    推荐文章