首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

adoquery参数为汉字,有时候有结果,有时候没有。怎么处理啊 。

2012-03-23 
adoquery参数为汉字,有时候有结果,有时候没有。。怎么办啊 。。在线等啊sql如下:selecttop25*fromT_歌曲信息wh

adoquery参数为汉字,有时候有结果,有时候没有。。怎么办啊 。。在线等啊
sql   如下:
select   top   25   *   from   T_歌曲信息  
where   歌曲名称   like   '% '+   (:x)+ '% '   and   歌曲代码  
not   in(select   歌曲代码  
from(select   top   0   *   from   T_歌曲信息   where   歌曲名称   like   '% '+   (:KTVx)+ '% ')temptable)

其中有俩参数,x和KTVx

ADOQuerySelect.Parameters.ParamValues[ 'x ']   :=   '我 ';
ADOQuerySelect.Parameters.ParamValues[ 'KTVx ']   :=   '我 ';

如上,当我给这俩个参数传入参数为一个汉字的时候,查询结果为空(当然实际是有值的),当我传入俩个汉字的时候,比如‘我爱’,结果就出来了,
同样,输入三个汉字又没有结果了,四个又有了,
也就是双数的汉字可以,单数的汉字个数就不可以。。
请问是什么问题啊。。
很着急。。在线等



[解决办法]
当对TParameter的Value属性赋值时,同时会设置Size属性,用来表示Value的长度,而取Size时是取WideString的长度,如果传入中文“歌曲名称”,Size=4,而不是8,最后下到数据库的SQL中只有“歌曲”两个字。
具体可参见ADODB单元TParameter.SetValue中语句NewSize := VarDataSize(NewValue);
function VarDataSize(const Value: OleVariant): Integer;
begin
if VarIsNull(Value) then
Result := -1
else if VarIsArray(Value) then
Result := VarArrayHighBound(Value, 1) + 1
else if TVarData(Value).VType = varOleStr then
begin
Result := Length(PWideString(@TVarData(Value).VOleStr)^);
if Result = 0 then
Result := -1;
end
else
Result := SizeOf(OleVariant);
end;
解决方法:
1.修改ADODB中代码将Result := Length(PWideString(@TVarData(Value).VOleStr)^);
改为Result := Length(PAnsiString(@TVarData(Value).VOleStr)^);
2.在ADOQuery的BeforeOpen事件中重置TParameter的Size属性
procedure TForm1.ADOQuery1BeforeOpen(DataSet: TDataSet);
var
i: integer;
begin
with (DataSet as TCustomADODataSet) do
for i := 1 to Parameters.Count do
Parameters.Items[i - 1].Size := Length(Parameters.Items[i - 1].Value);
end;
[解决办法]
“当对TParameter的Value属性赋值时,同时会设置Size属性,用来表示Value的长度,而取Size时是取WideString的长度,如果传入中文“歌曲名称”,Size=4,而不是8,最后下到数据库的SQL中只有“歌曲”两个字。”

不敢苟同。sql server中存储的汉字也是一个汉字占用一个单位,select len( '汉 '),结果一定为1,

所以我觉得问题是出在:歌曲名称中包含不可视字符,如tab之类,请楼主试试将查不出来的记录从数据库后台直接删除歌曲名称,再重新手动输入,再试试。

另外我记得在sql server 2K里转到Sql Server 2005有一个数据类型在做转换时也会出问题。不记得具体是哪个了
[解决办法]
楼上的兄弟,有两个问题可能要搞清楚
一、Delphi和SQL Server根本不是一回事
SQL Server帮助中关于LEN函数功能写的很明确:LEN 返回给定字符串表达式的字符(而不是字节)个数,其中不包含尾随空格。
SQL Server中LEN函数取的是字符数,它会自动判断字符是单字节还是双字节。
在SQL Server中如果想取字符串的字节数可以用函数:DATALENGTH 返回任何表达式所占用的字节数。

二、Delphi中ADO的实现
大家应该都知道,Delphi中对ADO的实现,只是对微软ADO的封装,微软的ADO是一个COM对象。
对于Parameter的处理,最后只是作为COM接口的参数传入COM中处理。
具体可参才ADODB单元中TADOCommand.Execute方法:
function TADOCommand.Execute(var RecordsAffected: Integer;
const Parameters: OleVariant): _Recordset;
var
VarRecsAffected: OleVariant;
begin
SetConnectionFlag(cfExecute, True);
try
Initialize;
Result := CommandObject.Execute(VarRecsAffected, Parameters,
Integer(CommandObject.CommandType) + ExecuteOptionsToOrd(FExecuteOptions));
RecordsAffected := VarRecsAffected;
finally
SetConnectionFlag(cfExecute, False);
end;
end;
查找微软MSDN中关于ADO的帮助,可以看到对Parameter的Size属性的描述:表示 Parameter 对象的最大大小(按字节或字符)。具体在COM中对Parameter的Size属性的处理是按字节还是字符,恐怕只有问微软了。

关于ADO参数中文问题决不是包含不可见字符那么简单。

热点排行