Как экранировать запрос к базе данных SQLite?

Если в поисковой строке(Edit1) поставить символ, например ".", то появляется ошибка: "[FireDAC][Phys][SQLite] ERROR: fts5: syntax error near ".""
А так же, если стереть весь текст из Edit1, то ошибка: "[FireDAC][Phys][SQLite] ERROR: unknown special query:"

Как я понял надо экранировать текст запроса, но не совсем понимаю как это сделать.
procedure TForm1.FormCreate(Sender: TObject);
begin
FDQuery1.SQL.Text:=('CREATE VIRTUAL TABLE vdb USING fts5 ( text )');
FDQuery1.ExecSQL;
FDQuery1.SQL.Text:=('INSERT INTO vmdb VALUES ("Привет. Конь БарМалей, Корова?")');
FDQuery1.ExecSQL;
FDQuery1.SQL.Text:=('INSERT INTO vmdb VALUES ("Привет. Лось Ты лось: БорМалей ")');
FDQuery1.ExecSQL;
FDQuery1.SQL.Text:=('INSERT INTO vmdb VALUES ("Привет Бар ты Лось.")');
FDQuery1.ExecSQL;
end;

procedure TForm1.Edit1Typing(Sender: TObject);
var
 mr : string;
begin
     FDQuery1.SQL.Text:=('SELECT text FROM vdb WHERE text MATCH "'+Edit1.Text+'*" ORDER BY rank');
     FDQuery1.OpenOrExecute;
     mr:=(FDQuery1.FieldByName('text ').AsString);
     Memo1.Text := mr;
end;
  • Вопрос задан
  • 353 просмотра
Решения вопроса 1
@fromdns Автор вопроса
Проблема решилась удалением ненужных символов еще на этапе ввода текста, до того как он попадет в запрос.
procedure TForm1.sEdit2Typing(Sender: TObject);
var
s:string;
begin
S:=sEdit2.Text;   // Вводим запрос
S:=StringReplace(s, '~', '', [rfReplaceAll]);
S:=StringReplace(s, '`', '', [rfReplaceAll]);
S:=StringReplace(s, '!', '', [rfReplaceAll]);
S:=StringReplace(s, '@', '', [rfReplaceAll]);
S:=StringReplace(s, '"', '', [rfReplaceAll]);
S:=StringReplace(s, '#', '', [rfReplaceAll]);
S:=StringReplace(s, '№', '', [rfReplaceAll]);
S:=StringReplace(s, ';', '', [rfReplaceAll]);
S:=StringReplace(s, '$', '', [rfReplaceAll]);
S:=StringReplace(s, '%', '', [rfReplaceAll]);
S:=StringReplace(s, '^', '', [rfReplaceAll]);
S:=StringReplace(s, ':', '', [rfReplaceAll]);
S:=StringReplace(s, '?', '', [rfReplaceAll]);
S:=StringReplace(s, '&', '', [rfReplaceAll]);
S:=StringReplace(s, '*', '', [rfReplaceAll]);
S:=StringReplace(s, '(', '', [rfReplaceAll]);
S:=StringReplace(s, ')', '', [rfReplaceAll]);
S:=StringReplace(s, '-', '', [rfReplaceAll]);
S:=StringReplace(s, '_', '', [rfReplaceAll]);
S:=StringReplace(s, '+', '', [rfReplaceAll]);
S:=StringReplace(s, '=', '', [rfReplaceAll]);
S:=StringReplace(s, '[', '', [rfReplaceAll]);
S:=StringReplace(s, ']', '', [rfReplaceAll]);
S:=StringReplace(s, '{', '', [rfReplaceAll]);
S:=StringReplace(s, '}', '', [rfReplaceAll]);
S:=StringReplace(s, '|', '', [rfReplaceAll]);
S:=StringReplace(s, '>', '', [rfReplaceAll]);
S:=StringReplace(s, '<', '', [rfReplaceAll]);
S:=StringReplace(s, ',', '', [rfReplaceAll]);
S:=StringReplace(s, '\', '', [rfReplaceAll]);
S:=StringReplace(s, '/', '', [rfReplaceAll]);

sEdit1.Text:=S;  // "Чистый" запрос
end;

procedure TForm1.sEdit2ChangeTracking(Sender: TObject);  // procedure TForm1.sEdit1ChangeTracking(Sender: TObject);
var
 i : Integer;
 mr : string;
 empySQL, SQL : string;
 rs : string;
begin
  ListView1.Items.Clear;
    FDQuery2.Close;
    FDQuery2.Active:=True;
    FDQuery2.SQL.Clear;
    SQL := 'SELECT text FROM vdb WHERE text MATCH :search ORDER BY rank';
    empySQL := 'SELECT * FROM vdb';
    FDQuery2.SQL.Text := SQL;

    if
      (sEdit1.text='')
    or(sEdit1.text=' ')
    or(sEdit1.text='  ')
    or(sEdit1.text='   ')
    or(sEdit1.text='    ')
    or(sEdit1.text='     ')
    or(sEdit1.text='      ')
    or(sEdit1.text='       ')
    or(sEdit1.text='        ')
    or(sEdit1.text='         ')
    or(sEdit1.text='          ')
    or(sEdit1.text='           ')
    or(sEdit1.text='            ')
    or(sEdit1.text='             ')
    or(sEdit1.text='              ')
    or(sEdit1.text='               ')
    or(sEdit1.text='                ')
    or(sEdit1.text='                 ')
    or(sEdit1.text='                  ')
    or(sEdit1.text='                   ')
    or(sEdit1.text='                    ')
    or(sEdit1.text='                     ')
    or(sEdit1.text='                      ')
    or(sEdit1.text='                       ')
    or(sEdit1.text='                        ')
    or(sEdit1.text='                         ')
    or(sEdit1.text='                          ')
    or(sEdit1.text='                           ')
    or(sEdit1.text='                            ')
    or (pos('.', sEdit1.Text) > 0)
    or (pos(',', sEdit1.Text) > 0)
    or (pos('<', sEdit1.Text) > 0)
    or (pos('>', sEdit1.Text) > 0)
    or (pos('?', sEdit1.Text) > 0)
    or (pos(':', sEdit1.Text) > 0)
    or (pos(';', sEdit1.Text) > 0)
    or (pos('"', sEdit1.Text) > 0)
    or (pos('|', sEdit1.Text) > 0)
    or (pos('\', sEdit1.Text) > 0)
    or (pos('[', sEdit1.Text) > 0)
    or (pos(']', sEdit1.Text) > 0)
    or (pos('{', sEdit1.Text) > 0)
    or (pos('}', sEdit1.Text) > 0)
    or (pos('~', sEdit1.Text) > 0)
    or (pos('`', sEdit1.Text) > 0)
    or (pos('@', sEdit1.Text) > 0)
    or (pos('#', sEdit1.Text) > 0)
    or (pos('№', sEdit1.Text) > 0)
    or (pos('$', sEdit1.Text) > 0)
    or (pos('%', sEdit1.Text) > 0)
    or (pos('^', sEdit1.Text) > 0)
    or (pos('&', sEdit1.Text) > 0)
    or (pos('*', sEdit1.Text) > 0)
    or (pos('(', sEdit1.Text) > 0)
    or (pos(')', sEdit1.Text) > 0)
    or (pos('_', sEdit1.Text) > 0)
    or (pos('-', sEdit1.Text) > 0)
    or (pos('=', sEdit1.Text) > 0)
    or (pos('+', sEdit1.Text) > 0)
    or (pos('/', sEdit1.Text) > 0)
    then
    FDQuery2.SQL.Text := empySQL
       else
   FDQuery2.ParamByName('search').AsString := '^'+sEdit1.Text+'*';
   FDQuery2.Open;
     Memo1.BeginUpdate;
  for i:=0 to FDQuery2.RecordCount -1 do
     begin
     mr:=(FDQuery2.FieldByName('text').AsString);
	  Memo1.Text:=mr;
        FDQuery2.Next;
        end;
            Memo1.EndUpdate;
            end;
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
HemulGM
@HemulGM Куратор тега Delphi
Delphi Developer, сис. админ
Использовать параметры
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы