首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 利用 DBGrid 實現靈活多條件查詢:可視化 SQL 構建器思路

     編輯:Delphi

問題痛點

傳統多條件查詢需程序員為每種組合寫 SQL,或動態拼接字符串極易出錯。用戶界面往往只提供 2-3 個固定條件。本文提出利用 TDBGrid 的 PickList 特性,構建類 Excel 的條件編輯表格,用戶可任意增刪行、選擇字段/操作符/邏輯連接詞,程序自動生成標準 SQL,實現真正的「無限條件、可視化、用戶可微調」查詢。

核心組件佈局

  • Table1:數據源表 (如 Customer)
  • Table2 (對應 CxComm.db):條件存儲表,結構:FieldName (字段名), Operator (操作符), Value (值), Logic (AND/OR)
  • DBGrid2:綁定 Table2,設置列 PickList 實現下拉選擇
  • Query1:執行生成的 SQL
  • Memo1:顯示生成的 SQL,允許用戶手工修改 (如加括號調整優先級)
  • 三個按鈕:設置 Grid、生成 SQL、執行查詢

關鍵代碼實現

1. 設置 DBGrid 列選項

procedure TfrmDBGrid.MySetDBGrid(sTable: TTable; tjDBGrid: TDBGrid);
var i: Byte;
begin
  if not sTable.Active then sTable.Open;
  tjDBGrid.Columns[0].PickList.Clear;
  for i := 0 to sTable.FieldCount - 1 do
    tjDBGrid.Columns[0].PickList.Add(sTable.Fields[i].FieldName); // 字段名列

  tjDBGrid.Columns[1].PickList.Text := '='#13#10'<>'#13#10'>'#13#10'>='#13#10'<'#13#10'<='; // 操作符列
  tjDBGrid.Columns[3].PickList.Text := 'AND'#13#10'OR'; // 邏輯列
end;

2. 生成 SQL 核心邏輯

function TfrmDBGrid.MyCreate_SQL(sTable, tjTable: TTable; tjQuery: TQuery): Boolean;
var i: Byte; lsDate: TDateTime; sLj, sFilter, sFieldName: string;
begin
  Result := True;
  with tjQuery.SQL do
  begin
    Close; Clear;
    DatabaseName := sTable.DatabaseName;
    Add('Select * from ' + sTable.TableName);
  end;

  with tjTable do
  begin
    if not Active then Open;
    if IsEmpty then begin ShowMessage('未選擇篩選條件!'); Exit; end;
    tjQuery.SQL.Add('Where ');
    sFilter := ''; First;
    for i := 0 to RecordCount - 1 do
    begin
      sLj := Fields[3].AsString; // Logic (AND/OR)
      sFilter := sFilter + '(';
      sFilter := sFilter + Fields[0].AsString + Fields[1].AsString; // Field + Operator
      sFieldName := Fields[0].AsString;
      case sTable.FieldByName(sFieldName).DataType of
        ftString: sFilter := sFilter + QuotedStr(Fields[2].AsString); // 字符串加引號
        ftFloat, ftAutoInc, ftSmallInt, ftInteger, ftCurrency:
          sFilter := sFilter + Fields[2].AsString; // 數值直接拼接
        ftDate:
          try
            lsDate := StrToDate(Fields[2].AsString);
            sFilter := sFilter + QuotedStr(FormatDateTime('mm/dd/yyyy', lsDate)); // 日期格式化
          except ShowMessage('錯誤的日期格式!'); Result := False; Break; end;
      else
        // 可擴展其他類型
      end;
      sFilter := sFilter + ')';
      if sLj <> '' then
      begin
        if RecNo <> RecordCount then sFilter := sFilter + ' ' + sLj + ' '; // 非最後行加邏輯
      end else Break;
      Next;
    end;
    tjQuery.SQL.Add(sFilter);
  end;
end;

3. 執行查詢 (支持用戶修改 SQL)

procedure TfrmDBGrid.Button3Click(Sender: TObject);
begin
  with Query1, SQL do
  begin
    Close;
    if Memo1.Modified then SQL := Memo1.Lines; // 用戶可能在 Memo 中手改 SQL
    try
      Open; // 用 Open 而非 ExecSQL,因為是 SELECT
    except
      MessageBeep(0);
      Application.MessageBox('錯誤的 SQL 語句!', '確認', MB_OK + MB_ICONSTOP);
      Close;
    end;
  end;
end;

優勢總結

特性傳統固定條件本方案 (DBGrid 條件表)
條件數量固定 1-3 個無限制 (表格行數動態增減)
字段選擇預設下拉框自動讀取數據源所有字段
操作符硬編碼統一配置 (=, <>, >, >=, <, <=)
邏輯組合固定 AND/OR每行獨立指定 AND/OR
用戶干預不可見Memo 顯示 SQL,可手工加括號/調整
代碼維護每新增查詢改代碼通用邏輯,零代碼擴展新表

實際部署建議

  1. 為 Table2 增加「新增行」「刪除行」按鈕 (調用 Append/Delete),提升易用性。
  2. 條件表 Table2 可設計為內存表 (TClientDataSet / TMemTable) 無需物理文件。
  3. 日期格式化根據數據庫調整 (Access 'mm/dd/yyyy', SQL Server 'yyyy-mm-dd', Oracle 'dd-mon-yy')。
  4. 大數據量時建議在生成 SQL 前檢查是否有索引支持,避免全表掃描。

總結

將「查詢條件」數據化、表格化,利用 DBGrid.PickList 實現可視化編輯,再通用算法生成 SQL,是構建靈活查詢界面的經典模式。此思想不限於 Delphi,同樣適用於 C# DataGridView、Web 前端表格組件等場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved