写 SQL 开发 XML 用 children

Writing SQL to develop XML with children

我正在尝试编写 SQL 以生成包含 child 元素的 XML 字符串。我可以获得所有内容,但 children 并没有像 children 那样下降,它们显示为单独的根级项目。我一直在研究 XML 路径语句,但就是运气不好。

不胜感激。我在 SQL 2014 服务器上。

declare @xmldata xml
set     @xmldata = (    SELECT adr.ACCOUNT_IDENTIFIER   
                            , adr.FIRST_NAME
                            , adr.LAST_NAME
                            , adr.ADDR_LINE1
                            , adr.ADDR_LINE2
                            , adr.CITY
                            , adr.STATE
                            , adr.ZIP
                            , ( SELECT ACCT_NBR
                                    , LOAN_ORGL_PRIN_AMT
                                    , LOAN_OSTD_PRIN_AMT
                                    , LOAN_EFTV_INT_RT 
                                FROM Staging.StatementOfBalance_SRC sob
                                WHERE  sob.ACCT_NBR = crbr.ACCT_NBR 
                                FOR XML path('accounts'), TYPE, elements )
                        from Staging.Account_Data crbr
                        join Unit_Cost.ADDRESSES_ALL adr on crbr.ACCOUNT_IDENTIFIER = adr.ACCOUNT_IDENTIFIER    
                        FOR XML path('letter'), root ('statement'), elements    )

SELECT @xmldata as returnXML

我的成绩是

<statement>
    <letter>
        <ACCOUNT_IDENTIFIER>123321</ACCOUNT_IDENTIFIER>
        <FIRST_NAME>Pippi</FIRST_NAME>
        <LAST_NAME>Longstockings</LAST_NAME>
        <ADDR_LINE1>123 Out Onna Boat</ADDR_LINE1>
        <ADDR_LINE2 />
        <CITY>Ocean</CITY>
        <STATE>ME</STATE>
        <ZIP>000000</ZIP>
        <accounts>
            <ACCT_NBR>0000000000000000</ACCT_NBR>
            <LOAN_ORGL_PRIN_AMT>2670.00</LOAN_ORGL_PRIN_AMT>
            <LOAN_OSTD_PRIN_AMT>2749.09</LOAN_OSTD_PRIN_AMT>
            <LOAN_EFTV_INT_RT>4.75000</LOAN_EFTV_INT_RT>
        </accounts>
    </letter>
    <letter>
        <ACCOUNT_IDENTIFIER>123321</ACCOUNT_IDENTIFIER>
        <FIRST_NAME>Pippi</FIRST_NAME>
        <LAST_NAME>Longstockings</LAST_NAME>
        <ADDR_LINE1>123 Out Onna Boat</ADDR_LINE1>
        <ADDR_LINE2 />
        <CITY>Ocean</CITY>
        <STATE>ME</STATE>
        <ZIP>000000</ZIP>
        <accounts>
            <ACCT_NBR>0000000000000000</ACCT_NBR>
            <LOAN_ORGL_PRIN_AMT>4082.00</LOAN_ORGL_PRIN_AMT>
            <LOAN_OSTD_PRIN_AMT>5520.21</LOAN_OSTD_PRIN_AMT>
            <LOAN_EFTV_INT_RT>5.50000</LOAN_EFTV_INT_RT>
        </accounts>
    </letter>
</statement>

但我需要的是:

 <statement>
        <letter>
            <ACCOUNT_IDENTIFIER>123321</ACCOUNT_IDENTIFIER>
            <FIRST_NAME>Pippi</FIRST_NAME>
            <LAST_NAME>Longstockings</LAST_NAME>
            <ADDR_LINE1>123 Out Onna Boat</ADDR_LINE1>
            <ADDR_LINE2 />
            <CITY>Ocean</CITY>
            <STATE>ME</STATE>
            <ZIP>000000</ZIP>
            <accounts>
                <ACCT_NBR>0000000000000000</ACCT_NBR>
                <LOAN_ORGL_PRIN_AMT>2670.00</LOAN_ORGL_PRIN_AMT>
                <LOAN_OSTD_PRIN_AMT>2749.09</LOAN_OSTD_PRIN_AMT>
                <LOAN_EFTV_INT_RT>4.75000</LOAN_EFTV_INT_RT>
            </accounts>
            <accounts>
                <ACCT_NBR>0000000000000000</ACCT_NBR>
                <LOAN_ORGL_PRIN_AMT>4082.00</LOAN_ORGL_PRIN_AMT>
                <LOAN_OSTD_PRIN_AMT>5520.21</LOAN_OSTD_PRIN_AMT>
                <LOAN_EFTV_INT_RT>5.50000</LOAN_EFTV_INT_RT>
            </accounts>
        </letter>
    </statement>

我想,问题是你在外层加入了SELECT...你没有提供你的结构,也没有提供样本数据...

你的实际输出在你想要的时候将主行加​​倍 - 至少预期输出指向这一点 - 字母和帐户之间的 1:n 关系。

我试图简化您的查询并声明 tables 适合查询,但去掉了连接的 table 并且输出似乎没问题:

DECLARE @letter TABLE(ACCOUNT_IDENTIFIER INT,FIRST_NAME VARCHAR(100),LAST_NAME VARCHAR(100));
INSERT INTO @letter VALUES(123321,'Pippi','Longstockings');
DECLARE @account TABLE(ACCOUNT_IDENTIFIER INT,ACCT_NBR VARCHAR(100), LOAN_ORGL_PRIN_AMT DECIMAL (14,4));
INSERT INTO @account VALUES(123321,'00000000000',2670.00),(123321,'00000000000',4082.00);

SELECT 
      adr.ACCOUNT_IDENTIFIER   
    , adr.FIRST_NAME
    , adr.LAST_NAME
    --, adr.ADDR_LINE1
    --, adr.ADDR_LINE2
    --, adr.CITY
    --, adr.STATE
    --, adr.ZIP
    , ( SELECT ACCT_NBR
            , LOAN_ORGL_PRIN_AMT
            --, LOAN_OSTD_PRIN_AMT
            --, LOAN_EFTV_INT_RT 
        FROM @account sob -- Staging.StatementOfBalance_SRC sob
        WHERE  sob.ACCOUNT_IDENTIFIER = adr.ACCOUNT_IDENTIFIER-- crbr.ACCT_NBR 
        FOR XML path('accounts'), TYPE, elements )
from @letter adr --Staging.Account_Data crbr
                 --join Unit_Cost.ADDRESSES_ALL adr on crbr.ACCOUNT_IDENTIFIER = adr.ACCOUNT_IDENTIFIER    
FOR XML path('letter'), root ('statement') 

结果

<statement>
  <letter>
    <ACCOUNT_IDENTIFIER>123321</ACCOUNT_IDENTIFIER>
    <FIRST_NAME>Pippi</FIRST_NAME>
    <LAST_NAME>Longstockings</LAST_NAME>
    <accounts>
      <ACCT_NBR>00000000000</ACCT_NBR>
      <LOAN_ORGL_PRIN_AMT>2670.0000</LOAN_ORGL_PRIN_AMT>
    </accounts>
    <accounts>
      <ACCT_NBR>00000000000</ACCT_NBR>
      <LOAN_ORGL_PRIN_AMT>4082.0000</LOAN_ORGL_PRIN_AMT>
    </accounts>
  </letter>
</statement>

所以我的建议是:

在没有 FOR XML PATH 的情况下测试这个 并从外到内。首先你应该对

感到满意
<statement>
  <letter>
    <ACCOUNT_IDENTIFIER>123321</ACCOUNT_IDENTIFIER>
    <FIRST_NAME>Pippi</FIRST_NAME>
    <LAST_NAME>Longstockings</LAST_NAME>
    --more columns
  </letter>
</statement>

当这有效时,您定义子select 以添加适当的帐户。您的查询实际上看起来还不错,所以我怀疑您的 table 关系中的原因没有按照您预期的方式产生...