【问题标题】:In SQL Server can I insert multiple nodes into XML from a table?在 SQL Server 中,我可以将多个节点从表中插入 XML 吗?
【发布时间】:2010-09-13 22:58:03
【问题描述】:

我想根据表中的数据在存储过程中生成一些 XML。

以下插入允许我添加许多节点,但它们必须是硬编码或使用变量(sql:variable):

SET @MyXml.modify('
      insert
         <myNode>
            {sql:variable("@MyVariable")}
         </myNode>
      into (/root[1]) ') 

所以我可以遍历表中的每条记录,将我需要的值放入变量中并执行上述语句。

但是有没有一种方法可以通过结合 select 语句并避免循环来做到这一点?

编辑 我以前用SELECT FOR XML 做过类似的事情,但是在处理来自多个表的数据层次结构时,我总是觉得很难阅读。我希望使用modify 可以使生成的 XML 更加明确和可控。

【问题讨论】:

    标签: sql-server xml tsql insert xquery


    【解决方案1】:

    您是否尝试过嵌套 FOR XML PATH 标量值函数? 使用嵌套技术,您可以将 SQL 分解为非常易于管理/可读的元素片段

    免责声明:以下内容虽然改编自一个工作示例,但本身并未经过实际测试

    一些供普通观众参考的链接

    最简单、最底层的嵌套节点示例

    考虑以下调用

    DECLARE  @NestedInput_SpecificDogNameId int
    SET @NestedInput_SpecificDogNameId = 99
    SELECT [dbo].[udfGetLowestLevelNestedNode_SpecificDogName] 
    (@NestedInput_SpecificDogNameId)
    

    假设 udfGetLowestLevelNestedNode_SpecificDogName 是在没有 FOR XML PATH 子句的情况下编写的,并且对于 @NestedInput_SpecificDogName = 99 它返回单个行集记录:

    @SpecificDogNameId 狗名 99 天文

    但是使用 FOR XML PATH 子句,

    CREATE FUNCTION dbo.udfGetLowestLevelNestedNode_SpecificDogName
    (
    @NestedInput_SpecificDogNameId
    )
        RETURNS XML
        AS
        BEGIN
    
            -- Declare the return variable here
            DECLARE @ResultVar XML
    
            -- Add the T-SQL statements to compute the return value here
            SET @ResultVar =
                (
                SELECT 
                      @SpecificDogNameId as "@SpecificDogNameId",
                      t.DogName 
                FROM tblDogs t
                FOR XML PATH('Dog')
                )
    
            -- Return the result of the function
            RETURN @ResultVar
    
    END
    

    用户定义的函数生成以下 XML(@ 符号导致 SpecificDogNameId 字段作为属性返回)

    <Dog SpecificDogNameId=99>Astro</Dog>
    

    嵌套 XML 类型的用户定义函数

    上面的udfGetLowestLevelNestedNode_SpecificDogName等用户自定义函数可以嵌套,提供强大的方法来生成复杂的XML。

    例如函数

    CREATE FUNCTION [dbo].[udfGetDogCollectionNode]()
        RETURNS XML
        AS
        BEGIN
    
            -- Declare the return variable here
            DECLARE @ResultVar XML
    
            -- Add the T-SQL statements to compute the return value here
            SET @ResultVar =
                (
                    SELECT  
                    [dbo].[udfGetLowestLevelNestedNode_SpecificDogName]
                            (t.SpecificDogNameId)
                    FROM tblDogs t
    
                    FOR XML PATH('DogCollection') ELEMENTS
                )
            -- Return the result of the function
            RETURN @ResultVar
    
    END
    

    当调用为

    SELECT [dbo].[udfGetDogCollectionNode]()
    

    可能会产生复杂的 XML 节点(给定适当的基础数据)

    <DogCollection>
        <Dog SpecificDogNameId="88">Dino</Dog>
        <Dog SpecificDogNameId="99">Astro</Dog>
    </DogCollection>
    

    从这里开始,您可以继续在嵌套树中向上工作,以构建任意复杂的 XML 结构

    CREATE FUNCTION [dbo].[udfGetAnimalCollectionNode]()
    RETURNS XML
    AS
    BEGIN
    
    DECLARE @ResultVar XML
    
    SET @ResultVar =
    (
    SELECT 
    dbo.udfGetDogCollectionNode(),
    dbo.udfGetCatCollectionNode()
    FOR XML PATH('AnimalCollection'), ELEMENTS XSINIL
    )
    
    RETURN @ResultVar
    
    END
    

    当调用为

    SELECT [dbo].[udfGetAnimalCollectionNode]()
    

    udf 可能会生成更复杂的 XML 节点(给定适当的基础数据)

    <AnimalCollection>
      <DogCollection>
        <Dog SpecificDogNameId="88">Dino</Dog>
        <Dog SpecificDogNameId="99">Astro</Dog>
      </DogCollection>
      <CatCollection>
        <Cat SpecificCatNameId="11">Sylvester</Cat>
        <Cat SpecificCatNameId="22">Tom</Cat>
        <Cat SpecificCatNameId="33">Felix</Cat>
      </CatCollection>
    </AnimalCollection>
    

    【讨论】:

      【解决方案2】:

      您能否详细说明您打算做什么。 是否只是根据表的内容生成 XML 数据 还是将表中的一些数据添加到现有的 xml 结构中?

      Jacob Sebastian 写的 SQLServer 中 XML 的主题上有great series of articles,它以basics of generating XML from the data in the table开头

      【讨论】:

        【解决方案3】:

        使用 sql:column 代替 sql:variable。您可以在这里找到详细信息:http://msdn.microsoft.com/en-us/library/ms191214.aspx

        【讨论】:

          猜你喜欢
          • 2019-05-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多