循环数据和XML输出

时间:2016-11-21 17:13:05

标签: xml tsql

我需要以下列XML格式从表中导出数据:

<studentid="000011111">
    <academic_goal type="official">
      <program_group>
        <program type="catalog">2014-16</program>
        <program type="degree">BS</program>
        <program type="major">PS</program>
        <program type="concentration">PCC</program>
      </program_group>
      <program_group>
        <program type="catalog">2014-16</program>
        <program type="degree">BS</program>
        <program type="minor">HI</program>
      </program_group>
    </academic_goal>
</studentid>

到目前为止我所拥有的是:

<studentid="000011111">
    <academic_goal type="official">
      <program_group>
        <program type="catalog">2014-16</program>
        <program type="degree">BS</program>
        <program type="major">PS</program>
        <program type="minor">HI</program>
        <program type="concentration">PCC</program>
      </program_group>
    </academic_goal>
</studentid>

如何循环显示此信息,以便未成年人在自己的program_group标记内(以及目录和学位)?

这是表结构:

CREATE TABLE [dbo].[StudentProgramData](
    [StudentID] [nvarchar](10) NULL,
    [Catalog] [nvarchar](10) NULL,
    [Degree] [nvarchar](10) NULL,
    [Major] [nvarchar](50) NULL,
    [Minor] [nvarchar](50) NULL,
    [Concentration] [nvarchar](50) NULL)

示例数据:

insert into StudentProgramData
values 
('000011111', '2014-16', 'BS', 'PS', 'HI', 'PCC'),
('000022222', '2012-14', 'BA', 'MK', 'BI', 'ESO'),
('000033333', '2012-14', 'BS', 'MB', NULL, 'AUE'),
('000044444', '2014-16', 'ME', 'PS', 'HI', NULL),
('000055555', '2010-12', 'MD', 'PS', NULL, 'PCC')

我收录了5个样本记录,但上面的输出只显示了第一个学生。

到目前为止我的循环代码是:

(select
    ltrim(rtrim(StudentProgramData.catalog)) as [program/@catalog],
    ltrim(rtrim(StudentProgramData.degree)) as [program/@degree],
    ltrim(rtrim(StudentProgramData.major)) as [program/@major],
    ltrim(rtrim(StudentProgramData.minor)) as [program/@minor],
    ltrim(rtrim(StudentProgramData.concentration)) as [program/@concentration]

    from StudentProgramData

for xml path('program'), type).query('
   <academic_goal type="official">
   {
     for $program in /program
         return
            <program_group>
               {$program/Name}
                <program type="catalog">{data($program/program/@year)}</program>
                <program type="degree">{data($program/program/@degree)}</program>
                <program type="major">{data($program/program/@major)}</program>
                <program type="minor">{data($program/program/@minor)}</program>
                <program type="concentration">{data($program/program/@concentration)}</program>
            </program_group>
   }
   </academic_goal>')

非常感谢您提供的任何帮助。

3 个答案:

答案 0 :(得分:2)

另一种方法是为每个程序组创建派生表/ unpivot。

select SPD.StudentID as '@id',
       (
       select 'official' as '@type',
              (
              select V.Type as '@type',
                     V.Value as '*'
              from (values('catalog', SPD.Catalog),
                          ('degree', SPD.Degree),
                          ('major', SPD.Major),
                          ('concentration', SPD.Concentration)) as V(Type, Value)
              for xml path('program'), root('program_group'), type
              ),
              (
              select V.Type as '@type',
                     V.Value as '*'
              from (values('catalog', SPD.Catalog),
                          ('degree', SPD.Degree),
                          ('minor', SPD.Minor)) as V(Type, Value)
              for xml path('program'), root('program_group'), type
              )
        for xml path('academic_goal'), type
       )
from dbo.StudentProgramData as SPD
for xml path('student');

答案 1 :(得分:1)

我很确定有人会因为想出一些如此迂回的东西而打我的手腕(@Shnugo,你在哪里?),但这就是我得到的。它可能不是最好的,毫无疑问,有人会给你一个更好的答案。但这是你可以在此期间使用的东西。

SELECT
    studentId AS [student/@id],
    'official' AS [student/academic_goal/@type],
    (
        SELECT
            (
                SELECT
                    'catalog' AS [program/@type],
                    ltrim(rtrim(catalog)) AS [program]
                FOR XML
                    PATH(''), TYPE
            ),
            (
                SELECT
                    'degree' AS [program/@type],
                    ltrim(rtrim(degree)) AS [program]
                FOR XML
                    PATH(''), TYPE
            ),
            (
                SELECT
                    'major' AS [program/@type],
                    ltrim(rtrim(major)) AS [program]
                FOR XML
                    PATH(''), TYPE
            ),
            (
                SELECT
                    'concentration' AS [program/@type],
                    ltrim(rtrim(concentration)) AS [program]
                FOR XML
                    PATH(''), TYPE
            )
        FOR XML 
            PATH('program_group'), TYPE
    ) AS [student/academic_goal],
    (
        SELECT
            (
                SELECT
                    'catalog' AS [program/@type],
                    ltrim(rtrim(catalog)) AS [program]
                FOR XML
                    PATH(''), TYPE
            ),
            (
                SELECT
                    'degree' AS [program/@type],
                    ltrim(rtrim(degree)) AS [program]
                FOR XML
                    PATH(''), TYPE
            ),
            (
                SELECT
                    'minor' AS [program/@type],
                    ltrim(rtrim(minor)) AS [program]
                FOR XML
                    PATH(''), TYPE
            )
        FOR XML 
            PATH('program_group'), TYPE
    ) AS [student/academic_goal]
FROM
    StudentProgramData
FOR XML 
    PATH(''), ROOT('students');

产地:

<students>
  <student id="000011111">
    <academic_goal type="official">
      <program_group>
        <program type="catalog">2014-16</program>
        <program type="degree">BS</program>
        <program type="major">PS</program>
        <program type="concentration">PCC</program>
      </program_group>
      <program_group>
        <program type="catalog">2014-16</program>
        <program type="degree">BS</program>
        <program type="minor">HI</program>
      </program_group>
    </academic_goal>
  </student>
  <student id="000022222">
    <academic_goal type="official">
      <program_group>
        <program type="catalog">2012-14</program>
        <program type="degree">BA</program>
        <program type="major">MK</program>
        <program type="concentration">ESO</program>
      </program_group>
      <program_group>
        <program type="catalog">2012-14</program>
        <program type="degree">BA</program>
        <program type="minor">BI</program>
      </program_group>
    </academic_goal>
  </student>
  <student id="000033333">
    <academic_goal type="official">
      <program_group>
        <program type="catalog">2012-14</program>
        <program type="degree">BS</program>
        <program type="major">MB</program>
        <program type="concentration">AUE</program>
      </program_group>
      <program_group>
        <program type="catalog">2012-14</program>
        <program type="degree">BS</program>
        <program type="minor" />
      </program_group>
    </academic_goal>
  </student>
  <student id="000044444">
    <academic_goal type="official">
      <program_group>
        <program type="catalog">2014-16</program>
        <program type="degree">ME</program>
        <program type="major">PS</program>
        <program type="concentration" />
      </program_group>
      <program_group>
        <program type="catalog">2014-16</program>
        <program type="degree">ME</program>
        <program type="minor">HI</program>
      </program_group>
    </academic_goal>
  </student>
  <student id="000055555">
    <academic_goal type="official">
      <program_group>
        <program type="catalog">2010-12</program>
        <program type="degree">MD</program>
        <program type="major">PS</program>
        <program type="concentration">PCC</program>
      </program_group>
      <program_group>
        <program type="catalog">2010-12</program>
        <program type="degree">MD</program>
        <program type="minor" />
      </program_group>
    </academic_goal>
  </student>
</students>

答案 2 :(得分:1)

您的格式很棘手的是使用了许多具有相同名称<program>的节点。由于引擎需要首先构建属性,因此无法再添加值,然后再将属性添加到相同节点。引擎至少这么认为。

技巧:在两者之间添加一个空元素。这将告诉引擎,最后一个要关闭。试试这样:

SELECT StudentID AS [@id]
      ,(
        SELECT 'official' AS [@type]
              ,(
                    SELECT 'catalog' AS [program/@type] 
                          ,spd.[Catalog] AS [program]
                          ,''
                          ,'degree' AS [program/@type] 
                          ,spd.[Degree] AS [program]
                          ,''
                          ,'major' AS [program/@type] 
                          ,spd.[Major] AS [program]
                          ,''
                          ,'concentration' AS [program/@type] 
                          ,spd.[Concentration] AS [program]
                    FOR XML PATH('program_group'),TYPE
               )
              ,(
                    SELECT 'catalog' AS [program/@type] 
                          ,spd.[Catalog] AS [program]
                          ,''
                          ,'degree' AS [program/@type] 
                          ,spd.[Degree] AS [program]
                          ,''
                          ,'minor' AS [program/@type] 
                          ,spd.[Minor] AS [program]
                    FOR XML PATH('program_group'),TYPE
               )
        FROM StudentProgramData AS spd
        WHERE s.StudentID=spd.StudentID
        FOR XML PATH('academic_goal'),TYPE
       )
FROM StudentProgramData AS s
FOR XML PATH('student')--,ROOT('root') --Do you need a root node? Probably yes, if more than 1 student...