0

我正在学习 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)
);
4

2 回答 2

2

If you know that you'll never have more than 3 authors, you can use something like this:

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)

I personally find using the native XQuery support much easier than the old, clunky OPENXML approach (which also suffered from memory leaks and other deficiencies).

This gives you an output like this:

enter image description here

于 2013-10-10T19:47:29.013 回答
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 行更改为在层次结构中更靠下一点。

于 2013-10-10T19:43:23.713 回答