平常新增多条记录,需要多次访问数据库,这样会影响性能;如果把新增的数据拼接成XML形式,作为参数传给存储过程来处理,这只访问数据库一次,执行速度会快很多。

1.C#代码如下:XML拼接的字段不能出现&等其他执行存储过程不支持的符号,需要转义,C#里面的方法是 1.Server.HtmlEncode(参数值);2. ReplaceXmlStr(参数值);

/// <summary>
/// XML特殊字符替换
/// </summary>
/// <param name="str"></param>
public static string ReplaceXmlStr(string str)
{
if (!string.IsNullOrEmpty(str))
{
  str = str.Replace("'", " "); //20140420 add
  str = str.Replace("<", "&lt;");
  str = str.Replace(">", "&gt;");
  str = str.Replace("&", "&amp;");
  str = str.Replace("'", "&apos;");
  str = str.Replace("\"", "&quot;");
}
  return str;
}

另外注意:

foreach循环不要这样写:

MovementItemWmsInfoToXM = string.Format(MovementItemWmsInfoToXML, item.SkuCode, item.MovenmentCode, item.Effect,
item.Skunum, item.PropertityStock, item.PromotionCode.Replace("&", "%"), item.StockoutCount, item.StockSerialNumber,
!string.IsNullOrEmpty(item.UnitPrice) ? double.Parse(item.UnitPrice).ToString("0.00") : "0"
,item.ShipperId)
strBuilder.AppendLine(MovementItemWmsInfoToXM);

应该这样写: strBuilder.AppendFormat(MovementItemWmsInfoToXML, item.SkuCode, item.MovenmentCode, item.Effect,
item.Skunum, item.PropertityStock, item.PromotionCode.Replace("&", "%"), item.StockoutCount, item.StockSerialNumber,
!string.IsNullOrEmpty(item.UnitPrice) ? double.Parse(item.UnitPrice).ToString("0.00") : "0"
,item.ShipperId); 或strBuilder.Append(string.Format(MovementItemWmsInfoToXML, item.SkuCode, item.MovenmentCode, item.Effect,item.Skunum, item.PropertityStock, item.PromotionCode.Replace("&", "%"), item.StockoutCount, item.StockSerialNumber,!string.IsNullOrEmpty(item.UnitPrice) ? double.Parse(item.UnitPrice).ToString("0.00") : "0",item.ShipperId));

//拼接XML
private static string MovementItemWmsInfoToXML = "<MovementItemWmsInfoTO SkuCode=\"{0}\" MovenmentCode=\"{1}\" Effect=\"{2}\" Skunum=\"{3}\" PropertityStock=\"{4}\" " +
"PromotionCode=\"{5}\" StockoutCount=\"{6}\" StockSerialNumber=\"{7}\" UnitPrice=\"{8}\" ShipperId=\"{9}\"/>"; /// <summary>
/// 调用存储过程插入MovementItemWmsInfo信息
/// </summary>
/// <param name="list"></param>
/// <returns></returns>
public int InsertMovementItemWmsInfoByListstring(List<MovementItemWmsInfoTO> list)
{
int result = ;
try
{
if (list != null && list.Count > )
{
StringBuilder strBuilder = new StringBuilder();
foreach (MovementItemWmsInfoTO item in list)
{
strBuilder.AppendLine(string.Format(MovementItemWmsInfoToXML, item.SkuCode, item.MovenmentCode, item.Effect,
item.Skunum, item.PropertityStock, item.PromotionCode.Replace("&", "%"), item.StockoutCount, item.StockSerialNumber,
!string.IsNullOrEmpty(item.UnitPrice) ? double.Parse(item.UnitPrice).ToString("0.00") : ""
,item.ShipperId));
} List<SqlParameter> param = new List<SqlParameter>();
param.Add(new SqlParameter("@MovementItemWmsInfoToXML", strBuilder.ToString())); result = Convert.ToInt32(SqlHelper.ExecuteScalar(SqlHelper.connectionString, CommandType.StoredProcedure, "Proc_InsertMovementItemWmsInfo", param.ToArray()));
LogInfo.GetErrorInfoByExcetion("[移库单拆分]添加总数:“" + list.Count + "”,执行成功数“" + result + "”。\r\n SQL语句:" + strBuilder.ToString());
}
return result;
}
catch (Exception ee)
{
LogInfo.GetErrorInfoByExcetion("异常信息:"+ee.Message);
return result;
}
}

2.SQL脚本:

--====================================================
-- Author:Hamilton Tan
-- Create Date:2014-07-22
-- Description:插入MovementItemWmsInfo信息
--====================================================
CREATE PROCEDURE [dbo].[Proc_InsertMovementItemWmsInfo]
@MovementItemWmsInfoToXML XML
AS
BEGIN
DECLARE @ERROR INT SET @ERROR = 0;
DECLARE @rows INT;
DECLARE @index INT SET @index=1;
DECLARE @StockSerialNumber INT;
DECLARE @SkuCode NVARCHAR(200);
DECLARE @Effect VARCHAR(500);
DECLARE @PropertityStock INT;
DECLARE @UnitPrice numeric(18,2);
DECLARE @shipperid INT;
DECLARE @Tb_MovementItem TABLE
(
[ID] int IDENTITY(1,1),
[SkuCode] [nvarchar](200) NULL,
[MovenmentCode] [nvarchar](200) NULL,
[Effect] [varchar](500) NULL,
[Skunum] [int] NULL,
[PropertityStock] [int] NULL,
[PromotionCode] [nvarchar](200) NULL,
[StockoutCount] [int] NULL,
[StockSerialNumber] [int] NULL,
[UnitPrice] [numeric](18, 3) NULL,
[ShipperId] [int] NULL
);
--解析移库单MovementItemWmsInfo的XML信息
IF @MovementItemWmsInfoTOXML IS NOT NULL
BEGIN
BEGIN TRY
INSERT @Tb_MovementItem
SELECT
R.c.value('@SkuCode','nvarchar(200)'),
R.c.value('@MovenmentCode','nvarchar(200)'),
R.c.value('@Effect','varchar(500)'),
R.c.value('@Skunum','int'),
R.c.value('@PropertityStock','int'),
R.c.value('@PromotionCode','nvarchar(200)'),
R.c.value('@StockoutCount','int'),
R.c.value('@StockSerialNumber','int'),
R.c.value('@UnitPrice','numeric(18,2)'),
R.c.value('@ShipperId','int')
FROM @MovementItemWmsInfoTOXML.nodes('MovementItemWmsInfoTO') R(c) --R为行(Row),c为列(Column),
/*
也可以这样写
SELECT
Y.x.value('@SkuCode','nvarchar(200)'),
Y.x.value('@MovenmentCode','nvarchar(200)'),
Y.x.value('@Effect','varchar(500)'),
Y.x.value('@Skunum','int'),
Y.x.value('@PropertityStock','int'),
Y.x.value('@PromotionCode','nvarchar(200)'),
Y.x.value('@StockoutCount','int'),
Y.x.value('@StockSerialNumber','int'),
Y.x.value('@UnitPrice','numeric(18,2)'),
Y.x.value('@ShipperId','int')
FROM @MovementItemWmsInfoTOXML.nodes('MovementItemWmsInfoTO') Y(x) --R为行(Row),c为列(Column),
*/
/*
<Rows>
<Row Name="1" Value="">abcde</Row>
<Row Name="2" Value="">abcde</Row>
</Rows> SELECT
X.y.value('@Name','nvarchar(200)'), 为1
X.y.value('Row[1]','nvarchar(200)')为abcde
FROM @MovementItemWmsInfoTOXML.nodes('MovementItemWmsInfoTO') X(y)
*/ END TRY
BEGIN CATCH
SET @ERROR =-1;
END CATCH --获取总记录数
SELECT @rows = COUNT(1) FROM @Tb_MovementItem --循环处理
while(@rows>0)
begin
select @StockSerialNumber=StockSerialNumber,@SkuCode=SkuCode,@Effect=Effect
,@PropertityStock=PropertityStock,@UnitPrice= UnitPrice,@shipperid= ShipperId from @Tb_MovementItem where ID=@index -- 不能出现StockSerialNumber,SkuCode ,Effect,PropertityStock,UnitPrice,ShipperId相同的记录
IF NOT EXISTS (select 1 from MovementItemWmsInfo where StockSerialNumber=@StockSerialNumber and SkuCode = @SkuCode and Effect = @Effect
and PropertityStock = @PropertityStock and UnitPrice = @UnitPrice and ShipperId = @shipperid)
BEGIN
--插入数据
INSERT INTO [MovementItemWmsInfo]([SkuCode],[MovenmentCode],[Effect],[Skunum],[PropertityStock],[PromotionCode],[StockoutCount],[StockSerialNumber],[UnitPrice],[ShipperId])
SELECT [SkuCode],[MovenmentCode],[Effect],[Skunum],[PropertityStock],Replace([PromotionCode],'%','&'),[StockoutCount],[StockSerialNumber],[UnitPrice],[ShipperId] FROM @Tb_MovementItem
END
set @rows=@rows-1;
set @index=@index+1;
end
END select @Error; END

C# 如何通过拼接XML调用存储过程来优化系统性能的更多相关文章

  1. CSharp 如何通过拼接XML调用存储过程来查询数据

    每查询数据,需要访问一次数据库,这样会影响性能:如果把查询的数据拼接成XML形式,作为一个参数整体传给存储过程来处理,这只访问数据库一次,执行速度会快很多. 1.C#代码如下: /// <sum ...

  2. Mybatis之基于XML的调用存储过程与手动回滚事务

    一.调用存储过程 一.返回单个值 1.存储过程准备 这里先创建一个存储过程,传入参数为age,传出参数为count.然后先测试一下是否正确. CREATE DEFINER=`root`@`localh ...

  3. FineReport调用存储过程

    "总结一下本人在项目中遇到的问题,如何在数据库表名未知且作为一种查询条件的情况下查询出数据集,仅能通过FineReport+Oracle实现. 首先分析这个问题的条件和要求: 条件:只有一个 ...

  4. myabatis oracle 调用存储过程返回list结果集

    Mapper.xml 配置 <resultMap type="emp" id="empMap"> <id property="emp ...

  5. IBatis.Net使用总结(四)-- IBatis 调用存储过程

    IBatis 调用存储过程 http://www.cnblogs.com/jeffwongishandsome/archive/2010/01/10/1543219.html http://www.c ...

  6. MyBatis学习总结(六)——调用存储过程(转载)

    本文转载自:http://www.cnblogs.com/jpf-java/p/6013518.html 一.提出需求 查询得到男性或女性的数量, 如果传入的是0就女性否则是男性 二.准备数据库表和存 ...

  7. MyBatis入门学习教程-调用存储过程

    一.提出需求 查询得到男性或女性的数量, 如果传入的是0就女性否则是男性 二.准备数据库表和存储过程 create table p_user( id int primary key auto_incr ...

  8. Java和Ibatis调用存储过程并取得返回值详解

    Java和Ibatis调用存储过程并取得返回值详解 2011-07-19 17:33 jiandanfeng2 CSDN博客 字号:T | T 本文主要介绍了Java和Ibatis调用存储过程的方法, ...

  9. Spring JdbcTemplate 调用存储过程

    遇到调用存储过程的业务,以前有用过,但不是用Spring的 JdbcTemplate去做的,这次是在一个已经有的SpringMVC框架的项目下写处理存储过程的. 参考网络中的方法,在实际操作中遇到两个 ...

随机推荐

  1. ZOJ2006 (最小表示法)

    var s:ansistring; cas:longint; function minp(st,len:longint):longint; var p1,p2,k,tmp:longint; begin ...

  2. HDU 4460

    http://acm.hdu.edu.cn/showproblem.php?pid=4460 水题一道,oj时间卡的非常奇怪,把spfa的queue开成全局卡线过,别的全挂了,迪杰斯特拉的手写堆都超时 ...

  3. C/C++学习之路----volatile

    因为经常看见volatile这个关键词,想想自己对这个volatile也不是很清楚,仅仅知道它表明变量是易于变化的和防止编译器优化.所以就在网上找了一些其他道友对于volatile的理解,仔仔细细看了 ...

  4. 如何配置magento免运费商品方法

    作为magento电商来说,免运费是一种常见的促销手段,要让产品成为免运费对magento来说并不难,后台操作即可完成. 首先,我们要建立一个新的产品属性. catalog->attribute ...

  5. convert转化成特定日期格式

    CONVERT() 函数可以用不同的格式显示日期/时间数据. CONVERT(data_type(length),data_to_be_converted,style) 例子: CONVERT(VAR ...

  6. 文件夹差异文件对比工具 meld

    /***************************************************************************************** * 文件夹差异文件 ...

  7. html5实现饼图和线图-我们到底能走多远系列(34)

    我们到底能走多远系列(34) 扯淡: 送给各位一段话:     人生是一个不断做加法的过程     从赤条条无牵无挂的来     到学会荣辱羞耻 礼仪规范     再到赚取世间的名声 财富 地位    ...

  8. 总结 output 用法

    第一种用法 返回受 INSERT.UPDATE 或 DELETE 语句影响的每行的信息,或者返回基于上述每行的表达式.这些结果可以返回到处理应用程序, 以供在确认消息.存档以及其他类似的应用程序要求中 ...

  9. spring学习笔记---第三方SDK(Rest API)和Jaskson的巧用

    前言: 其实我以前一直不懂电商, 以及电商中所涉及的业务概念. 对于SKU等名词, 觉得有些玄乎. 对其背后的数据模型, 也有莫名的未知恐惧感: 庞大而理不清头绪. 不过最近有机会接触了微商(有赞), ...

  10. Codeforces Round #377 (Div. 2) A B C D 水/贪心/贪心/二分

    A. Buy a Shovel time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...