2

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

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

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

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

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

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

4

3 回答 3

7

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

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

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

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

考虑以下调用

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

假设在没有 FOR XML PATH 子句的情况下编写了 udfGetLowestLevelNestedNode_SpecificDogName,并且对于 @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>
于 2008-09-29T14:21:17.107 回答
1

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

Jacob Sebastian 撰写了关于 SQLServer 中 XML 主题的精彩系列文章,它从从表中的数据生成 XML 的基础知识开始

于 2008-09-29T09:40:03.540 回答
1

使用 sql:column 而不是 sql:variable。您可以在此处找到详细信息:http: //msdn.microsoft.com/en-us/library/ms191214.aspx

于 2010-03-15T14:36:33.317 回答