FireDAC 中文字段过滤问题

时间:2023-01-08 07:31:26

 当使用 FireDAC Filter  过滤数据的时候,通常这样写:

FDMemTable.Filtered := False;
FDMemTable1.Filter := '姓名=' + string(edtFilter.Text).QuotedString;
FDMemTable.Filtered := True;

将会报错:
[FireDAC][Stan][Eval]-107. Invalid character found [ 姓名 = '张三' ]

解决方法一:字段名称加上书名号[]

FDMemTable1.Filter := '[姓名]=' + string(edtFilter.Text).QuotedString;

解决方法二:通过 OnFilterRecord 事件处理

procedure TForm1.OnMyFilterRecord(DataSet: TDataSet; var Accept: Boolean);
begin
  Accept := DataSet.FieldByName('姓名').AsString = edtFilter.Text;
end;

附上完整代码,如下:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Param, FireDAC.Stan.Error,
  FireDAC.DatS, FireDAC.Phys.Intf, FireDAC.DApt.Intf, Data.DB, FireDAC.Comp.DataSet, FireDAC.Comp.Client,
  FireDAC.Stan.StorageBin, Vcl.StdCtrls, Vcl.Grids, Vcl.DBGrids;

type
  TForm1 = class(TForm)
    grd1: TDBGrid;
    ds1: TDataSource;
    btnFiltered: TButton;
    edtFilter: TEdit;
    procedure btnFilteredClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    Filter: string;
    FDMemTable: TFDMemTable;
    procedure OnMyFilterRecord(DataSet: TDataSet; var Accept: Boolean);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


procedure TForm1.OnMyFilterRecord(DataSet: TDataSet; var Accept: Boolean);
begin
  Accept := Filter.IsEmpty or (DataSet.FieldByName('姓名').AsString = Filter);
end;

procedure TForm1.btnFilteredClick(Sender: TObject);
begin
  Filter := edtFilter.Text;

  FDMemTable.Filtered := False;
  // 方法一
  FDMemTable.Filter := '[姓名]=' + Filter.QuotedString;
  FDMemTable.Filtered := True;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FDMemTable := TFDMemTable.Create(Self);

  with FDMemTable do
  begin
    with FieldDefs do
    begin
      Clear;
      Add('姓名', ftWideString, 50);
      Add('年龄', ftInteger);
    end;
    CreateDataSet;
    AppendRecord(['张三', 35]);
    AppendRecord(['李四', 31]);
    AppendRecord(['王五', 40]);
    // 方法二
    // OnFilterRecord := OnMyFilterRecord;
  end;
  ds1.DataSet := FDMemTable;
end;

end.

FireDAC 中文字段过滤问题

由于开发工具都是洋大人的,对中文支持不是太友好,防止出现不可预料的BUG,建议尽量不要使用中文字段名。