从 SQL 服务器中的 XML 读取子节点及其父属性
Read child node along with its parent attribute from XML in SQL server
我有一个XML类似于这个结构。
<Root>
<id>a2bh5</id>
<Student ID="123">
<Name>abc<Name>
<course>ETL<course>
<Scores>
<Score>
<Subject>SSIS<subject>
<grade>B<grade>
</score>
<Score>
<Subject>Informatica<subject>
<grade>C<grade>
</score>
</Scores>
</Student>
<Student ID="456">
<Name>xyz<Name>
<course>ETL<course>
<Scores>
<Score>
<Subject>Pentaho<subject>
<grade>F<grade>
</score>
<Score>
<Subject>Datastage<subject>
<grade>A<grade>
</score>
</Scores>
</Student>
</Root>
我想在 SQL 服务器中使用 Xquery 从子节点(分数)及其父属性(Id)获取详细信息。
所有主题的查询结果预计如下所示。请帮忙。
Student_Id subject grade
========================
123 SSIS B
首先,您需要修复 XML。您的 Name
、course
、Subject
和 grade
元素没有正确的结束标记。此外,元素名称在 XML 中区分大小写; Subject
和 subject
不是一回事。
完成后,您可以使用 nodes()
method 将 XML 分成行,然后提取所需的数据。像这样:
declare @test xml =
'<Root>
<id>a2bh5</id>
<Student ID="123">
<Name>abc</Name>
<course>ETL</course>
<Scores>
<Score>
<Subject>SSIS</Subject>
<grade>B</grade>
</Score>
<Score>
<Subject>Informatica</Subject>
<grade>C</grade>
</Score>
</Scores>
</Student>
<Student ID="456">
<Name>xyz</Name>
<course>ETL</course>
<Scores>
<Score>
<Subject>Pentaho</Subject>
<grade>F</grade>
</Score>
<Score>
<Subject>Datastage</Subject>
<grade>A</grade>
</Score>
</Scores>
</Student>
</Root>';
select
[Student ID] = N.x.value('(../../@ID)[1]', 'bigint'),
[Subject] = N.x.value('(./Subject)[1]', 'varchar(64)'),
[Grade] = N.x.value('(./grade)[1]', 'char(1)')
from
@test.nodes('/Root/Student/Scores/Score') N(x)
结果:
Student ID Subject Grade
---------------------------------
123 SSIS B
123 Informatica C
456 Pentaho F
456 Datastage A
清理样本 XML 并正确关闭所有标签后,试试这个:
DECLARE @input XML = '<Root>
<id>a2bh5</id>
<Student ID="123">
<Name>abc</Name>
<course>ETL</course>
<Scores>
<Score>
<Subject>SSIS</Subject>
<grade>B</grade>
</Score>
<Score>
<Subject>Informatica</Subject>
<grade>C</grade>
</Score>
</Scores>
</Student>
<Student ID="456">
<Name>xyz</Name>
<course>ETL</course>
<Scores>
<Score>
<Subject>Pentaho</Subject>
<grade>F</grade>
</Score>
<Score>
<Subject>Datastage</Subject>
<grade>A</grade>
</Score>
</Scores>
</Student>
</Root>'
SELECT
StudentID = XStudents.value('@ID', 'int'),
Course = XStudents.value('(course)[1]', 'varchar(50)'),
Subject = XScore.value('(Subject)[1]', 'varchar(50)'),
Grade = XScore.value('(grade)[1]', 'varchar(10)')
FROM
@Input.nodes('/Root/Student') AS XT1(XStudents)
CROSS APPLY
XStudents.nodes('Scores/Score') AS XT2(XScore)
这给出了输出:
我有一个XML类似于这个结构。
<Root>
<id>a2bh5</id>
<Student ID="123">
<Name>abc<Name>
<course>ETL<course>
<Scores>
<Score>
<Subject>SSIS<subject>
<grade>B<grade>
</score>
<Score>
<Subject>Informatica<subject>
<grade>C<grade>
</score>
</Scores>
</Student>
<Student ID="456">
<Name>xyz<Name>
<course>ETL<course>
<Scores>
<Score>
<Subject>Pentaho<subject>
<grade>F<grade>
</score>
<Score>
<Subject>Datastage<subject>
<grade>A<grade>
</score>
</Scores>
</Student>
</Root>
我想在 SQL 服务器中使用 Xquery 从子节点(分数)及其父属性(Id)获取详细信息。
所有主题的查询结果预计如下所示。请帮忙。
Student_Id subject grade
========================
123 SSIS B
首先,您需要修复 XML。您的 Name
、course
、Subject
和 grade
元素没有正确的结束标记。此外,元素名称在 XML 中区分大小写; Subject
和 subject
不是一回事。
完成后,您可以使用 nodes()
method 将 XML 分成行,然后提取所需的数据。像这样:
declare @test xml =
'<Root>
<id>a2bh5</id>
<Student ID="123">
<Name>abc</Name>
<course>ETL</course>
<Scores>
<Score>
<Subject>SSIS</Subject>
<grade>B</grade>
</Score>
<Score>
<Subject>Informatica</Subject>
<grade>C</grade>
</Score>
</Scores>
</Student>
<Student ID="456">
<Name>xyz</Name>
<course>ETL</course>
<Scores>
<Score>
<Subject>Pentaho</Subject>
<grade>F</grade>
</Score>
<Score>
<Subject>Datastage</Subject>
<grade>A</grade>
</Score>
</Scores>
</Student>
</Root>';
select
[Student ID] = N.x.value('(../../@ID)[1]', 'bigint'),
[Subject] = N.x.value('(./Subject)[1]', 'varchar(64)'),
[Grade] = N.x.value('(./grade)[1]', 'char(1)')
from
@test.nodes('/Root/Student/Scores/Score') N(x)
结果:
Student ID Subject Grade
---------------------------------
123 SSIS B
123 Informatica C
456 Pentaho F
456 Datastage A
清理样本 XML 并正确关闭所有标签后,试试这个:
DECLARE @input XML = '<Root>
<id>a2bh5</id>
<Student ID="123">
<Name>abc</Name>
<course>ETL</course>
<Scores>
<Score>
<Subject>SSIS</Subject>
<grade>B</grade>
</Score>
<Score>
<Subject>Informatica</Subject>
<grade>C</grade>
</Score>
</Scores>
</Student>
<Student ID="456">
<Name>xyz</Name>
<course>ETL</course>
<Scores>
<Score>
<Subject>Pentaho</Subject>
<grade>F</grade>
</Score>
<Score>
<Subject>Datastage</Subject>
<grade>A</grade>
</Score>
</Scores>
</Student>
</Root>'
SELECT
StudentID = XStudents.value('@ID', 'int'),
Course = XStudents.value('(course)[1]', 'varchar(50)'),
Subject = XScore.value('(Subject)[1]', 'varchar(50)'),
Grade = XScore.value('(grade)[1]', 'varchar(10)')
FROM
@Input.nodes('/Root/Student') AS XT1(XStudents)
CROSS APPLY
XStudents.nodes('Scores/Score') AS XT2(XScore)
这给出了输出: