XML转换DataSet,然后插入数据库+批量插入数据库

       上周五接到一个任务,就是PHP组会传递一些数据过来,我要完成的任务就是将这些数据库导出然后插入数据库,周四下午恰好在学习XML的序列化。于是经过讨论后决定传递过来的数据用XML格式,我对其进行反序列化,然后插入数据库。但是后来发现,这样反序列化后,得到的是一个数组对象。最简单的方法就是用一个for循环将其一个个插入数据库,但是觉得这样的效率太低了。于是在网上找了下关于批量插入数据库的资料。找到两个可行方案,接下来对这两个可行方案进行备忘。

       1.用ADO.NET的一个新特性:SqlBulkCopy.将传递过来的xml文件读入到DataSet中,当然还要对这个xml进行数据格式上的Xsd验证。代码如下:

View Code
1 Database db = DatabaseFactory.CreateDatabase();
2 public DataSet CXmlFileToDataSet(string xmlPath,string xmlSchemaPath)
3 {
4 DataSet ds = new DataSet();
5 ds.ReadXmlSchema(xmlSchemaPath);
6 ds.ReadXml(xmlPath);
7 return ds;
8 }
9
10 public void SqlBulkCopyInsert()
11 {
12 string xmlPath="D:/临时备份/PersonalLearnDemo/WuxqHelper/XMLFile1.xml";;
13 string xmlSchemaPath = "D:/临时备份/PersonalLearnDemo/WuxqHelper/XMLFile1.xsd";
14 using (SqlConnection sqlCon = (SqlConnection)db.CreateConnection())
15 {
16 sqlCon.Open();
17 SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(sqlCon);
18 sqlBulkCopy.DestinationTableName = "Revenue";
19 sqlBulkCopy.WriteToServer(CXmlFileToDataSet(xmlPath, xmlSchemaPath).Tables[0]);
20 sqlCon.Close();
21 }
22 }

       2.利用SQLServer2008的新特性--表值参数(Table-Valued Parameter)。表值参数是SQLServer2008才有的一个新特性,使用这个新特性,我们可以把一个表类型作为参数传递到函数或存储过程里。不过,它也有一个特点:表值参数在插入数目少于 1000 的行时具有很好的执行性能。

       从MSDN得知:表值参数提供一种将客户端应用程序中的多行数据封送到 SQL Server 的简单方式,而不需要多次往返或特殊服务器端逻辑来处理数据。 您可以使用表值参数来包装客户端应用程序中的数据行,并使用单个参数化命令将数据发送到服务器。 传入的数据行存储在一个表变量中,然后您可以通过使用 Transact-SQL 对该表变量进行操作。

       而这个表变量需要我们事先进行声明。使用Transact-SQL CREATE TYPE 语句定义的强类型表结构为基础。 您必须先在 SQL Server 中创建一个表类型并定义结构,才能在客户端应用程序中使用表值参数。例如下面的代码创建一个CategoryId列和一个CategoryName列。

CREATE TYPE dbo.CategoryTableType AS TABLE
( CategoryID
int, CategoryName nvarchar(50) )

        定义完表值参数后,我们可以对相应数据表进行更新,或者插入。列入将表值参数传递给存储过程。个人认为利用表值参数来实现批量插入技术可行性不如上面的SqlBulkCopy.应该是用在批量更新上面。代码如下:

create type RevenueTableType as table([Uid] int,[Year] int,[Month]int,Amount decimal,CheckStatus tinyint,CheckTime date,FailureReason nvarchar(300))

create proc BulkInsertProc
@RevenueTable RevenueTableType
readonly
as
begin
--接下来用insert into select进行插入
insert into Revenue ([uid],[Year],[Month],Amount ,CheckStatus ,CheckTime ,FailureReason)
select r.[uid],r.[Year],r.[Month],r.Amount ,r.CheckStatus ,r.CheckTime ,r.FailureReason
from @RevenueTable r
end

       .NET调用代码:悲剧发现在.NET企业库下没有DbType.Struct.所以....用ADO.NET进行编写。

View Code
1 public void CallBulkCopyInsert()
2 {
3 string xmlPath = "D:/临时备份/PersonalLearnDemo/WuxqHelper/XMLFile1.xml";
4 string xmlSchemaPath = "D:/临时备份/PersonalLearnDemo/WuxqHelper/XMLFile1.xsd";
5 DataSet ds = CXmlFileToDataSet(xmlPath, xmlSchemaPath);
6 using (SqlConnection con = (SqlConnection)db.CreateConnection())
7 {
8 con.Open();
9 SqlCommand insertCommand = new SqlCommand(
10 "BulkInsertProc", con);
11 insertCommand.CommandType = CommandType.StoredProcedure;
12 SqlParameter Param = insertCommand.Parameters.AddWithValue(
13 "@RevenueTable", ds.Tables[0]);
14 Param.SqlDbType = SqlDbType.Structured;
15 insertCommand.ExecuteNonQuery();
16 con.Close();
17 }
18
19 }

posted @ 2011-03-08 11:56  雁北飞  阅读(2207)  评论(1编辑  收藏  举报