使用xml将数据分解为表

时间:2013-10-10 19:36:11

标签: sql sql-server xml

我正在学习XML / SQL并且有以下问题。我想将XML数据分解成表格。但我的问题是:我有很多作者在同一书籍类别中使用相同的标签(<author>)。我想选择所有的作者,但我无法实现这一点。你能帮我做一下吗?

结果如下:

category    title              author             author1        author2
=============================================================================
CHILDREN    Harry Potter       J K. Rowling       NULL           NULL
WEB         XQuery Kick Start  James McGovern     Per Bothner    Kurt Cagle

代码:

declare @int int
declare @var xml = '<?xml version="1.0" encoding="ISO-8859-1"?>
 <bookstore>

 <book category="CHILDREN">
   <title lang="en">Harry Potter</title>
   <author>J K. Rowling</author>
   <year>2005</year>
   <price>29.99</price>
 </book>

 <book category="WEB">
   <title lang="en">XQuery Kick Start</title>
   <author>James McGovern</author>
   <author>Per Bothner</author>
   <author>Kurt Cagle</author>
   <year>2003</year>
   <price>49.99</price>
 </book>

 </bookstore>';

EXEC sp_xml_preparedocument @int OUTPUT, @var


SELECT
*
into MyTable
FROM
OPENXML(@int, 'bookstore/book', 11)
with
(
category varchar(100),
title varchar(100),
author varchar(100)
author1 varchar(100),
author2 varchar(100)
);

2 个答案:

答案 0 :(得分:2)

如果您知道您将永远不会超过3位作者,您可以使用以下内容:

SELECT
    XBook.value('@category', 'varchar(20)'),
    XBook.value('(title)[1]', 'varchar(50)'),
    XBook.value('(year)[1]', 'int'),
    XBook.value('(price)[1]', 'decimal(10,2)'),
    XBook.value('(author)[1]', 'varchar(50)'),
    XBook.value('(author)[2]', 'varchar(50)'),
    XBook.value('(author)[3]', 'varchar(50)')
FROM 
    @var.nodes('/bookstore/book') AS XTbl(XBook)

我个人觉得使用原生XQuery支持比旧的笨重的 OPENXML方法更容易(它也遭受了内存泄漏和其他缺陷)。

这会给你一个这样的输出:

enter image description here

答案 1 :(得分:0)

这是一种方式......

SELECT
*
into MyTable
FROM
OPENXML(@int, 'bookstore/book', 11)
with
(
category varchar(100) '@category',
title varchar(100) 'title',
author varchar(100) 'author[1]',
author1 varchar(100) 'author[2]',
author2 varchar(100) 'author[3]'
);

这是另一种方式,具有不同的结构。

SELECT
*
into MyTable
FROM
OPENXML(@int, 'bookstore/book/author', 11)
with
(
category varchar(100) '../@category',
title varchar(100) '../title',
author varchar(100) '.'
);

请注意,当您使用第二种方法时,您将获得包含样本数据的4行,因为第一本书有1位作者,而第二本书有3位作者。请注意,我更改了OPENXML行以在层次结构中向下开始。