Delphi查询多参数

时间:2017-12-22 08:42:38

标签: delphi parameters

我试图通过此代码使用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
我应该怎么做,使查询返回结果,如果其中一个或两个都有一个值??

感谢。

4 个答案:

答案 0 :(得分:1)

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

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;

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

答案 1 :(得分:0)

您可以执行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使用)

答案 2 :(得分:0)

你需要提防Null的测试,正如其他人所警告的那样,但还有更多内容 而不仅仅是将参数值设置为Null。

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

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,否则使用SQL明确指定name列为空。

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

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

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

答案 3 :(得分:0)

根据编辑框是否为空来动态构建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;