Delphi查询多参数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Delphi查询多参数相关的知识,希望对你有一定的参考价值。

我试图通过此代码使用ADOQuery对dataBase表进行查询

begin
    adoquery1.close;
    adoquery1.sql.clear;
    adoquery1.sql.add(SELECT * FROM Table WHERE name=:name and tel=:tel);
    adoquery1.Parameters.ParamByName('name').Value:= edtName.text;
    adoquery1.Parameters.ParamByName('tel').Value:= edtTel.text;
    adoquery1.open;
end;

现在,如果我设置edtName和edtTel,则查询返回结果 但是如果edtName或edtTel为空怎么办? 查询将返回null 我应该怎么做,如果其中一个或两个都有一个值,使查询返回结果?

谢谢。

答案

你应该检查文本框是否为空;

begin
    adoquery1.close;
    adoquery1.sql.clear;
    adoquery1.sql.add(SELECT * FROM Table WHERE 1=1 );
    if edtName.text <> '' then
      Begin
        adoquery1.sql.add(' And name=:name ');
        adoquery1.Parameters.ParamByName('name').Value:= edtName.text;
      End;
    if edtTel.text <> '' then
      Begin
        adoquery1.sql.add(' And tel=:tel ');
        adoquery1.Parameters.ParamByName('tel').Value:= edtTel.text;
      End;
    adoquery1.open;
end;

注意:如果它们都为空,结果将显示所有记录。

另一答案

您可以执行sddk建议的操作(根据TEdits值构建SQL)或

您可以为这些参数指定NULL值

begin
    adoquery1.close;
    adoquery1.sql.clear;
    adoquery1.sql.add('SELECT * FROM Table WHERE name=:name and tel=:tel');
    if edtName.text <> '' then begin
        adoquery1.Parameters.ParamByName('name').Value:= edtName.text;
    end else begin
        adoquery1.Parameters.ParamByName('name').Value:= Null;
    end;
    if edtTel.text <> '' then begin
        adoquery1.Parameters.ParamByName('tel').Value:= edtTel.text;
    end else begin
        adoquery1.Parameters.ParamByName('tel').Value:= Null;
    end;
    adoquery1.open;
end;

不要忘记在您的使用列表中添加System.Variants(用于Null使用)

另一答案

正如其他人所警告的那样,你需要注意对Null的测试,但除了仅仅将参数值设置为Null之外,还有更多内容。

假设您有一个带有name列的Sql Server表,并且许多行具有该列的空条目。然后考虑这段代码:

procedure TForm1.Button1Click(Sender: TObject);
begin
  if cbUseNullParam.Checked then begin
    AdoQuery1.SQL.Text := 'select * from MATable1 where name = :name';
    AdoQuery1.Parameters.ParamByName('name').Value := Null;
  end
  else
    AdoQuery1.SQL.Text := 'select * from MATable1 where name is Null';
  AdoQuery1.Open;
end;

换句话说,如果选中cbUseNullParam复选框,则将name参数设置为Nll,否则使用明确指定name列为空的SQL。

打开Sql Server Management Studio的Profiler,观察发生在服务器上的内容以及连接到AdoQuery1的DBGrid显示的内容,这就是它。

选中cbUseNullParam时,查询无法返回具有Null name的行。未选中时,将返回正确的行。

换句话说,无论如何都要对MS Sql Server使用ADO,如果要查找给定列具有Null状态的行,则需要使用明确指出该列为空的Sql,而不是依赖于设置该列的AdoQuery参数为Null。所以,如果你的情况,你实际上需要四个版本的SQL(两个列为Null,一个为Null,一个为Null,另一个为Null)。

另一答案

根据编辑框是否为空动态构建SQL,例如:

var
  hasName, hasTel: Boolean;
  whereClause: string;
begin
  ADOQuery1.Close;
  ADOQuery1.SQL.Clear;

  ADOQuery1.SQL.Add('SELECT * FROM Table');

  hasName := edtName.GetTextLen > 0;
  hasTel := edtTel.GetTextLen > 0;

  if hasName or hasTel then
  begin
    whereClause := 'WHERE ';

    if hasName then
      whereClause := whereClause + 'name=:name';

    if hasTel then
    begin
      if hasName then
        whereClause := whereClause + ' and ';    
      whereClause := whereClause + 'tel=:tel';
    end;

    ADOQuery1.SQL.Add(whereClause);

    if hasName then
      ADOQuery1.Parameters.ParamByName('name').Value := edtName.Text;

    if hasTel then
      ADOQuery1.Parameters.ParamByName('tel').Value := edtTel.Text;
  end;

  ADOQuery1.Open;
end;

或者,更一般地说:

var
  params: TStringList;
  I: Integer;
begin
  ADOQuery1.Close;
  ADOQuery1.SQL.Clear;

  params := TStringList.Create;
  try
    if edtName.GetTextLen > 0 then
      params.Add('name=' + edtName.Text);

    if edtTel.GetTextLen > 0 then
      params.Add('tel=' + edtTel.Text);

    // other parameters as needed ...

    ADOQuery1.SQL.Add('SELECT * FROM Table');

    if params.Count > 0 then
    begin
      ADOQuery1.SQL.Add('WHERE ' + params.Names[0] + '=:' + param.Names[0]);
      for I := 1 to params.Count-1 do
        ADOQuery1.SQL.Add('AND ' + params.Names[I] + '=:' + param.Names[I]);

      for I := 0 to params.Count-1 do
        ADOQuery1.Parameters.ParamByName(params.Names[I]).Value := params.ValueFromIndex[I];
    end;
  finally
    params.Free;
  end;

  ADOQuery1.Open;
end;

以上是关于Delphi查询多参数的主要内容,如果未能解决你的问题,请参考以下文章

delphi 中用数组作为参数传入sql语句中

delphi多线程参数传递问题

delphi locate多字段查询

Delphi多线程数据库查询(ADO)

终于懂了:Delphi重定义消息结构随心所欲,只需要前4个字节是消息编号就行了,跟Windows消息虽然尽量保持一致,但其实相互没有特别大的关系。有了这个,就有了主动,带不带句柄完全看需要。(代码片段

将参数传递给 TADOStoredProc (Delphi) 的更好方法