`
happmaoo
  • 浏览: 4472020 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

[SQLXML]FOR XML语法导出XML的易错之处

阅读更多
<iframe align="center" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog336280.html" frameborder="0" width="336" scrolling="no" height="280"></iframe>

[SQLXML]FOR XML语法导出XML的易错之处

Version

Date

Creator

Description

1.0.0.1

2006-6-29

郑昀@Ultrapower

草稿

继续阅读之前,我们假设您熟悉以下知识:

n MS SQL Server 2000

n Sp_makewebtask

n FOR XML 子句

如果不熟悉这些知识点,可以看下面两小节[准备工作一:FOR XML][准备工作二:sp_makewebtask];否则可以直接跳过。

[准备工作一:FOR XML]

关键词 FOR XML AUTO/EXPLICIT

功能 可以对现有的关系数据库执行 SQL 查询,以返回 XML 文档形式而不是标准行集的结果。若要直接检索结果,请使用 SELECT 语句的 FOR XML 子句,并且在 FOR XML 子句中指定下列 XML 模式之一:

l RAW

l AUTO

l EXPLICIT

这些模式仅在设置它们的查询执行时有效。它们对后面执行的任何查询的结果没有影响。除了指定 XML 模式外,还可以请求 XML-Data 架构。

引申 在实际工作中,肯定会经常遇到要自己去查询数据库然后组织一个XML文档的需求,这时候就可以直接用FOR XML语法。

举一个最简单的例子:

Sql script

Use pubs

SELECT TOP 2 title_id, title, type

FROM titles FOR XML AUTO, ELEMENTS

那么,输出结果就是:

Sql result

XML_F52E2B61-18A1-11d1-B105-00805F49916B

-----------------------------------------------------------------------------------

<titles><p></p></titles>

<title_id>BU1032</title_id>

The Busy Executive's Database Guide

<type>business<span style="mso-spacerun: yes"> </span></type>

<titles><p></p></titles>

<title_id>BU1111</title_id>

Cooking with Computers: Surreptitious Balance Sheets

<type>business<span style="mso-spacerun: yes"> </span></type>

上面的例子,你自己并没有能够定义XML节点。下面用FOR XML EXPICIT就可以。

XML EXPLICIT的语法为:

[Element Tag!Tag!Attribute!Directive]

下面举一个例子:

Sql script

Use pubs

SELECT TOP 2

1 AS Tag,

NULL AS Parent,

title_id AS [titles!1!title_id],

title AS [titles!1!title!element],

type AS [titles!1!type]

FROM

titles

FOR XML EXPLICIT

那么,输出结果就是:

Sql result

XML_F52E2B61-18A1-11d1-B105-00805F49916B

-----------------------------------------------------------------------------------

<titles title_id="BU1032" type="business&lt;span style=" mso-spacerun: yes></titles>">

The Busy Executive's Database Guide

<titles title_id="BU1111" type="business&lt;span style=" mso-spacerun: yes></titles>">

Cooking with Computers: Surreptitious Balance Sheets

可以看到,

由于“[titles!1!title_id]”,所以titles节点有一个属性就是title_id

由于“[titles!1!title!element]”,所以titles节点有一个子节点就是title

之所以有“<titles></titles>”节点,是因为“FROM titles”,也就是表名。

很简单的语法。

但是如果数据量大的话,会发生什么事情呢?

比如我执行

Sql script

Use pubs

SELECT title_id, title, type

FROM titles FOR XML AUTO, ELEMENTS

呢?

她还会返回一个完整的XML文档吗?

[准备工作二:sp_makewebtask]

关键词: sp_makewebtask

功能: 创建一项生成 HTML 文档的任务,该文档包含执行过的查询返回的数据。

引申: 虽说这是一个SQL Server 2000用来根据查询结果来自动生成HTML文档的存储过程。但也还是经常被人用作输出XML文件的工具。

最简单的例子:

第一步,在C盘新建一个模板文件shippers_output_style.tpl,内容为:

template

<?xml version="1.0" encoding=”GB2312” ?>

<shippers><p></p></shippers>

第二步,我们运行SQL语句:

Sql script

Use Northwind

GO

EXEC sp_makewebtask

@outputfile = 'c:\Shippers.xml',

@query = 'SELECT * FROM Shippers FOR XML AUTO',

@templatefile ='c:\shippers_output_style.tpl'

第三步,文件已经生成,查看C盘的输出文件Shippers.xml如下:

Sql script

<?xml version="1.0" encoding=”GB2312”?>

<shippers><p></p></shippers>

<shippers shipperid="1" companyname="Speedy Express" phone="(503) 555-9831"></shippers>

<shippers shipperid="2" companyname="United Package" phone="(503) 555-3199"></shippers>

<shippers shipperid="3" companyname="Federal Shipping" phone="(503) 555-9931"></shippers>

也就是说,对于FOR XML语句生成的XML数据流,本来需要你自己读,并且落地。现在,交给sp_makewebtask这个系统存储过程即可。

它只不过需要特殊的权限才可以运行:sys_admin

不过,sp_makewebtask强大定制功能还是不错的,它本身就提供自动定时生成功能。

同样,提一个问题,如果数据量很大,sp_makewebtask输出的FOR XML结果会是什么样呢?它还会是一个有效的XML文件吗?

[回答前面的问题]

如果查询结果数据量大的话,你可能会对你所看到的东西觉得奇怪。

假如你是在SQL Server2000的查询分析器里执行的SQL语句,那么你可能会看到折成好几个记录返回,如下所示:

而不再是一个记录。

这时候,有一个有趣的问题,可能XML的节点名也被一劈两半,分成两个记录。

这时候,如果你是用sp_makewebtask的自动生成文件功能,那么XML文件内容到处都是断裂的节点名,从而无法正常解析。

类似于

. ...

n><pubdate>2009-06-27<p></p></pubdate>

Description节点名就被分裂为两块,中间还换了行,当然这个换行是因为我们的模板文件的“

”存在换行,但是如果因此调整为“”,那么sp_makewebtask就不认endtail了,“”会原封不动出现在XML文件中,而没有做置换。

所以,即使你调整template模板文件内容也无济于事。这时候,解析XML的程序就会报告类似“结束标记 'body' 与开始标记 'title' 不匹配”的错误。

为什么呢?因为sp_makewebtask的本身是为了生成HTML服务的,HTML可不在乎标签名断裂。

SQL Server XML - Multiple rows returned by for xml explicit》提到了这个现象,并给出了解释。

[解释]

原因只是你用了“错误”的工具。

我试验过,不管是SQL Server 2000的查询分析器的“文本显示”/“表格显示”,还是SQL Server 2005SQL Server Management Studio,或者是存储过程,或者是SQL Server 2000的作业,都无法避免这个问题。

但是,如果用dotNET中的XMLReader对象来读,就可以。

Rob自己也说:

The sql reader returns records and the xmlreader returns one xml. If you use the sqlreader you can concat the records and it will work but it is a waste to do it that way.

[可用的方法]

用下面的C#代码就可以保存一个完整的、没有被辟成几截的XML文件。注意,你的机器上必须安装SQL Server 2005安装盘下Servers\Setup\sqlxml4.msi,以拥有Microsoft.Data.SqlXml.DLL以及配套环境。

C# Codes

string coString = "Provider=sqloledb;data source=YourServer;user id=sa;password=;initial catalog=pubs";

SqlXmlCommand cmd = new SqlXmlCommand(coString);

XmlReader xr;

XmlDocument xDoc = new XmlDocument();

DataSet ds = new DataSet();

//Set the Root document tag

//to make sure the xml is well formed

cmd.RootTag = "Authors";

//set the clientSideXml property

cmd.ClientSideXml = true;

//call the existing strored proc

//and append the for xml nested syntax

cmd.CommandText = "exec proc_output_authors";

//Execute the reader

xr = cmd.ExecuteXmlReader();

//load the xml document with

//the contents of the reader

xDoc.Load(xr);

//Persist the document to disk

xDoc.Save(txtXMLFilePath.Text);

那边的存储过程实际就是这样的语句:

/* Body of XML Document */

select

Author.au_fname as FirstName,

Author.au_lname as LastName,

Book.title as BookTitle,

Book.title_id as BookId

from

authors as Author

inner join

dbo.titleauthor as Titles

on

Author.au_id = Titles.au_id

inner join

dbo.titles as Book

on

Titles.title_id = Book.title_id

for

xml auto

[参考资料]




分享到:
评论

相关推荐

    SQL Server FOR XML PATH 语句的应用

    SQL Server 提供了多种方法来生成XML数据,其中`FOR XML PATH`是最常用的方法之一。通过使用`FOR XML PATH`语句,可以将SQL Server中的数据查询结果转换成符合特定结构的XML文档。 #### 基本用法 `FOR XML PATH`的...

    将SQL数据库表转换成XML文件输出(脚本)

    - 使用`bcp`命令来创建格式文件,再使用`FOR XML AUTO`来生成XML数据,并最终通过`bcp`命令将XML数据导出到指定路径。 ```sql declare cur cursor for select tblname from #temp open cur fetch next from ...

    SQLXML_Sample

    **SQLXML_Sample** 在IT领域,SQLXML是微软提供的一种技术,用于在SQL Server数据库与XML数据之间建立桥梁。这个“SQLXML_Sample”示例着重展示了如何使用SQLXML来映射XML文件到关系数据库中,特别是针对博客文章的...

    xml 数据库教程 xml语法

    - **基于SQL的查询语言**:扩展SQL以支持XML数据的操作。 - **XML Query语言**:如XQuery,专门针对XML数据设计的查询语言。 - **5.3 在原生XML数据库中存储数据**:原生XML数据库能够更有效地存储和处理XML数据,...

    xml的导入导出(java)

    1. **解析XML文件**:Java提供了多种解析器来读取XML文件,如DOM(Document Object Model)、SAX(Simple API for XML)和StAX(Streaming API for XML)。DOM解析器会将整个XML文档加载到内存中,适合小型文件;SAX...

    sql各年标准bnf语法之xml展示

    sql各年标准bnf语法之xml展示,利用了xml的扩展特性,对BNF语法进行了元素显示深度扩展,十分利于查看sql语法,是学习sql和开发数据库软件的好帮手。 文件也包含了sql2011标准文档,下载来源是此网站。内包含一个程序...

    Kettle数据导出为XML文件

    标题“Kettle数据导出为XML文件”涉及的是使用Pentaho Data Integration(通常称为Kettle或ETL工具)将数据转换并导出为XML格式的过程。Kettle是一款开源的数据集成工具,它允许用户通过图形化界面设计数据处理流程...

    FOR XML子句在SQL Server中的用法比较.pdf

    随着XML(可扩展标记语言)在数据交换中的广泛应用,SQL Server引入了FOR XML子句,以便能够将SQL查询结果转换成XML格式。本篇文章主要介绍了SQL Server中FOR XML子句的四种不同用法:AUTO、RAW、EXPLICIT和PATH,...

    mybatis导出xml文件(只支持mysql数据库)

    标题"mybatis导出xml文件(只支持mysql数据库)"指的是一个特定的功能,即在MySQL数据库环境下,能够自动生成MyBatis的XML映射文件。这个功能通常是为了提高开发效率,避免手动编写XML映射文件,这些文件定义了SQL查询...

    SQL Server中读取XML文件的简单做法

    然而,在SQL Server 2000中,处理XML文件并不像导出数据那样直接。这篇文章主要介绍了如何利用SQL Server的内置函数和存储过程来实现这一目标。 首先,SQL Server提供了两种主要的方法来处理XML数据:`OPENXML`和`...

    SQL 数据表转化为XML 文件

    首先,SQL Server提供了`FOR XML`子句,允许我们直接在SQL查询中生成XML结果。它的基本语法是: ```sql SELECT column1, column2, ... FROM table_name FOR XML AUTO, ELEMENTS, ROOT('rootElementName'); ``` 这...

    使用java把数据库数据导出生成xml文件

    使用java把数据库数据导出生成xml文件 使用java把数据库数据导出生成xml文件

    oracle导入导出xml

    根据提供的文件信息,本文将对Oracle数据库中导入导出XML文件的相关知识点进行详细的解析与介绍。主要内容包括如何通过Java代码实现Oracle数据库与XML文件之间的数据交互,并深入理解所提供代码的具体功能。 ### ...

    ACCESS对象导入与导出XML模块.rar

    在进行XML导入导出时,要警惕SQL注入和其他安全风险。确保对用户输入进行验证,并在必要时进行转义处理,以防止恶意数据进入数据库。 8. 错误处理和异常处理: 在编写源码时,良好的错误处理和异常处理机制是必不...

    在SQL Server中将数据导出为XML和Json的方法

    总的来说,SQL Server提供了灵活的方式来导出数据为XML和JSON格式,无论是通过原生的`FOR XML`子句还是借助第三方解决方案。这使得在不同系统之间交换数据变得更加容易,同时也简化了数据迁移和分析的过程。然而,...

    走进 SQL/XML

    【SQL/XML】是数据库技术中一个重要的领域,它涉及到如何在SQL环境中处理和操作XML数据。XML(可扩展标记语言)常被用于存储和传输结构化数据,而SQL则是关系数据库的标准查询语言。随着XML在现代信息系统中的广泛...

    将sqlserver中的数据导出成为sql语句

    在SQL Server管理数据库的过程中,有时我们需要将数据导出以便备份、迁移或在其他环境中复用。标题提到的“将sqlserver中的数据导出成为sql语句”是指将SQL Server数据库中的表结构和数据转换为一系列的INSERT INTO ...

Global site tag (gtag.js) - Google Analytics