Sqlserver 2005使用XML一次更新多条记录的方法

2016-02-19 10:26 2 1 收藏

下面这个Sqlserver 2005使用XML一次更新多条记录的方法教程由图老师小编精心推荐选出,过程简单易学超容易上手,喜欢就要赶紧get起来哦!

【 tulaoshi.com - 编程语言 】

我想很多人都知道,在oracle里面,存储过程里面可以传入数组(如int[]),也就是说,可以传多条记录到数据,从而一起更新。减少数据库的请求次数。
但SqlServer呢?bulk Insert这个很多人都知道,我也知道,但可惜,我从来没用过,只有导数据的时候才会考虑,但导数据DTS不是更方便吗?
手头的一个项目,有几个功能,每次需要更新N(N1000)条记录,记录不多,但如果每次只更新一条,循环insert,那每个功能需要N次请求数据库,如果有1000个并发,那数据库除了做你这个事情,其他的活不用干了。所以,需要尽量减少数据库请求,做到一次更新所有的记录。
幸好,SqlServer给我们提供了一个新功能,利用XML(2000好像是没有这个功能的)。
先来假定一个这样的需求:用户更新一个book,同时需要更新N个章节。
一般的思路是这样,先更新book,然后循环章节数,N次更新数据的章节表。大家可以看下这个性能。

那我们用XML试试

利用XML更新的存储过程
代码如下:

Create PROCEDURE UP_Book_Insert
(
@BookId INT,
@ChapterXml XML
)
AS
BEGIN
CREATE TABLE #table
(
ChapterId INT,
ChapterName VARCHAR(255),
Price INT
);
INSERT #table
SELECT *
FROM (
SELECT X.C.value('Id[1]', 'int') AS ChapterId,
X.C.value('Name[1]', 'varchar(255)') AS ChapterName,
X.C.value('Price[1]','int') AS Price
FROM @ChapterXml.nodes('Chapter') AS X(C) --注意:这里的X(C)命名空间是需要的
) t;
INSERT INTO tbChapter(BookId,ChapterId,ChapterName,Price)
SELECT @BookId,ChapterId,ChapterName,Price from #table;
END

其实,在存储过程里面可以把临时表去掉的。


然后我们执行下看看

执行存储过程
代码如下:

exec UP_Book_Insert 10000,'ChapterId268/IdName第268章/NamePrice100/Price/ChapterChapterId273/IdName第273章/NamePrice100/Price/ChapterChapterId275/IdName第275章/NamePrice100/Price/Chapter'

怎么样?不错吧。只需要在存储过程里面对XML格式进行解析。


而在c#里面,XML格式可以传入DbType.String类型就可以了。

再写一个函数来生成XML格式的字符串


生成XML格式的函数
代码如下:

public static string FormatXmlInfo(ListChapterInfo list)
{
if (list==null||list.Count=0)
{
return String.Empty;
}
StringBuilder sb = new StringBuilder();
foreach (ChapterInfo info in list)
{
sb.AppendFormat("ChapterId{0}/IdName{1}/NamePrice{2}/Price/Chapter", info.ChapterId, info.ChapterName, info.Price);
}
return sb.ToString();
}



好了,完成了。

性能具体怎么样,还没进行测试,但肯定的一点是,比多次请求数据库,或者在存储过程里面循环分割字符串效率要高。

来源:https://www.tulaoshi.com/n/20160219/1594639.html

延伸阅读
MySQL是支持在单个查询字符串中指定多语句执行的,使用方法是给链接指定参数: 代码如下: //链接时设定 mysql_real_connect( ..., CLIENT_MULTI_STATEMENTS ); //或者 //中途指定 mysql_set_server_option( mysql, MYSQL_OPTION_MULTI_STATEMENTS_ON ); //mysql是连接的名称 当使用执行多语句功能后,一定要读完整个resault集,否则...
下面我们来看下,如何利用它来删除一个表中重复记录: 代码如下: If Exists(Select * From tempdb.Information_Schema.Tables Where Table_Name Like '#Temp%') Drop Table #temp Create Table #temp ([Id] int, [Name] varchar(50), [Age] int, [Sex] bit default 1) Go Insert Into #temp ([Id] , [Name] , [Age] , [Sex] ) Values(1,'J...
1、你可以用SQLCMD执行交互式动作,如: C:sqlcmdsqlcmd 1 SELECT name from sys.databases 2 GO 你也可以试着键入如下命令,现实服务器列表 1:ServerList SERVERS: WUYZ 1如果想看其他命令的使用,可以键入:Help /? 2、执行SQL脚本文件 你可以在SQLCMD命令上加入参数I来执行SQL脚本文件,例...
正常情况下,按照每天早晚两次的食用频率来算,塑料牙刷要1-2个月内就更换,动物毛的牙刷最多使用1个月,就必须更换。 刷牙杯多久换一次?正确使用牙刷的方法 牙刷多久换一次 一般来说,大部分牙刷是塑料制作的,只有极少数牙刷是动物毛制作的,因为,动物毛的成本过高,价格昂贵,制作易消耗品,不同的牙刷使用期限也有所...
语法:ROW_NUMBER() OVER(PARTITION BY COLUMN ORDER BY COLUMN) BR 例子: 代码如下: select * from ( select *, ROW_NUMBER() OVER(Order by a.CreateTime DESC ) AS RowNumber from table_name as a ) as b where RowNumber BETWEEN 1 and 5 将会返回table表 其中有一列名字为 RowNumber, 编号从1开始 示例: ...

经验教程

826

收藏

84
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部