[求助]大量数据处理时只有部分得到更新

yingyuebingya 2010-06-18 10:43:58
一个以前的系统,一个很老的BUG


流程大概是这个样子,用一个Windows服务监控一个txt文件,内容发生改变时启动一个程序。现在这个文件的容量有11M多。

在程序中读入文件转换成XML格式的字符串,传进数据库,调用sp_xml_preparedocument处理传入的XML数据,

然后用游标遍历,先做两个嵌套的IF判断,如果符合条件,则更新数据库中的数据。


现在的问题是,只有部分数据得到了更新。

我做了三次测验,更新的记录条数分别是:245,266,229,

其中还有满足条件的记录三次都没有得到更新,

而我用直接调用执行更新的脚本传入刚才那条记录,记录更新成功。


实在没辙了,想到会不会是数据量太大,在执行的过程中产生了数据遗漏?

以前没碰到过,向各位大大求个建议或者思路 : )
...全文
191 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
llddyy123wq 2010-06-18
  • 打赏
  • 举报
回复
呵呵,是sqlserver的事件跟踪器说错了。
查到传进来的字符串后
你直接拿传进来的xml串到查询分析器中执行,多执行几遍。看看返回的数据是不是一样的。
还有就是要学会调试sql语句。
一个最简单的办法就是一步步的剪切,就是去掉你怀疑的部分,留下可以执行的部分,当然要保证正确。
还要就是要多写写select,方便查看各个变量的值。
我想只要你这么做的,应该能查出什么问题的。
如果存储过程没问题,那只能找你们公司要封装方法的源代码 了。
llddyy123wq 2010-06-18
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 yingyuebingya 的回复:]
堆栈跟踪到了,就是报方法调用的异常

at ******.Business.OM.Inventory.Process.InventorySynchronizeProcess.InsertSynchronizedData(String xml) in
[/Quote]
只能说明是这个封装方法有可能出现问题。
但是既然又数据可以执行成功,说明封装方法出现问题的机率不大,最有可能就是游标循环那块有些代码不代严谨。你好好研究下那些sql语句。前面使用sp_xml_preparedocument我们倒是用过。我还能看明白。后面一堆游标的东西我就不太熟了,看到累。
你在执行的时候,打开sqlserver的事件查看器,调试一下。

捷哥1999 2010-06-18
  • 打赏
  • 举报
回复
完整的异常信息贴出来!
yingyuebingya 2010-06-18
  • 打赏
  • 举报
回复
堆栈跟踪到了,就是报方法调用的异常

at ******.Business.OM.Inventory.Process.InventorySynchronizeProcess.InsertSynchronizedData(String xml) in
捷哥1999 2010-06-18
  • 打赏
  • 举报
回复

还有一个问题,我检查了他的APPLOG,里面报了一个这个异常: nested Exception 。

不知道是什么原因?我 google了好久,没明白这个异常的原因.


原来的人,够晕的,这样的错误记录了有什么用?
           catch(Exception e1)
{
string loadError = e1.ToString();
this.writeLog(loadError);
}


这样记录的就是错误的类型名称!
修改一下,再执行会发现什么错误,贴出来!

           catch(Exception e1)
{
//把错误源和错误发生时的堆栈信息都记录到日志
string loadError = e1.Message+"\r\n"+e1.StackTrace;
this.writeLog(loadError);
}

IceTeeth 2010-06-18
  • 打赏
  • 举报
回复
南无阿弥陀佛
IceTeeth 2010-06-18
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 myhope88 的回复:]

逻辑代码有问题,或者你的存放数据格式不一致
[/Quote]

我做了三次测验,更新成功的记录数分别是:245,266,229,

在此期间,代码和存放数据的文件(为了触发事件,把其中的一条记录中一个字段改为1)未做其他改变,

结果却相差如此之大...
IceTeeth 2010-06-18
  • 打赏
  • 举报
回复
myhope88 2010-06-18
  • 打赏
  • 举报
回复
逻辑代码有问题,或者你的存放数据格式不一致
IceTeeth 2010-06-18
  • 打赏
  • 举报
回复

折磨了我两天了,这个bug已经存在至少两年了,难道注定就无解了吗?
yingyuebingya 2010-06-18
  • 打赏
  • 举报
回复

还有一个问题,我检查了他的APPLOG,里面报了一个这个异常: nested Exception 。

不知道是什么原因?我google了好久,没明白这个异常的原因.
yingyuebingya 2010-06-18
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 computerfox 的回复:]

如果是我,我会这么去解决问题
1、手工执行命令,验证存储过程逻辑的正确性,确定是否存储过程的逻辑问题
2、如果存储过程ok,那么就是调用的问题,有两种原因
调用方传入的参数,本身有问题,导致处理错误
调用方,本身就调用了有限的次数,并不是对所有数据都执行了存储过程
[/Quote]
第一个已经验证了,服务无法更新的数据,手工已成功更新。
第二个问题不确定,他是把xml数据(在格式化成xml以前就有11M多)一次性传入数据库的。
yingyuebingya 2010-06-18
  • 打赏
  • 举报
回复

//脚本里面的,原来开发的人写的
CREATE TABLE [#SyncErrorLog] (
[id] [int] NULL ,
[wNo] [varchar] (10) NULL ,
[pCode] [varchar] (10) NULL ,
[sLoc] [varchar] (10) NULL ,
[sSku] [varchar] (10) NULL ,
[OnHandQty] [int] NULL ,
[UnitFactor] [int] NULL ,
[PickLocation] [varchar] (10) NULL ,
[filter] [varchar] (19) NULL,
[ImportCertNumber] [varchar] (50) NULL,
[CountryOfOrigin] [varchar](3) NULL,
[ErrorDesc] [varchar](100) NULL
) ON [PRIMARY]

--自建的一个表,发生异常时插入错误信息的,因为是循环,所以用了table.
--返回DataSet的原因,应该底层(我看不到了)里面操作数据库的方法
insert into #SyncErrorLog
values(@id,@wNo,@pCode,@sLoc,@sSku,@OnHandQty,@UnitFactor,@PickLocation,@filter,@ImportCertNumber,@CountryOfOrigin,@PRODUCT_ERROR)

捷哥1999 2010-06-18
  • 打赏
  • 举报
回复
如果是我,我会这么去解决问题
1、手工执行命令,验证存储过程逻辑的正确性,确定是否存储过程的逻辑问题
2、如果存储过程ok,那么就是调用的问题,有两种原因
调用方传入的参数,本身有问题,导致处理错误
调用方,本身就调用了有限的次数,并不是对所有数据都执行了存储过程

捷哥1999 2010-06-18
  • 打赏
  • 举报
回复
感觉不太明白为什么要返回数据集?
下面是关键的调用方法:
生成xml文档后,xml数据在sb中,断点调试看看,每次sb都能读取到所有的数据吗?
                xr.WriteEndElement();
errorDS = InventorySynchronizeProcess.InsertSynchronizedData(sb.ToString());
result = true;

另外errorDS 好像只是为了记录错误的信息,还是记录错误的数据?
如果是错误的信息,我觉得不应该让InsertSynchronizedData方法,返回数据集,返回一个错误信息就好了。
所以不是很明白为什么要调用返回数据集的方法:
ds = dataCommand.ExecuteDataset();      

yingyuebingya 2010-06-18
  • 打赏
  • 举报
回复
刚才那个继承自 ServicedComponent
yingyuebingya 2010-06-18
  • 打赏
  • 举报
回复
是一个类,new出来调用方法

public InventorySynchronizeCtrl()
{

}
yingyuebingya 2010-06-18
  • 打赏
  • 举报
回复

//存储过程在这里
<?xml version="1.0" encoding="utf-8" ?>
<DataAccessConfiguration>
<Commands>
<DataCommand Name="OrderManagement.InsertSynchronizedData" HelperAlias="SqlHelper" CommandType="StoredProcedure" CommandTimeout="30">
<CommandText>uspInsertSynchronizedData</CommandText>
<Parameters>
<Parameter Alias="XmlDoc" ParameterName="@sXmlDoc" DbType="String" Direction="Input" />
</Parameters>
<ConnectionString Value="Server=*.*.*.*;UID=sa;PWD=sa;Database=*****;"/>
</DataCommand>
</Commands>
</DataAccessConfiguration>
捷哥1999 2010-06-18
  • 打赏
  • 举报
回复
                    loadFileCtrl = new InventorySynchronizeCtrl();
succeed = loadFileCtrl.LoadFileByStoreProcedure(fileName,LOGFILE);


关键是上面的调用。
InventorySynchronizeCtrl返回什么,代码是?
yingyuebingya 2010-06-18
  • 打赏
  • 举报
回复

//继续
public static DataSet InsertSynchronizedData(string xml)
{
DataSet ds = null;

try
{
using(ConfiguredDataCommand dataCommand = ConfiguredItems.GetDataCommand(CommandPrefix.OrderManagement , CommandName.InsertSynchronizedData))
{
dataCommand.SetParameterValue(CommandParam.XmlDoc , xml);

ds = dataCommand.ExecuteDataset();
}

}
catch (AppException)
{
throw ;
}
catch (Exception ex)
{
throw new SysException(ex.Message);
}
return ds;
}
加载更多回复(9)

110,571

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧