MS Jet中奇怪的问题?

Kanas.net 1.3在紧张的测试中。为了保证数据库支持的中立性,采用SQL标准实现最差的MS Jet(MS Access 2000格式载体,使用ADO.NET的OleDb引擎)。以往这种数据库配置用得比较少,对其特异性严重掌握不够,导致排错效率不高。
其中有一个TestCase出现的bug狂找了一个小时才发现,真是哭笑不得。

大家看看以下两个SQL语句,相同的指令,不同的结果:
命令文本:update debtors set debit=@P3,searches=@P4 where id=@P2
参数表:
  @P2=16
  @P3=3650
  @P4=520
(所影响的行数为 0 行)
命令文本:update debtors set debit=@P1,searches=@P2 where id=16
参数表:
  @P1=3650
  @P2=520
(所影响的行数为 1 行)
而在Sql Server中则不会出现类似这样的问题。

posted on 2005-08-10 02:12 双鱼座 阅读(1169) 评论(7)  编辑 收藏 网摘

评论

#1楼  2005-08-10 09:05 Teddy's Knowledge Base      

这个是ado oledb驱动的老问题了,传入参数必须按sql中参数出现的顺序,sql不会有这样的问题。不过在ado.net下面,除了sqlserver就都难以避免了,不过好在,一般使用框架时如果sql是由程序动态构造的一般不会出现参数顺序不一致,我原来被这个问题折腾也是在测试用例中:)当时查了一下才发现真的是一个很早就广为流传的问题了,并且不是bug,而是因为oledb支持通用的db,但有很多db本身识别参数的时候不按名称只按顺序的,所以也是没办法的。

其实还有另一个问题:
在sqlserver中:select * from table where param1 = @p1 and param2 = @p2 and param3 = @p1
@p1=1
@p2=2
是完全没问题的

但是如果对oledb驱动就不行了,必须以三个参数对待,同样是因为oledb只按参数索引顺序,不按名称来为参数赋值。   回复  引用  查看    

#2楼  2005-08-10 09:42 Teddy's Knowledge Base      

谈到sql语法差异,我再说两点access和sqlserver中的不同,希望对你所有帮助:

一个是access不支持select top 0 from table这样的语句,注意top后面的数字不能是0,如果大于0没问题,但是sqlserver下是没问题的。发现这个问题是在我的一个基于代码生成的框架中自动通过形如select columns from table这样的简单语句为每个实体类生成形如select top {0} ... where not in (select top {1}...)...这样的通用分页查询语句,当区第一页数据的时候,not in 后面的top {1}中,{1}将会是0,这时access就会报错,所以最后对取第一页的情况我只能区别对待。

再一个是像select * from (select * from table)这样的语法,在access下没问题,在sqlserver下则必须在后面为动态表指定一个别名语法才是正确的:select * from (select * from table) aliasname,aliasname可以是任意的单词。之所以使用这样的语句同样是为了通过形如select columns from table这样的简单语句构造分页语句时用来返回所有的记录总数:select count(ID) from (select columns from table),当然这样是偷懒,性能上应该会有部分影响的,count的时候尽可能还是建议直接用select count(ID) from table这样的句法。   回复  引用  查看    

#3楼 [楼主] 2005-08-10 12:54 双鱼座      

@Teddy's Knowledge Base:
非常感谢你的提示,你的提示对我非常重要。我没有使用类似Hibernate中的Dialect体系,我觉得在.net下的应用背景与java下相差很大。在IDbProvider中我只定义了一个参数名修饰。
如果是参数顺序的问题,我可以在build sql的时候保证定义次序与参数次序完全一致。事实上,在sql builder中,参数名称集合是一张表,参数值中另外一张表,而真正生成IDataParameter是运行时才做的,所以调整顺序并不困难。   回复  引用  查看    

#4楼  2005-08-10 14:43 蛙蛙池塘      

没错,access确实支持参数化查询,但是你设置的参数名不会有用的,是按顺序赋值的,上次我都折腾了好一阵子.   回复  引用  查看    

#5楼  2005-08-10 18:25 fancyf [未注册用户]

Access不支持命名的参数

用标准的方式就不会发生误解了:
update debtors set debit=?,searches=? where id=?
然后按顺序添加参数   回复  引用    

#6楼 [楼主] 2005-08-10 20:03 双鱼座      

非常感谢蛙蛙池塘和fancyf共享你们的经验...   回复  引用  查看    

#7楼  2005-08-16 18:46 IT      

ACCESS不支持多个语句一起执行

delete * from table;
insert into table(field)values(value);
而在SQL SERVER明显能执行   回复  引用  查看    





标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
Google站内搜索


China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
近千种 9-95 新二手计算图书火热销售中!

相关文章:

相关链接:
 

导航

<2005年8月>
31123456
78910111213
14151617181920
21222324252627
28293031123
45678910

统计

与我联系

搜索

 

常用链接

留言簿(31)

我参与的团队

我的标签

随笔档案

文章分类

相册

芸芸众生

最新评论

  • 1. re: ORM之硬伤
  • @田景
    没有人说ORM是万能的,也没有人说什么都使用ORM。
    我看了你的“简单的ORM”,不过真的很像个玩具,难怪你欢迎我下载玩玩了。
  • --双鱼座
  • 2. re: ORM之硬伤
  • ORM不是万能的,我也不会赞成在项目中什么都使用ORM。有时候使用ORM可能导致一定的学习成本。 我曾自己实现了一个简单的ORM,可供朋友们参考参考。同时也写了几篇配套Blog文,介绍了这个东西,欢迎...
  • --田景

阅读排行榜

评论排行榜