用ado+msserver2000+汉字查询时遇到的问题 ( 积分: 50 )

  • 主题发起人 主题发起人 abcdman
  • 开始时间 开始时间
A

abcdman

Unregistered / Unconfirmed
GUEST, unregistred user!
代码的主体部分(实际的代码要更复杂,测试:delphi5)<br>方式一<br>sql.add('select&nbsp;czy&nbsp;from&nbsp;posxsd&nbsp;where&nbsp;czy&nbsp;like&nbsp;:v0');<br>parameters[0].value:='张三';<br>方式二<br>SQL.Add(&nbsp;'select&nbsp;czy&nbsp;from&nbsp;(select&nbsp;czy&nbsp;from&nbsp;posxsd&nbsp;where&nbsp;czy&nbsp;like&nbsp;:v0&nbsp;)&nbsp;as&nbsp;sswe');<br>parameters[0].value:='张三';<br>用方式一查询时,有多条记录,但用方式二查询时,没有记录.在事件查看器中发现,方式一中变量@p1&nbsp;varchar(50),而方式二中变量@p1&nbsp;varchar(2),如果数据库改为access则二种方式都可以执行,且结果一样,有多条记录.<br>这是怎么会事呢??
 
delphi解析汉字有问题,好像是当成单字节的,你可以在赋值时指定大小即可。
 
因为SQL语句内检测“'”,检测到一个的时候默认语句结束,可试着在语句的前后个使用“'''”
 
parameters[0].value:='张三';<br>parameters[0].size:=length('张三');
 
parameters[0].value:='张三';<br>parameters[0].size:=length('张三');&nbsp;&nbsp;<br>这个我测试了,可行,谢谢.(继续讨论一下,最后给分)<br>但为什么用access数据库时,不会出现这样的问题呢,我测试时,access没有这样的错误.
 
在TParameter.SetValue过程中有如下代码<br>&nbsp;&nbsp;if&nbsp;DataType&nbsp;in&nbsp;SizedDataTypes&nbsp;then<br>&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;NewSize&nbsp;:=&nbsp;VarDataSize(NewValue);<br>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(Size&nbsp;=&nbsp;0)&nbsp;or&nbsp;(NewSize&nbsp;&gt;&nbsp;Size)&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Size&nbsp;:=&nbsp;NewSize;<br>&nbsp;&nbsp;end;<br><br>函数VarDataSize实现如下<br>function&nbsp;VarDataSize(const&nbsp;Value:&nbsp;OleVariant):&nbsp;Integer;<br>begin<br>&nbsp;&nbsp;if&nbsp;VarIsNull(Value)&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;Result&nbsp;:=&nbsp;-1<br>&nbsp;&nbsp;else&nbsp;if&nbsp;VarIsArray(Value)&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;Result&nbsp;:=&nbsp;VarArrayHighBound(Value,&nbsp;1)&nbsp;+&nbsp;1<br>&nbsp;&nbsp;else&nbsp;if&nbsp;TVarData(Value).VType&nbsp;=&nbsp;varOleStr&nbsp;then<br>&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;Result&nbsp;:=&nbsp;Length(PWideString(@TVarData(Value).VOleStr)^);&nbsp;&nbsp;//重点<br>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;Result&nbsp;=&nbsp;0&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Result&nbsp;:=&nbsp;-1;<br>&nbsp;&nbsp;end<br>&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;&nbsp;Result&nbsp;:=&nbsp;SizeOf(OleVariant);<br>end;<br><br>注意标示为重点的行,它把中文强制转换成了PWideString()^,导致1个汉字计算长度为1.<br>是什么导致同样的语句,Access和SQL&nbsp;Server的不同表现?<br>也许ADO针对不同的驱动,对OleVariant所存储的双字节字符的处理不同<br>也许SQL&nbsp;Server接受输入的SQL默认为ANSI&nbsp;String,而参数的size指定的值与参数实际占用字节不等,导致参数截断.<br><br>不改源码最简单的解决方法就是参数赋值后再指定参数size了
 
ysai解析的源代码,我懂些<br>可为什么当sql语句是简单语句时(如方式一),查询是有结果的,如果是嵌套语句时(如方式二),查询却没有结果,难道,它们的执行过程不一样吗,size的计算方式不一样吗?
 
呵,等了几天,没人参与这个讨论了,今天一个同事也遇到这样的问题,我把方法给他说了,问题是解决了,可根源我还是不太明白:<br>1.相同的sql语句,access数据库是可查询的,而msserver却不能,如题.<br>2.都是sql语句参数化,简单语句可以查询,而复合语句而不能,这是什么原因.
 
这个不仅与Delphi解析汉字有关,还与MS&nbsp;SQL中字段的Collection有关的。
 
ChrisMao&nbsp;:<br>能不能再详细的说明一下呀,想更了解一些.谢谢啦.
 
这个不仅与Delphi解析汉字有关,还与MS&nbsp;SQL中字段的Collection有关的。&nbsp;<br>这句话怎么理解呢??&nbsp;谁能再深入分析一些
 
后退
顶部