sql 如下:
select top 25 * from T_歌曲信息 
where 歌曲名称 like '%'+ (:x)+'%' and 歌曲代码 
not in(select 歌曲代码 
from(select top 0 * from T_歌曲信息 where 歌曲名称 like '%'+ (:KTVx)+'%')temptable)其中有俩参数,x和KTVxADOQuerySelect.Parameters.ParamValues['x'] := '我';
ADOQuerySelect.Parameters.ParamValues['KTVx'] := '我';如上,当我给这俩个参数传入参数为一个汉字的时候,查询结果为空(当然实际是有值的),当我传入俩个汉字的时候,比如‘我爱’,结果就出来了,
同样,输入三个汉字又没有结果了,四个又有了,
也就是双数的汉字可以,单数的汉字个数就不可以。。
请问是什么问题啊。。
很着急。。在线等

解决方案 »

  1.   

    where ( ...  )  and ( ... not in ...)...
      

  2.   

    sql语句是绝对没有问题的 参数为奇数个汉字的时候可以查询出结果,可为偶数的时候就没有
      

  3.   

    可能是数据库的字符编码问题,比如:ascii和unioncode的编码占的字符数就不一样!
    只是猜想!
      

  4.   

    当对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;
      

  5.   

    “当对TParameter的Value属性赋值时,同时会设置Size属性,用来表示Value的长度,而取Size时是取WideString的长度,如果传入中文“歌曲名称”,Size=4,而不是8,最后下到数据库的SQL中只有“歌曲”两个字。”不敢苟同。sql server中存储的汉字也是一个汉字占用一个单位,select len('汉'),结果一定为1,所以我觉得问题是出在:歌曲名称中包含不可视字符,如tab之类,请楼主试试将查不出来的记录从数据库后台直接删除歌曲名称,再重新手动输入,再试试。另外我记得在sql server 2K里转到Sql Server 2005有一个数据类型在做转换时也会出问题。不记得具体是哪个了
      

  6.   

    楼上的兄弟,有两个问题可能要搞清楚
    一、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参数中文问题决不是包含不可见字符那么简单。
      

  7.   

    MDB的数据库中字符型存储都是Unicode编码,大概微软数据库中字符型都是Unicode编码。