FOR XML PATH - 动态节点?

时间:2014-10-29 17:38:32

标签: sql xml

我有这个样本表。

rate_id | ACCOUNT_ID |定义|类别| pmpm_override |量

1 | A1 | PSPM | C1 |空| 100

2 | A1 | PSPM | C2 |空| 200

3 | A1 | PC | C3 |空| 150

4 | A1 | PC | C4 |空| 250

5 | A2 | PMPM | C5 | TRUE | 400

6 | A2 | PMPM | C3 | TRUE | 500

7 | A3 | PMPM | C2 | FALSE | 600

问题集中在'定义' column作为其值确定元素category,amount和pmpm_override所在的节点名称。

例如,当定义= PSPM时,节点是pspmrate,当定义= PC节点是pcrate等时。

使用FOR XML PATH我希望返回以下内容:

<?xml version="1.0" encoding="utf-8"?>
<Rates>
    <rate_id id="1">
    <account_id>a1</account_id>
    <pspmrate>
        <category>c1</category>
        <amount>100</amount>
    </pspmrate>
    </rate_id>
    <rate_id id="2">
    <account_id>a1</account_id>
    <pspmrate>
        <category>c2</category>
        <amount>200</amount>
    </pspmrate>
    </rate_id>
    <rate_id id="3">
    <account_id>a1</account_id>
    <pcrate>
        <category>c3</category>
        <amount>150</amount>        
    </pcrate>
    </rate_id>
    <rate_id id="4">
    <account_id>a1</account_id>
    <pcrate>
        <category>c4</category>
        <amount>250</amount>        
    </pcrate>
    </rate_id>
    <rate_id id="5">
    <account_id>a2</account_id>
    <pmpmrate>
        <category>c5</category>
        <amount>400</amount>        
        <pmpm_override>true</pmpm_override>
    </pmpmrate>
    </rate_id>
    <rate_id id="6">
    <account_id>a2</account_id>
    <pmpmrate>
        <category>c3</category>
        <amount>500</amount>        
        <pmpm_override>true</pmpm_override>
    </pmpmrate>
    </rate_id>
    <rate_id id="7">
    <account_id>a3</account_id>
    <pmpmrate>
        <category>c2</category>
        <amount>600</amount>        
        <pmpm_override>false</pmpm_override>
    </pmpmrate>
    </rate_id>
</Rates>

现在我有一个查询返回正确的结构减去节点名称(我用FOR XML PATH(&#39; pspmrate&#39;)硬编码了这个)所以速率ids 3-7有错误节点

实际上查询代码要大得多,结构有点复杂但是这个样本代表了我正在寻找的东西 - 我想有办法用动态sql执行此操作但是我&#39 ;如果可能的话,我试图避免工作和排除大量查询字符串。

我想我正在寻找一种动态确定XML PATH的方法。

任何建议都表示赞赏。

感谢。

1 个答案:

答案 0 :(得分:0)

如果您有一个已知数量的定义,我认为您可以使用案例表达式执行此操作:

SELECT  [@id] = rate_id,
        account_id,
        CASE definition
            WHEN 'PC' THEN (SELECT pmpm_override, amount, category FOR XML PATH('pcrate'), TYPE)
            WHEN 'PMPM' THEN (SELECT pmpm_override, amount, category FOR XML PATH('pmpmrate'), TYPE) 
            WHEN 'PSPM' THEN (SELECT pmpm_override, amount, category FOR XML PATH('pspmrate'), TYPE)
        END
FROM    T
FOR XML PATH('rate_id'), ROOT('rates');

如果没有,则需要动态sql来构建案例表达式:

DECLARE @SQL NVARCHAR(MAX);
SELECT  @SQL = 'SELECT  [@id] = rate_id,
                        account_id,
                        CASE definition
                            ' + (SELECT 'WHEN ''' + Definition + 
                                        ''' THEN (SELECT pmpm_override, amount, category FOR XML PATH(''' + 
                                        LOWER(Definition) + 'rate''), TYPE) '
                                FROM    T
                                GROUP BY Definition
                                FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') + '
                        END
                FROM    T
                FOR XML PATH(''rate_id''), ROOT(''rates'');';

EXECUTE sp_executesql @SQL;