Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Tsql 如何将CTE与FOR XML子句组合?_Tsql_Sql Server 2008_Common Table Expression_For Xml - Fatal编程技术网

Tsql 如何将CTE与FOR XML子句组合?

Tsql 如何将CTE与FOR XML子句组合?,tsql,sql-server-2008,common-table-expression,for-xml,Tsql,Sql Server 2008,Common Table Expression,For Xml,我正在尝试生成一些具有不同嵌套级别的XML,并且冒着过度简化的风险,输出XML的格式将松散: <invoice number="1"> <charge code="foo" rate="123.00"> <surcharge amount="10%" /> </charge> <charge code="bar" /> </invoice> 现在,这是难以置信的接近,给出(注意嵌套的): 但我需要找到一种方法

我正在尝试生成一些具有不同嵌套级别的XML,并且冒着过度简化的风险,输出XML的格式将松散:

<invoice number="1">
 <charge code="foo" rate="123.00">
  <surcharge amount="10%" />
 </charge>
 <charge code="bar" />
</invoice>
现在,这是难以置信的接近,给出(注意嵌套的
):



但我需要找到一种方法,使结束查询包含XML列的值,该列将被视为元素的内容,而不是新元素。这是可能的,还是我需要采取一种新的方法?

我认为可以通过省略“for xml path('overload')”语句中的根节点类型来做到这一点。也就是说,使用“for xml path(“”)”。

您有一个列查询,它返回多行(@charge、@rate和一个xml类型)。我希望您发布的查询会给出错误:


只能指定一个表达式 在选择列表中,当子查询 不与EXISTS一起引入

但是,通过将查询移动到
外部应用
,可以很容易地解决这个问题。要删除double
supployee
元素,可以将XML列名尽可能地移到底部,如:

;WITH Charges (code, rate, surcharge, InvoiceId) AS 
    (
    SELECT  code, amount, NULL, InvoiceId
    FROM    @charges
    UNION ALL
    SELECT  code
    ,       amount
    ,       (
            SELECT  amount AS [@amount]
            FROM    @surcharges os
            WHERE   oc.ChargeId = os.ChargeId
            FOR XML PATH('surcharge'), TYPE
            )
    ,       InvoiceId
    FROM    @charges oc
)
SELECT  Number AS [@number]
,       c.code as [charge/@code]
,       c.rate as [charge/@rate]
,       c.surcharge as [charge]
FROM    @Invoices i
outer apply
        (
        SELECT  code
        ,       rate
        ,       surcharge
        FROM    Charges
        WHERE   Charges.InvoiceId = i.InvoiceId
        ) c
WHERE   i.InvoiceID = 1
FOR XML PATH( 'invoice' ), TYPE
这将打印,例如:

<invoice number="1">
  <charge code="1" rate="1" />
</invoice>
<invoice number="1">
  <charge code="1" rate="1">
    <surcharge amount="1" />
  </charge>
</invoice>


第一个元素来自联合体的顶部,其中
assemployment=null

似乎将(假)列命名为“*”将使用该列的内容作为元素的内容,因此按以下方式更改SQL使其工作:

WITH Charges ( [@code], [@rate], surcharge, InvoiceId ) AS (
    SELECT code AS [@Code], amount AS [@rate], NULL as surcharge, InvoiceId
    FROM item.charges
UNION ALL
    SELECT 
        code AS [@Code], 
        amount AS [@rate],
        (
             SELECT amount AS [@amount]
             FROM order.surcharges os
             WHERE oc.ChargeId = os.ChargeId
             FOR XML PATH('surcharge'), TYPE
        ), 
        InvoiceId
    FROM order.charges oc
)
SELECT
    Number AS [@number],
    (
         SELECT
             [@code],
             [@rate],
             surcharge AS [*] -- Thsi will embed the contents of the previously generated XML in here.
         FROM Charges
         WHERE Charges.InvoiceId = i.InvoiceId
    )
FROM Invoices i
FOR XML PATH( 'invoice' ), TYPE

这就产生了一个错误:“行标记省略(空行标记名称)不能与以属性为中心的XML序列化一起使用。”+1附加费是由位于联合体顶部的
NULL作为附加费隐式添加的,因此路径('surgcharge')看起来是重复的。我对该错误感到困惑。如果按照我建议的方式在联合体中使用“for xml”子句单独运行第二个select,会发生什么情况?如果子查询没有引入EXISTS,则select列表中只能指定一个表达式。@user3752281该解决方案对我有效,因此我不理解您的评论?
<invoice number="1">
  <charge code="1" rate="1" />
</invoice>
<invoice number="1">
  <charge code="1" rate="1">
    <surcharge amount="1" />
  </charge>
</invoice>
WITH Charges ( [@code], [@rate], surcharge, InvoiceId ) AS (
    SELECT code AS [@Code], amount AS [@rate], NULL as surcharge, InvoiceId
    FROM item.charges
UNION ALL
    SELECT 
        code AS [@Code], 
        amount AS [@rate],
        (
             SELECT amount AS [@amount]
             FROM order.surcharges os
             WHERE oc.ChargeId = os.ChargeId
             FOR XML PATH('surcharge'), TYPE
        ), 
        InvoiceId
    FROM order.charges oc
)
SELECT
    Number AS [@number],
    (
         SELECT
             [@code],
             [@rate],
             surcharge AS [*] -- Thsi will embed the contents of the previously generated XML in here.
         FROM Charges
         WHERE Charges.InvoiceId = i.InvoiceId
    )
FROM Invoices i
FOR XML PATH( 'invoice' ), TYPE