【问题标题】:shred data into table by using xml使用 xml 将数据切碎到表中
【发布时间】:2013-10-11 13:34:47
【问题描述】:

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

【问题讨论】:

  • obs:我是 Stackoverflow 的新手,所以我不知道如何正确格式化我的结果表。对此我感到很抱歉。
  • 我不知道“将数据分解成表格”这个词是什么意思。

标签: sql sql-server xml


【解决方案1】:

如果您知道您永远不会拥有超过 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 方法(也存在内存泄漏和其他缺陷)容易得多。

这会给你这样的输出:

【讨论】:

    【解决方案2】:

    这是一种方式...

    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 行更改为在层次结构中进一步向下开始。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-19
      • 1970-01-01
      相关资源
      最近更新 更多