[SQLXML]FOR XML语法导出XML的易错之处
原文:[SQLXML]FOR XML语法导出XML的易错之处
[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> <title_id>BU1032</title_id> <title>The Busy Executive's Database Guide</title> <type>business </type> </titles> <titles> <title_id>BU1111</title_id> <title>Cooking with Computers: Surreptitious Balance Sheets</title> <type>business </type> </titles> |
上面的例子,你自己并没有能够定义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 "> <title>The Busy Executive's Database Guide</title> </titles> <titles title_id="BU1111" type="business "> <title>Cooking with Computers: Surreptitious Balance Sheets</title> </titles> |
可以看到,
由于“[titles!1!title_id]”,所以titles节点有一个属性就是title_id;
由于“[titles!1!title!element]”,所以titles节点有一个子节点就是title;
之所以有“<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> <%begindetail%> <%insert_data_here%> <%enddetail%> </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> <Shippers ShipperID="1" CompanyName="Speedy Express" Phone="(503) 555-9831"/> <Shippers ShipperID="2" CompanyName="United Package" Phone="(503) 555-3199" /> <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文件内容到处都是断裂的节点名,从而无法正常解析。
类似于
“
. ...</descriptio
n><pubDate>2009-06-27
”
Description节点名就被分裂为两块,中间还换了行,当然这个换行是因为我们的模板文件的“<%insert_data_here%>
<%enddetail%>”存在换行,但是如果因此调整为“<%insert_data_here%><%enddetail%>”,那么sp_makewebtask就不认endtail了,“<%enddetail%>”会原封不动出现在XML文件中,而没有做置换。
所以,即使你调整template模板文件内容也无济于事。这时候,解析XML的程序就会报告类似“结束标记 'body' 与开始标记 'title' 不匹配”的错误。
为什么呢?因为sp_makewebtask的本身是为了生成HTML服务的,HTML可不在乎标签名断裂。
《SQL Server XML - Multiple rows returned by for xml explicit》提到了这个现象,并给出了解释。
[解释]
原因只是你用了“错误”的工具。
我试验过,不管是SQL Server 2000的查询分析器的“文本显示”/“表格显示”,还是SQL Server 2005的SQL 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
[参考资料]
- Understanding EXPLICIT XML Formatting
- Understanding and Using SELECT ... FOR XML
- SQL Server XML - Multiple rows returned by for xml explicit
[SQLXML]FOR XML语法导出XML的易错之处的更多相关文章
- JAVASE02-Unit012: Unit07: XML语法 、 XML解析
Unit07: XML语法 . XML解析 emplist.xml <?xml version="1.0" encoding="UTF-8"?> & ...
- XML 语法规则
转摘自:http://www.w3school.com.cn/xml/xml_elements.asp XML 语法规则 XML 文档包含 XML 元素. XML 的语法规则很简单,且很有逻辑.这些规 ...
- 利用XML语法 SQL 列转行
--行转列 固定xml语法 declare @xml xml ; set @xml=cast('<v>2</v><v>4</v><v>3&l ...
- XML 参考:XML基础 XML 简介
XML 参考:XML基础 -- XML简介和用途 转:http://www.cnblogs.com/Dlonghow/archive/2009/01/22/1379799.html XML 参考:XM ...
- xml语法、DTD约束xml、Schema约束xml、DOM解析xml
今日大纲 1.什么是xml.xml的作用 2.xml的语法 3.DTD约束xml 4.Schema约束xml 5.DOM解析xml 1.什么是xml.xml的作用 1.1.xml介绍 在前面学习的ht ...
- 【风马一族_xml】xml语法
xml语法 文档声明 用来声明xml的属性,用来指挥解析引擎如何去解析当前xml 通常一个xml都要包含并且只能包含一个文档声明 xml的文档必须在整个xml的最前面,在文档声明之前不能有任何内容 & ...
- Lazarus中TreeView导出XML以及XML导入TreeView
本来说是要给自己的某程序加一个xml导出功能,但是自己也没接触过xml,加之delphi和lazarus的xml部分还都不一样,折腾好久(整一天)才解决问题.. 如下是作为导出功能的组件部分: uni ...
- 使用XML的五种场合,XML基本规则,XML的术语,结构与语法
在很多研讨会和培训班上我遇到过许多人,他们还不明白为什么要使用XML也不知道如何 在他们的应用中使用XML.一些来自诸如Gartner公司的报告建议说,商业公司不能再做 局外人了,不能对XML置之不理 ...
- 老李分享:导出xml报告到手机
老李分享:导出xml报告到手机 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:908821 ...
随机推荐
- c# 在cmd中用 7z解压缩文件
var exePath = @"C:\Program Files\7-Zip\7z.exe"; var path = @"I:\work\MusicCatcher2\Wi ...
- S2SH新手框架结构的准备工作只需要导入这些文件
实习北京最近一直在某公司.时间很冲突,总想着有事找东西坐,思想,做事先成套我吧 一套完整的东西想好主题,术去实现了,在学校尽管说是学了J2EE,可是确实没学到东西,Struts2+Hibernate不 ...
- Maven+Spring
Maven+Spring 关于Maven Maven是一个用于项目构建的工具,通过它便捷的管理项目的生命周期.即项目的jar包依赖,开发,测试,发布打包. 做过.NET的人应该会联想到Nuget,是的 ...
- ASP.NET 5 Beta8 发布
ASP.NET 5 Beta8 发布 ASP.NET 5 的路线图(详见 ASP.NET 5 Schedule and Roadmap : https://github.com/aspnet/home ...
- Device "/dev/sdg" is not a partition【再续】
之前创建asm磁盘的时候总结过一下错误:http://blog.csdn.net/rhys_oracle/article/details/17029333 当今天情况是这种.例如以下: 在使用open ...
- JAVA web四个属性的范围汇总
首先,你需要知道client跳跃和server差别: client跳转: response.sendRedict(String path),地址栏发生改变. 不能传递request属性. server ...
- java jdk缓存-128~127的Long与Integer
先推断下以下代码的输出结果 Qa:---------------------------------------------- Long a = Long.valueOf(127) ...
- i++与++i哪个效率更高
简单的比较前缀自增运算符和后缀自增运算符的效率是片面的, 因为存在很多因素影响这个问题的答案. 首先考虑内建数据类型的情况: 如果自增运算表达式的结果没有被使用, 而是仅仅简单地用于增加一元操作数, ...
- 用C#绘图实现动画出现卡屏(运行慢)问题的解决办法
原文:用C#绘图实现动画出现卡屏(运行慢)问题的解决办法 正在用C#做一个小游戏,需要用到动画,上次解决的问题是闪烁问题,用双缓冲技术.以为不会有什么问题了.后来当把图片全部绘制上去的时候依然出现了卡 ...
- 【C++模版之旅】项目中一次活用C++模板(traits)的经历
曾经曾在一个项目中碰到过一个挺简单的问题,但一时又不能用普通常规的方法去非常好的解决,最后通过C++模板的活用,通过traits相对照较巧妙的攻克了这个问题.本文主要想重现问题发生,若干解决方式的比較 ...