SQL层次结构字符串列到XML

时间:2018-08-10 18:08:59

标签: sql xml hierarchy

尝试将SQL中的层次结构字符串列转换为XML并输出XML

我有这个...

    HIERARCHY_Column                                                  VALUE_Column
    Header_1 > Question_A                                             Answer_A
    Header_1 > Subheader_1 > Question_B                               Answer_B
    Header_1 > Subheader_2 > Question_C                               Answer_C
    Header_1 > Subheader_2 > Subheader_3 > Question_D                 Answer_D
    Header_1 > Subheader_4 > Subheader_5 > Question_E                 Answer_E
    Header_1 > Subheader_4 > Subheader_5 > Question_F                 Answer_F
    Header_1 > Subheader_6 > Subheader_7 > Subheader_8  > Question_G  Answer_G
    Header_1 > Subheader_6 > Subheader_7 > Subheader_9  > Question_H  Answer_H

我想要这个输出

<Header_1>
  <Question_A>Answer_A</Question_A>
  <SubHeader_1>
      <Question_B>Answer_B</Question_B>
  </SubHeader_1>
  <SubHeader_2>
      <Question_C>Answer_C</Question_C>
      <SubHeader_3>
          <Question_D>Answer_D</Question_D>
      </SubHeader_3>    
  </SubHeader_2>
  <SubHeader_4>
      <SubHeader_5>
          <Question_E>Answer_E</Question_E>
          <Question_F>Answer_F</Question_F>
      </SubHeader_5>    
  </SubHeader_4>
  <SubHeader_6>
    <SubHeader_7>
        <SubHeader_8>
            <Question_G>Answer_G</Question_G>
            <Question_H>Answer_H</Question_H>
        </SubHeader_8>
    </SubHeader_7>  
  </SubHeader_6>
</Header_1>

数据是动态的,因此子标题的位置和数量每天每行都会更改。因此,上面的示例的结构将根据回答的每个问题而针对每个标头进行更改。

1 个答案:

答案 0 :(得分:0)

那呢?

DECLARE @tbl TABLE(ID INT IDENTITY, HierarchyColumn VARCHAR(1000),Content VARCHAR(100));
INSERT INTO @tbl VALUES('Header_1 > Question_A','Answer_A')
                      ,('Header_1 > Subheader_1 > Question_B','Answer_B')
                      ,('Header_1 > Subheader_2 > Question_C','Answer_C')
                      ,('Header_1 > Subheader_2 > Subheader_3 > Question_D','Answer_D')
                      ,('Header_1 > Subheader_4 > Subheader_5 > Question_E','Answer_E')
                      ,('Header_1 > Subheader_4 > Subheader_5 > Question_F','Answer_F')
                      ,('Header_1 > Subheader_6 > Subheader_7 > Subheader_8  > Question_G','Answer_G')
                      ,('Header_1 > Subheader_6 > Subheader_7 > Subheader_9  > Question_H','Answer_H');

DECLARE @stmt VARCHAR(MAX)=' SELECT '
+ STUFF(
        (
            SELECT ',''' + t.Content + ''' AS ' + QUOTENAME(REPLACE(REPLACE(t.HierarchyColumn,' ',''),'>','/'))
            FROM @tbl t 
            ORDER BY ID
            FOR XML PATH('')
        ),1,1,'') + ' FOR XML PATH('''')';

EXEC( @stmt);

诀窍是动态创建此语句并使用EXEC()执行它:

 SELECT 'Answer_A' AS [Header_1/Question_A]
       ,'Answer_B' AS [Header_1/Subheader_1/Question_B]
       ,'Answer_C' AS [Header_1/Subheader_2/Question_C]
       ,'Answer_D' AS [Header_1/Subheader_2/Subheader_3/Question_D]
       ,'Answer_E' AS [Header_1/Subheader_4/Subheader_5/Question_E]
       ,'Answer_F' AS [Header_1/Subheader_4/Subheader_5/Question_F]
       ,'Answer_G' AS [Header_1/Subheader_6/Subheader_7/Subheader_8/Question_G]
       ,'Answer_H' AS [Header_1/Subheader_6/Subheader_7/Subheader_9/Question_H] 
FOR XML PATH('')

缺点可能是,您必须依赖某种排序顺序。我使用ID,按您的层次结构列排序(字母数字)可能就足够了。

任何其他方法都将变得相当棘手...如果这对您没有帮助,请回来。