Exemplos

Padrões práticos para integrar o EgStrParser em aplicações de bases de dados.

Campo de filtro básico

A utilização mais comum: um campo de edição num formulário de pesquisa, validado ao sair e aplicado a um query.

procedure TfrmOrders.edDateExit(Sender: TObject);
var
  R: TParseResult;
begin
  R := ParseInput(edDate.Text, itDate);
  case R.ResultType of
    otEmpty:
 // Não há filtro neste campo; remova qualquer fragmento de cláusula WHERE existente.
 FDateFilter := '';
    otInvalid:
 begin
 edDate.Color := clYellow;
        Exit;
 end;
  else
    edDate.Color := clWindow;
    FDateFilter := 'OrderDate ' + R.SQLExpression;
  end;
  ApplyFilters;
end;

R.SQLExpression para otEmpty é preenchida (contém IS NULL ou = ''), mas o padrão típico de aplicação é tratar uma entrada vazia como «sem filtro» e remover completamente o campo da cláusula WHERE.

Filtro de intervalo

Os intervalos são detetados automaticamente quando a entrada contém o separador de intervalo. Não é necessário qualquer tratamento especial por parte do chamador.

// O utilizador digita: 100~500
R := ParseInput(edAmount.Text, itDecimal);
// R.ResultType   = otRange
// R.SQLExpression = BETWEEN 100.0000 AND 500.0000

// O utilizador digita: 2026-01-01~2026-03-31
R := ParseInput(edDate.Text, itDate);
// R.SQLExpression = BETWEEN DATE '2026-01-01' AND DATE '2026-03-31'

Lista com vários valores

As listas também são detetadas automaticamente.

// Tipos de utilizador: 1001;1002;1005
R := ParseInput(edIds.Text, itInteger);
// R.ResultType    = otList
// R.SQLExpression = IN (1001, 1002, 1005)

// Tipos de utilizador: smith, jones, o'brien
R := ParseInput(edName.Text, itString, [opTrim]);
// R.SQLExpression = IN ('smith', 'jones', 'O''brien')

Pesquisa LIKE

// Tipos de utilizador: acme
R := ParseInput(edCompany.Text, itString, [opTrim], sopLikeBoth);
// R.SQLExpression = LIKE '%acme%' ESCAPE '\'

Query1.SQL.Text := 'SELECT * FROM Companies WHERE CompanyName ' + R.SQLExpression;

Utilização do componente

Configure TEgStrParser em tempo de design (dialeto, operador predefinido, opções predefinidas) e chame Parse() a partir dos manipuladores de eventos.

// No Object Inspector:
//   EgParser1.SqlDialect    = sqlElevateDB
//   EgParser1.DefaultOptions = [opTrim]

procedure TfrmSearch.edNameExit(Sender: TObject);
var
  R: TParseResult;
begin
  R := EgParser1.Parse(edName.Text, itString, sopLikeRight, Sender as TComponent);
  if R.ResultType <> otInvalid then
    FNameFilter := 'CustomerName ' + R.SQLExpression;
end;

Manipulador partilhado para vários campos

procedure TfrmSearch.FilterExit(Sender: TObject);
var
  Ed: TEdit;
  R: TParseResult;
  Fragment: *string*;
begin
  Ed := Sender as TEdit;

  if Ed = edOrderDate then
    R := EgParser1.Parse(Ed.Text, itDate)
  else if Ed = edAmount then
    R := EgParser1.Parse(Ed.Text, itDecimal)
  else if Ed = edCustomer then
    R := EgParser1.Parse(Ed.Text, itString, [opTrim], sopLikeBoth)
  else
    Exit;

  Ed.Color := IfThen(R.ResultType = otInvalid, clYellow, clWindow);
  if R.ResultType <> otInvalid then
    FFilters.Values[Ed.Name] := R.SQLExpression;

  ApplyFilters;
end;

procedura TfrmSearch.ApplyFilters;
var
  Key, WhereClause: *string*;
  Parts: TStringList;
begin
  Parts := TStringList.Create;
  try
    for Key in FFilters.Keys do
 if FFilters.Values[Key] <> '' then
 Parts.Add(Key + ' ' + FFilters.Values[Key]);
    WhereClause := Parts.CommaText; // ou String.Join(' AND ', ...)
  finally
    Parts.Free;
  end;
  // aplicar a *query*...
end;

Tratamento de todos os tipos de resultados

procedure ApplyFieldFilter(const ColName, Input: *string*;
  ValueType: TInputType; Query: TQuery);
var
  R: TParseResult;
begin
  R := ParseInput(Input, ValueType, [opTrim]);
  case R.ResultType of
    otEmpty:
 // Sem filtro: *query* sem uma cláusula WHERE nesta coluna.
      Query.SQL.Text := Format('SELECT * FROM T', []);

 otInvalid:
 raise EValidationError.CreateFmt(
 'Valor inválido para %s (erro %d)', [ColName, R.ErrorCode]);

  else
    // otSingleValue, otList, otRange — todos produzem uma SQLExpression válida.
    Query.SQL.Text :=
 Format('SELECT * FROM T WHERE %s %s', [ColName, R.SQLExpression]);
  end;
  Query.Open;
end;

Rejeitar valores vazios e NULL

Utilize opRequired para rejeitar entradas vazias e opNotNull para rejeitar posições vazias numa lista.

R := ParseInput(edId.Text, itInteger, [opRequired, opNotNull]);
if R.ErrorCode = ERR_EMPTY_NOT_ALLOWED then
  ShowMessage('O ID é obrigatório.')
else if R.ErrorCode = ERR_NULL_NOT_ALLOWED then
  ShowMessage('A lista não pode conter posições vazias.')
else if R.ResultType = otInvalid then
  ShowMessage('ID inválido.')
else
  // utilize R.SQLExpression

Pesquisa de texto completo (ElevateDB)

// O utilizador digita: fatura de pagamento
R := ParseInput(edKeywords.Text, itString, [opTrim], sopContainsAll);
// sqlElevateDB: CONTAINS ALL 'fatura de pagamento'
// outros dialetos: LIKE '%pagamento%fatura%' ESCAPE '\'

Query1.SQL.Text :=
  'SELECT * FROM Documents WHERE Body ' + R.SQLExpression;

Dialeto explícito por chamada (aplicação com várias bases de dados)

function BuildFilter(const Input: *string*; ValueType: TInputType;
  Dialect: TSqlDialect): *string*;
var
  R: TParseResult;
begin
  R := ParseInput(Input, ValueType, '~', [opTrim], sopEqual, Dialect);
  if R.ResultType in [otSingleValue, otList, otRange] then
    Result := R.SQLExpression
  else
    Result := '';
end;

Entrada de data com reconhecimento de localização

O parser aceita formatos de data compactos, ISO e de localização sem qualquer configuração. Os utilizadores podem introduzir qualquer um destes formatos e obter o mesmo resultado SQL:

25/03/2026     → DATE '2026-03-25'   (formato local dd/mm/aaaa, pt-PT)
2026-03-25     → DATE '2026-03-25'   (ISO)
25032026 → DATE '2026-03-25'   (compacto ddmmyyyy)
2503 → DATE '2026-03-25'   (compacto ddmm, ano atual)

Não é necessário qualquer pré-processamento do lado do chamador.

Exibição dos valores analisados

Values[] contém a exibição normalizada e adaptada às configurações regionais strings. Utilize-os para mostrar ao utilizador o que o parser compreendeu:

R := ParseInput('25032026~31122026', itDate);
// R.Values[0]: '25-03-2026'   (configuração regional pt-PT)
// R.Values[1]: '31-12-2026'
// R.ParsedValue: '25-03-2026 ~ 31-12-2026'

lblParsed.Caption := 'Interpretado como: ' + R.ParsedValue;
(C) 2026 Easygate, Lda