【问题标题】:Construct xml with variable node names in TSQL在 SQL 中构造带有变量节点名称的 xml
【发布时间】:2018-08-16 21:09:11
【问题描述】:

在我的应用程序中,我使用FOR XML PATH() 运行一个相当复杂的查询来构造一个xml 结果。我在几个存储过程中使用此查询,但每个根节点和第一级节点名称都不同。我想做的是创建一个标量用户定义函数,它将两个节点名称作为参数并返回正确的 xml。预期的输出如下所示:

<{root node name}>
    <{first level node name}  attr1="value1" attr2="value2">
        <detail attr1="value3">
            <error code="1" descr="some error"/>
            <error code="3" descr="some other error"/>
        </detail>
    </{first level node name}>
    <error code="4" descr="yet another error"/>
</{root node name}>

将 {root node name} 和 {first level node name} 作为参数传递

我知道我可以使用动态 SQL 来执行此操作,但它可能非常麻烦,我想避免它。我也可以使用 C# 或使用 XSLT 轻松完成此操作,但我需要完全在 SQL 中完成此操作,因为它将从 SQL 服务代理处理程序中调用。

不幸的是,FOR XML PATH 需要一个文字作为节点名称。我还尝试使用已知的通用节点名称创建 xml,然后尝试使用 XQuery 替换它们,但这也需要文字。 XQuery 必须是文字,节点构造函数中使用的节点名称也必须是文字(不能使用sql:variable()

有没有办法用动态节点名创建 XML?

【问题讨论】:

  • “我知道我可以使用动态 SQL 来执行此操作”不在用户定义的函数中....恐怕我知道在数据库级别执行此操作的唯一两个选项是 CLR 或动态 SQL(在存储过程中,而不是 UDF)。
  • 没错,但在 UDF 中这样做只是为了方便而不是要求。我可以把它变成一个返回单列结果集的存储过程,或者使用输出参数。
  • 这个问题解决了吗?您需要进一步的帮助吗?
  • 并非如此。我最终将 UDF 编码为使用通用元素名称,然后在已知元素名称的 UDF 之外使用 xquery 操作 xml,因此 xquery 可以是文字。我必须在我使用该函数的任何地方重复 xquery,这很烦人且容易出错。据我所知,它要么是这个(如果可能的话)要么是动态 SQL。

标签: sql-server xml tsql generics for-xml


【解决方案1】:

由于元素名称是根据结果集的列名称构建的,因此无法正常工作(动态 SQL 或 CLR 除外),但有补救措施:

DECLARE @rowName NVARCHAR(10)=N'TheRow';
DECLARE @rootName NVARCHAR(10)=N'TheRoot';

DECLARE @OutputXml XML=
CAST(
    REPLACE(REPLACE(
    CAST((SELECT TOP 2 [name],[type] 
          FROM sys.objects 
          FOR XML PATH(N'ThisIsAStringOnlyUsedAsRowElementName')
                 ,ROOT(N'TheSameIdeaForTheRootName')
                 ,TYPE) AS NVARCHAR(MAX))
    ,N'ThisIsAStringOnlyUsedAsRowElementName',@rowName)
    ,N'TheSameIdeaForTheRootName',@rootName) AS XML);


SELECT @outputXML;

结果

<TheRoot>
  <TheRow>
    <name>spt_fallback_db</name>
    <type>U </type>
  </TheRow>
  <TheRow>
    <name>spt_fallback_dev</name>
    <type>U </type>
  </TheRow>
</TheRoot>

一般来说,我会避免对 XML 进行字符串操作(由于可能的副作用和性能影响)。但我认为这是一个合法的解决方法......

【讨论】:

  • 双重转换和双重替换......如果它是一个长 XML,这可能会受到性能问题的影响,但这是一个很好的解决方法...... +1。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-24
  • 2012-10-04
相关资源
最近更新 更多