找回密码
 立即注册

QQ登录

只需一步,快速开始

Carl

版主

49

主题

213

帖子

962

积分

版主

Rank: 7Rank: 7Rank: 7

积分
962

活字格认证微信认证勋章

QQ
Carl
版主   /  发表于:2009-12-10 10:27  /   查看:7093  /  回复:0
Post by "Zesson", 2007-01-11, 22:22
-----------------------------------------------------


使用System.Data.Common.DbDataAdapter.Update()方法时出现的问题,给我的教训:当出问题的时候使用SQLProfiler可以很好的判断问题的原因。

出问题的现场:程序分为客户端和服务器端。当程序开启的时候,会执行一种数据同步的操作,把远程的一个SQL Server数据库的数据Download并同步到本地,使得本地的MDB数据库是远程SQLServer数据库的一个子集。用这个MDB数据库作为本地程序的一个缓冲。以提高程序的性能。

原始程序中用System.Data.Common.DbDataAdapter.Update()这个方法Update一个DataSet。原来这段程序一直运行正常。最近,客户有一个新需求,需要改动数据同步的逻辑,让一个同步到本地的字段进行一次加密。Server的数据是原始数据,同步到本地MDB的数据是加密过一次的数据。程序测试了一段时间一直没有问题。当快要发布的时候,报了一个Bug。说User信息不能更新。跟踪客户端发给服务器端的User信息的DataSet没有问题是更改过的新数据。跟踪服务器端收到的DataSet,也是更新过的正确数据。但是就是不能更新数据。这个太奇怪了。

后来所以点都查了,所有问题都集中到System.Data.Common.DbDataAdapter. Method (DataSet)这个方法的调用上。就是这个方法调用了没有起作用,才产生了这个Bug。MSDN对这个方法的介绍是:Calls the respective INSERT, UPDATE, or DELETE statements for each inserted, updated, or deleted row in the specified DataSet. 估计这个方法的下面也是执行一段特定的SQL。 用SQLProgiler跟踪发现这个方法会执行exec sp_executesql N'UPDATE users SET Column1 = @p1…. , WHERE ( (Column4 = @p4) AND …', N'@p1 nvarchar(4000),@p2 nvarchar(4000),@p3 nvarchar(4000),@p4 uniqueidentifier,…. ', @p1 = N'user1', @p2 = N'user1', @p3 = N' user1p3',…. 这样一种SQL。 把这段SQL放在 SQL Query Analyzer中执行后确实没有更新数据。就是这段SQL的问题,导致了不能更新数据。是Where语句不能找到一条确定数据。由于发给服务器的数据是从MDB中取出来的,并且修改了部分内容的DataSet。而Server是要更新的服务器数据。Where语句中的一个字段正是同步到本地被加密过一次的内容,而服务器是原始内容产,由于用户没有改这个字段的内容,所以被拼入了Where语句。生了数据找不到的错误。


Reply by "SmiletotheLife", 2007-01-12, 10:02
-----------------------------------------------------

.Net提供的DBDataAdapter.Update方法是我认为最不成功,影响又十分恶略的方法之一。由他自动拼成的SQL Script的Where语句,把原值(从DB中读取时的值)每一个字段作为Where语句的过滤条件。这样只要在从取数据到更新数据这段时间内,数据库中的这条记录的任意一个字段值发生变化,Update语句就会因找不到纪录失效。(当然还有效率的问题,每个字段的值进行比较,效率可想而知。)


3年前,我曾反编译DBDataAdapter.Update()方法,想要找到.Net拼装SQL Script的逻辑,看看有没有修改可能,结果发现微软把这段逻辑隐藏掉了。开发人员没机会组装更新语句,而且该方法只能用于单Sql Server,对于跨SQL Server的更新也办不到。

也就是说.NET的DataAdapter.Update方法即不支持并发,也不能跨Server执行,只能做个单机版的程序自己玩玩。而这些特征是商用数据库系统最常见的Case。 微软产品的易用和不专业由此可见一斑。

后来的解决方案是使用Update Command,自己写Sql语句,但毕竟不方便。

0 个回复

您需要登录后才可以回帖 登录 | 立即注册
返回顶部