Короткий ответ заключается в том, что вы хотите получить назначение параметров, подобное этому:
FDQuery1.Params[0].AsString := '%a%';
FDQuery1.Open();
при условии, что значение, которое вы хотите сопоставить в своем выражении LIKE, - это просто буква a
. Или, если вы хотите использовать Format
, вы можете сделать что-то вроде этого:
FDQuery1.Params[0].AsString := Format('%%%s%%', [edFilter.Text]);
Причина появления трех знаков ha sh в строке заключается в том, что первый собственный «ускользает» от второй в выражении, вычисляемом форматом, а третий, непосредственно перед 's' объединяется с ним, чтобы действовать как заполнитель для строки, поскольку Format создает ее результат.
Однако, учитывая, что вы не полностью знаком с работой с наборами данных и фильтрацией, я думаю, что вы делаете это излишне сложным для себя по крайней мере в двух отношениях:
FMX + LiveBindings не полностью свободен от ошибок и имеет некоторые причуды, которые могут хорошо встаньте у вас на пути.
Синтаксис для использования оператора LIKE, в котором используются символы ha sh (#
), противоречит использованию знаков ha sh для разрешения параметров в функции Format
. Это, в частности, может сбивать с толку чрезвычайно , особенно когда вы пытаетесь получить синтаксически правильное выражение LIKE, будь то для включения в Sql ваш запрос или в «локальный фильтр», т. Е. тот, который использует свойства Filter
+ Filtered
FDQuery.
Итак, я собираюсь сделать предложение, которое, возможно, изначально может быть нежелательным, а именно провести ваше исследование таких вещей, как фильтрация в приложении VCL , как показано ниже. Настройка займет всего несколько минут, но, вероятно, сэкономит вам время и нервную систему, по сравнению с попытками сделать это правильно в приложении FMX + LiveBinding, которое находится в стадии разработки. Вот как это сделать:
- Создайте новое приложение VCL и добавьте в него эти компоненты.
FDConnection1: TFDConnection;
FDGUIxWaitCursor1: TFDGUIxWaitCursor;
FDQuery1: TFDQuery;
DBGrid1: TDBGrid;
DBNavigator1: TDBNavigator;
DataSource1: TDataSource;
edFilter: TEdit;
btnLocalFilter: TButton;
btnSqlFilter: TButton;
Добавьте приведенный ниже код в файл формы.
Поместите точку останова отладчика в строку
case FilterMode of
и исследуйте поведение приложения, изменяя содержимое элемента управления edFilter и нажимая две кнопки, как только вы адаптировали код к имеющимся у вас данным. Моя использует таблицу авторов, я не могу вспомнить, откуда я ее взял, но, возможно, она была из образца базы данных Pubs для Sql -Server.
Приложение показывает - я уверен, что вы собранные - что вы можете фильтровать данные, отображаемые вашим приложением, либо на стороне сервера, изменив Sql, используемое для получения данных, либо на стороне клиента, используя свойство Filter
FDQuery. Чтобы вы могли легко увидеть, что происходит, Sql для фильтрации на стороне сервера создается путем объединения содержимого edFilter.Text с остальной частью Sql, но в реальной жизни вы не должны никогда делает это из-за уязвимости Sql Injection .
Код
type
TFilterMode = (fmLocal, fmSql);
type
TForm1 = class(TForm)
[...]
public
{ Public declarations }
FilterMode : TFilterMode;
end;
[...]
const
sOrderBy = ' order by lastname, forename';
sSql = 'select * from authors';
sFilteredSql = sSql + ' where lastname like :lastname%';
sLocalFilter = 'lastname like ''%%s%%''';
procedure TForm1.OpenFDQuery;
var
S : String;
begin
if FDQuery1.Active then FDQuery1.Close;
FDQuery1.Params.Clear;
FDQuery1.Filter := '';
FDQuery1.Filtered := True;
case FilterMode of
fmSql : begin
FDQuery1.Sql.Text := '';
// WARNING - don't do this for real - risk of Sql Injection exploit
// use a parameterised query instead - see http://docwiki.embarcadero.com/RADStudio/Rio/en/Using_Parameters_in_Queries
S := 'select * from authors where lastname like ''%' + edFilter.Text + '%''';
FDQuery1.Sql.Text := S;
end;
fmLocal : begin
FDQuery1.Sql.Text := sSql + sOrderBy;
S := 'lastname like ''%' + edFilter.Text + '%''';
FDQuery1.Filter := S;
FDQuery1.Filtered := True;
end;
end;
FDQuery1.Open;
end;
procedure TForm1.ApplySqlFilter;
begin
FilterMode := fmLocal;
OpenFDQuery;
end;
procedure TForm1.ApplyLocalFilter;
begin
FilterMode := fmLocal;
OpenFDQuery;
end;
procedure TForm1.btnLocalFilterClick(Sender: TObject);
begin
ApplyLocalFilter;
end;
procedure TForm1.btnSqlFilterClick(Sender: TObject);
begin
ApplySqlFilter;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
edFilter.Text := 'a';
end;