SQL 存储过程 解析XML
第一种说明:
我看过这样一篇文章,如下
在SQL Server2005中,微软延续了 2000中一个特性(即支持XML类型的数据),并加强了对XML 数据列、XML变量以及XML索引的支持。
在数据库中存储XML数据是一个很出色的特征。对于大部分的数据处理需求来讲,将XML数据格式化为其它关联数据是十分重要。这也是引入OPENXML函 数的原因。OPENXML是一个SQL Server提供的函数,它的作用是接收XML数据,提供内存中 XML数据的行集视图。
一个OPENXML函数用例
在下面的例子中,我们将演示如何使用OPENXML函数。假定我们现在正在从事一个网上购物系统开发。在这个场景中,顾客选择登录网站方式购买多种产品。 因为根据公司的商业模式,通过网站购物能够节省成本。我们假定大部分的顾客都购买了七件或者更多的商品。我们的目标是当客户频繁的访问网站的时候,要尽量 减少数据库的调用。我们的想法是将网页上提交的采购需求存储为XML文档,并且将其中的XML数据以字符串的形式传送给数据库底层的程序处理。这样,我们 就可以在一次数据库调用中将XML数据中的订单信息插入数据库中。
我们该如何解决上面的问题呢?首先我们看看将要编辑的网页数据。一个简单的XML文档含有来自网站的很多核心信息,包括:产品名称、价格、日期以及顾客资料。列表A包含了一个简单的XML数据流。
<ShoppingCart>
<Purchase ProductID= "7 " Price= "10.00 " SaleDate= "10/11/2006 " SaleBatchID = "4523 " CustomerID = "2398 "/>
<Purchase ProductID= "99 " Price= "25.00 " SaleDate= "10/11/2006 " SaleBatchID = "4523 " CustomerID = "2398 "/>
<Purchase ProductID= "32 " Price= "12.00 " SaleDate= "10/11/2006 " SaleBatchID = "4523 " CustomerID = "2398 "/>
<Purchase ProductID= "11 " Price= "90.00 " SaleDate= "10/11/2006 " SaleBatchID = "4523 " CustomerID = "2398 "/>
<Purchase ProductID= "7 " Price= "50.00 " SaleDate= "10/11/2006 " SaleBatchID = "4523 " CustomerID = "2398 "/>
<Purchase ProductID= "8 " Price= "67.35 " SaleDate= "10/11/2006 " SaleBatchID = "4523 " CustomerID = "2398 "/>
<Purchase ProductID= "45 " Price= "29.99 " SaleDate= "10/11/2006 " SaleBatchID = "4523 " CustomerID = "2398 "/>
<Purchase ProductID= "54 " Price= "49.49 " SaleDate= "10/11/2006 " SaleBatchID = "4523 " CustomerID = "2398 "/>
</ShoppingCart>
列表A
然后,我们需要设计一个网页接口提供存储程序的调用。通过调用这一存储程序,将XML数据流存储至数据库。列表B是这一存储程序的实现内容。
CREATE PROCEDURE usp_InsertShoppingCartOrder
(
@xml XML
)
AS
BEGIN
DECLARE @Pointer INT
EXECUTE sp_xml_preparedocument @Pointer OUTPUT,@xml INSERT INTO WebSales
(
ProductID,
SalePrice,
SaleDate,
SaleBatchID,
CustomerID
)
SELECT
ProductID,
Price,
SaleDate,
SaleBatchID,
CustomerID
FROM
OPENXML (@Pointer, '/ShoppingCart/Purchase ')
WITH
(
ProductID INT,
Price MONEY,
SaleDate SMALLDATETIME,
SaleBatchID INT,
CustomerID INT
) EXEC sp_xml_removedocument @Pointer
END
列表B
这一存储程序支持XML数据类型(SQL Server 2005中新特色)作为输入参数(我们也可以使用变量字符数据类型作为我们的输入参数,例如VARCHAR (max)或者定义VARCHAR数据类型)。
接下来,我们调用系统程序sp_xml_preparedocument,它不仅创建了XML文档在内存中的表示,也允许XML文档作为调用参数。一旦我 们拥有了指向内存中XML文档的句柄,就可以调用OPENXML函数。在函数调用中使用不同的参数,还可以对XML数据的返回结果集进行详细的控制。
我们提供指向XML文档的句柄,并且通过XPATH查询返回想要的XML数据中的节点。OPENXML函数中的WITH子句允许指定返回数据的行集格式。 一旦将数据插入到websales 表格中,就可以调用系统程序sp_xml_removedocument删除SQL Server 服务器内存中的XML数据。
这个简单的例子演示了通过OPENXML函数来减少数据库调用次数的强大功能。OPENXML函数提供很大的灵活性,你既可以将所有的XML数据插入到 SQL Server 数据表中,也可以拆分XML文件,将其插入到不同的SQL Server数据表中。通过这一技术,我们就可以在一次程序调用中插入8条记录,而不是像传统的技术那样,要通过8次操作实现。
OPENXML的局限性
调用OPENXML函数时要注意内存的使用情况。系统程序sp_xml_preparedocument 的返回值是指向内存中XML文档的句柄。所以,你最好不要使用OPENXML加载较大的XML文档,因为那样可能会造成服务器的内存溢出。
在以后的文章中,我将会向你介绍如何使用SQL Server 2005提供的关于XML的一些新属性,这些新属性不仅能够实现OPENXML函数的功能,而且不需要考虑OPENXML调用时产生的内存操作问题。
作者简介
Tim Chapman先生在一家位于Louisville, KY的银行从事数据库管理员的工作,拥有7年的IT工作经验。他还通过了微软的SQL Server 2000和SQL Server 2005认证。
第二种说明:
创建几个带不同参数的存储过程去完成同一样任务对我们来说一直以来都是一个负担。通过使用XML字符串传递参数给你的存储过程可以简化这个任务,从而使设计COM组件变得更加简单。
达 到这个目标的方法是将你的参数作为一个XML字符串传入,然后解析XML以取得你需要的数据,最后继续完成你需要实现的功能。你不但可以从XML中获得参 数,你还可以在由XML创建的DOM文档运行查询语句,完成几个存储过程调用。我将给出一些例子来说明怎样做,每个例子都有一个简单的解释。
在这个例子中,我将传递一些参数用以更新Customer表的name域。XML被解析以获得customerid(标识列)和新的name。我传给过程的XML字符串如下:
<root>
<Customer>
<customerid>3</customerid>
<name>Acme Inc.</name>
</Customer>
</root>
创建的存储过程如下:
CREATE PROCEDURE update_Customer (@xmldata varchar(8000)) AS
DECLARE @customerid int
DECLARE @customername varchar(50)
DECLARE @xmldata_id int EXEC sp_xml_preparedocument @xmldata_id OUTPUT, @xmldata, '' SELECT @customerid = customerid, @customername = [name] FROM
OPENXML(@xmldata_id, '//Customer', 2) WITH (customerid int, [name]
varchar(50)) EXEC sp_xml_removedocument @xmldata_id UPDATE Customer SET Customer.[name] = ISNULL(@customername, Customer.[name])
WHERE Customer.tblID = @customerid
这个过程首先声明我们用于存储相关信息的变量。之后,打开DOM文档,调用过程sp_xml_preparedocument,其第一个参数返回一个“句柄”。
这个过程调用的第二个参数是新DOM文档的XML源。第一个参数返回的“句柄”在OPENXML调用中用于查询DOM文档。OPENXML调用的第二个参数是一个映射到包含要提取数据的父节点的扩展路径。
第三个参数(2)指明使用以元素为中心的映射。WITH子句为被解析的数据提供行集合格式,然后sp_xml_removedocument调用删除DOM文档资源。
在下面的另一个例子中,我将会根据传入的一组customer ID删除几行数据。使用的XML字符串如下:
<root>
<Customer>
<customerid>1</customerid>
</Customer>
<Customer>
<customerid>2</customerid>
</Customer>
<Customer>
<customerid>3</customerid>
</Customer>
</root>
使用的存储过程如下:
EXEC sp_xml_preparedocument @xml_id OUTPUT, @xmldata, ''
DELETE FROM Customer WHERE Customer.tblID IN (SELECT customerid FROM
OPENXML (@xmldata_id, '//Customer', 2) WITH (customerid int))
这个存储过程的使用避免了建立一个长SQL查询字符串来通过ADO传递,或者多次调用同一个存储过程。也避免了由于多次调用引起的网络拥挤。
正如你看到的,使用Microsoft SQL Server 2000可以使一些事情变得比较简单。但记住是当你在SQL Server 2000中使用XML时,作为参数传入的XML不能超过8000个字符。就像常说的,不要过高的看待一件好事的好处。
参考MSDN库取得更多关于OPENXML, sp_xml_preparedocument 和 sp_xml_removedocument 的信息。
SQL 存储过程 解析XML的更多相关文章
- SQL Server解析XML数据的方法详解
--下面为多种方法从XML中读取EMAIL DECLARE @x XML SELECT @x = ' <People> <dongsheng> <Info Name=&q ...
- SQL Server 存储过程解析XML传参 参考方案
1.定义存储过程 -- =============================================--定义存储过程-- ================================ ...
- SQL 里解析 XML 格式 字段 信息
DECLARE @ItemMessage XML ),zje ),yfje ),bcje ),URL ),Remark )) SET @ItemMessage=N'<List> <i ...
- sql解析xml
我们有时候需要在sql中解析xml,xml解析sql实例如下: DECLARE @params xml DECLARE @customparams xml = null -- 0.解析输入参数 ...
- ms sql server读取xml文件存储过程-sp_xml_preparedocument
最近要在存储过程中读取xml中节点的值,然后进行sql操作: 要使用到的系统存储过程如下:sp_xml_preparedocument create procedure [dbo].[pro_Test ...
- sql 解析字符串添加到临时表中 sql存储过程in 参数输入
sql 解析字符串添加到临时表中 sql存储过程in 参数输入 解决方法 把字符串解析 添加到 临时表中 SELECT * into #临时表 FROM dbo.Func_SplitOneCol ...
- 通过generate解析SQL日志生成xml进行SQL回放
查看Oracle redo日志来分析SQL执行记录 1)设置Oracle数据字典导出路径参数(可选) shutdown immediatealter system set UTL_FILE_DIR=' ...
- 批量处理sql 数据存入xml类型列
个人记录 需求:当表T1 ItemCode和表T2 ItemName的数据相等时,将表T2所对应的ID和ItemName列的数据分别存入表T1 CAOZUO字段的id元素和text元素的文本中. 下面 ...
- java解析xml的三种方法
java解析XML的三种方法 1.SAX事件解析 package com.wzh.sax; import org.xml.sax.Attributes; import org.xml.sax.SAXE ...
随机推荐
- 利用反射+AOP,封装Basehandler
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点, ...
- AngularJS中多个ng-app(手动加载模块)
1.当有多个ng-app时:(首先是要加载angularJS) <div ng-app=""> <p>姓名:<input type="tex ...
- 合并excel中多个sheet
Sub 合并当前工作簿下的所有工作表() Application.ScreenUpdating = False For j = 1 To Sheets.Count If Sheets(j).Name ...
- jQuery事件绑定.on()简要概述及应用
原文地址:http://www.jquerycn.cn/a_5346 前几天看到事件委托的时候,关于live()方法讲的不是很详细,就去搜了一下关于live()和delegate()的,最后看 ...
- C#操作word的一些基本方法(word打印,插入文件,插入图片,定位页眉页脚,去掉横线)
Microsoft.Office.Interop.Word.Application wordApp = new ApplicationClass() word对象 2. Microsoft.Offic ...
- good design
canvas 效果麦当劳40周年纪念日 效果图 McDonald's 40th Anniversary 交互效果很流畅,赞!
- iOS - WXPay 微信支付
1.微信支付申请 微信支付官方集成指引 微信支付官方集成指导视频 微信 APP 支付开发者文档 微信公众平台 微信开放平台 微信商户平台 1.1 微信 APP 支付申请步骤 APP 支付:APP 支付 ...
- 使用Angularjs的ng-cloak指令避免页面乱码
在使用Anguarjs进行web开发或者进行SPA(single page application)开发时,往往会遇到下面这样的问题. 刷新页面时,页面会出现一些乱码,这里的乱码具体是指`{{expr ...
- Python_Day4_函数
本节内容 1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数 定义: 函数是指将一组语句的集合通过一个名字( ...
- SQL Server Reporting Service(SSRS) 第四篇 SSRS 用法总结
1. 如何让表头在每页显示(译) A. 打开高级模式: 在分组栏中点击Column Goups右侧的箭头选择高级模式; B. 找到第一个Static组 在Row Groups区域中(注意不是Colu ...