Unrecognized token при большом количестве совпадений - Lazar

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Unrecognized token при большом количестве совпадений - Lazar

Сообщение mrkaban » 28.10.2016 08:51:13

Здравствуйте, Благодарен всем за неоднократную помощь! Хочу предупредить сразу, что я совсем новичок.

С такой ошибкой уже есть темы, но мне они не помогли. Может я что-то не понимаю, если так, тогда прошу прощения.

Имеется программа, которая получается список установленных программ и из него формирует sql запрос для сравнения с базой в SQLite3, далее отображаются в DBGrid совпадения с базой. Так вот, при большом количестве совпадений с базой появляется ошибка Unrecognized token.
Снимок2.jpg

    То есть, если установлено очень много программ, но совпадений с базой не много, тогда такой ошибки нет
. Вот сам sql запрос выполненный на компьютере с ошибкой
Снимок.jpg


Хочу обратить внимание на то, что на другом компьютере такой проблемы вообще нет. Прикладываю скриншот Showmessage(s) с другого компьютера (пусть будет второй компьютер).
Снимок3.jpg

Долго не мог понять с чем связано. Понял, когда на третьем компьютере из реестра все программы добавил в базу. То есть, до этого на третьем компьютере не было такой проблемы. Везде ОС Windows 7 x64.

Подскажите пожалуйста, не могу сам разобраться. Ниже привожу код всей процедуры. Если нужно что-то ещё, только скажите. Заранее благодарен за любую помощь!

Код: Выделить всё
procedure TfMian.mBeginSerchClick(Sender: TObject);
var
   MyList: TStringList;     // для хранения названий ключей реестра, нужна для извлечения DisplayName в MyList2
   MyList2: TStringList;   // содержит DisplayName, объявлен глобально
   MyRegistry: TRegistry;
   s: string;                 // в неё записывается готовый sql запрос
   i : integer;               // нужна для счетчика цикла for
   Str: string;              // используется для получения DisplayName
begin
Cursor:= crHourGlass;     
bSearch.Visible:=False;    //скрываем кнопку начать поиск   

MyList2:=TStringList.Create;
MyRegistry:=TRegistry.Create(KEY_WOW64_64KEY);
MyList:=TStringList.Create;     

// далее получаем список программ и записываем в MyList2
// цикл for дублируется, чтобы получать и 32-битные и 64-битные

with MyRegistry do
        begin
        RootKey:=HKEY_LOCAL_MACHINE;
        OpenKeyReadOnly('Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\');
        GetKeyNames(MyList);
        CloseKey;
        for i:=0 to MyList.Count-1 do
           begin
           RootKey:=HKEY_LOCAL_MACHINE;
           OpenKeyReadOnly('Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\'+
           MyList[i]);
           Str:=ReadString('DisplayName');
           if Str<>'' then
           MyList2.Add(ReadString('DisplayName'));
           CloseKey;
           end;

        RootKey:=HKEY_LOCAL_MACHINE;
        OpenKeyReadOnly('Software\Microsoft\Windows\CurrentVersion\Uninstall\');
        GetKeyNames(MyList);
        CloseKey;
        for i:=0 to MyList.Count-1 do
           begin
           RootKey:=HKEY_LOCAL_MACHINE;
           OpenKeyReadOnly('Software\Microsoft\Windows\CurrentVersion\Uninstall\'+
           MyList[i]);
           Str:=ReadString('DisplayName');
           if Str<>'' then
           MyList2.Add(ReadString('DisplayName'));
           CloseKey;
           end;
          end;     
     
     
//далее составляем sql запрос и присваиваем его переменной s
                with MyList2.Create do
  try
    MyList2.StrictDelimiter := true;
    s := '';
    for i := 0 to MyList2.Count - 1 do if Trim(MyList2.Strings[i]) <> '' then
      s := s + Format('%s(name LIKE "%%%s%%")', [IfThen(i = 0, '', ' OR '), MyList2.Strings[i]]);
    s := 'SELECT * FROM program WHERE ' + s + ' ORDER BY id';
  finally

  end;         


// всё, в s хранится запрос, он используется для получения данных из БД
  Showmessage(s);
  MyList.Free;             // в ней не хранится DisplayName, поэтому освобождаем память
SQLQuery1.Close;
SQLQuery1.Active:=false;
SQLQuery1.SQL.Clear;
SQLQuery1.SQL.Add(s);
SQLQuery1.Active:=true;
SQLQuery1.Open;         

//заполняем заголовки колонок и меняем ширину колонок
DBGrid1.Columns[1].Title.Caption:='Название';
DBGrid1.Columns[2].Title.Caption:='Тип ПО';
DBGrid1.Columns[3].Title.Caption:='Лицензия';
DBGrid1.Columns[4].Title.Caption:='Стоимость';
DBGrid1.Columns[5].Title.Caption:='Замена';
DBGrid1.Columns[1].Width:= 200;
DBGrid1.Columns[2].Width:= 150;
DBGrid1.Columns[3].Width:= 110;
DBGrid1.Columns[4].Width:= 90;
DBGrid1.Columns[5].Width:= 150;   

end;
У вас нет необходимых прав для просмотра вложений в этом сообщении.
mrkaban
новенький
 
Сообщения: 55
Зарегистрирован: 28.05.2016 09:48:18

Re: Unrecognized token при большом количестве совпадений - L

Сообщение v-t-l » 29.10.2016 09:05:39

создать в базе временную таблицу searched, загнать туда список искомых программ, затем
Код: Выделить всё
SELECT p.*
FROM program p
JOIN searched s ON p.name LIKE '%' || s.name || '%'
v-t-l
энтузиаст
 
Сообщения: 740
Зарегистрирован: 13.05.2007 16:27:22
Откуда: Belarus

Re: Unrecognized token при большом количестве совпадений - L

Сообщение mrkaban » 29.10.2016 14:41:52

Спасибо!

Я переделал код под запись списка программ в базу и чтения от туда, но код не работает, выдаёт ошибку SQLQuery1: Cannot open a non-select statement.

Подскажите пожалуйста, как переделать его под Ваше предложение. Я просто не понял.
Код: Выделить всё
var
   MyList: TStringList;     // для хранения названий ключей реестра
   MyRegistry: TRegistry;
     s: string;
     i : integer;
//     p: Integer;
   Str: string;
     N:integer;        // для записи в базу списка
begin   
Cursor:= crHourGlass;
bSearch.Visible:=False;    //скрываем кнопку начать поиск
     // очищаем старое содержимое
        SQLQuery1.Close;                               // очистка таблицы в базе, в которую
        SQLQuery1.SQL.Text := 'delete from install';    //  записывается список программ
        SQLQuery1.ExecSQL;
        SQLTransaction1.CommitRetaining;

  MyList2:=TStringList.Create;
MyRegistry:=TRegistry.Create(KEY_WOW64_64KEY);
MyList:=TStringList.Create;

  with MyRegistry do
        begin
        RootKey:=HKEY_LOCAL_MACHINE;
        OpenKeyReadOnly('Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\');
        GetKeyNames(MyList);
        CloseKey;
        for i:=0 to MyList.Count-1 do
           begin
           RootKey:=HKEY_LOCAL_MACHINE;
           OpenKeyReadOnly('Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\'+
           MyList[i]);
           Str:=ReadString('DisplayName');
           if Str<>'' then
       //    Memo1.Lines.Add(SysToUTF8(ReadString('DisplayName')));
           MyList2.Add(ReadString('DisplayName'));
           CloseKey;
           end;

        RootKey:=HKEY_LOCAL_MACHINE;
        OpenKeyReadOnly('Software\Microsoft\Windows\CurrentVersion\Uninstall\');
        GetKeyNames(MyList);
        CloseKey;
        for i:=0 to MyList.Count-1 do
           begin
           RootKey:=HKEY_LOCAL_MACHINE;
           OpenKeyReadOnly('Software\Microsoft\Windows\CurrentVersion\Uninstall\'+
           MyList[i]);
           Str:=ReadString('DisplayName');
           if Str<>'' then
           MyList2.Add(ReadString('DisplayName'));
           CloseKey;
           end;
          end;   

  SQLQuery1.Close;
  SQLQuery1.SQL.Clear;
  SQLQuery1.SQL.Add('insert into install(text)');     //    Запись полученного списка прог в базу
  SQLQuery1.SQL.Add('Values (:pText)');
  for N := 0 to MyList2.Count - 1 do
  begin
    SQLQuery1.ParamByName('pText').AsString := MyList2[N];
    SQLQuery1.ExecSQL;
  end;
  SQLTransaction1.CommitRetaining;


SQLQuery1.Open;
  SQLQuery1.First;
  MyList2.clear;                   // пытался из базы получать список прог
while not SQLQuery1.Eof do
begin
  MyList2.Add(SQLQuery1.FieldByName('install').AsString);
  SQLQuery1.Next;
end;
SQLQuery1.Close;

       with MyList2.Create do
  try
    MyList2.StrictDelimiter := true;
    s := '';
    for i := 0 to MyList2.Count - 1 do if Trim(MyList2.Strings[i]) <> '' then
      s := s + Format('%s(name LIKE "%%%s%%")', [IfThen(i = 0, '', ' OR '), MyList2.Strings[i]]);
    s := 'SELECT * FROM program WHERE ' + s + ' ORDER BY id';
  finally
    Free;
  end; 

// всё, в s хранится запрос, его и используй для получения данных из БД
// Showmessage(s);
  MyList.Free;
SQLQuery1.Close;
SQLQuery1.Active:=false;
SQLQuery1.SQL.Clear;
SQLQuery1.SQL.Add(s);
SQLQuery1.Active:=true;
SQLQuery1.Open; 
mrkaban
новенький
 
Сообщения: 55
Зарегистрирован: 28.05.2016 09:48:18

Re: Unrecognized token при большом количестве совпадений - L

Сообщение WAYFARER » 29.10.2016 19:37:47

Вы пытается вызвать Open в датасете SQLQuery1, но без select запроса.
Если вы пытаетесь вывести содержимое только что заполненную таблицы install, то должно быть так:

Код: Выделить всё
  begin
    SQLQuery1.ParamByName('pText').AsString := MyList2[N];
    SQLQuery1.ExecSQL;
  end;
  SQLTransaction1.CommitRetaining;
SQLQuery1.SQL.Clear;
SQLQuery1.SQL.Text:='select text from install';
SQLQuery1.Open;
SQLQuery1.First;
MyList2.clear;                   // пытался из базы получать список прог
while not SQLQuery1.Eof do
begin
  MyList2.Add(SQLQuery1.FieldByName('text').AsString);
  SQLQuery1.Next;
end;
SQLQuery1.Close;
Аватара пользователя
WAYFARER
энтузиаст
 
Сообщения: 537
Зарегистрирован: 09.10.2009 00:00:04
Откуда: г. Курган

Re: Unrecognized token при большом количестве совпадений - L

Сообщение mrkaban » 29.10.2016 20:30:59

WAYFARER писал(а):Вы пытается вызвать Open в датасете SQLQuery1, но без select запроса.
Если вы пытаетесь вывести содержимое только что заполненную таблицы install, то должно быть так:

Код: Выделить всё
  begin
    SQLQuery1.ParamByName('pText').AsString := MyList2[N];
    SQLQuery1.ExecSQL;
  end;
  SQLTransaction1.CommitRetaining;
SQLQuery1.SQL.Clear;
SQLQuery1.SQL.Text:='select text from install';
SQLQuery1.Open;
SQLQuery1.First;
MyList2.clear;                   // пытался из базы получать список прог
while not SQLQuery1.Eof do
begin
  MyList2.Add(SQLQuery1.FieldByName('text').AsString);
  SQLQuery1.Next;
end;
SQLQuery1.Close;


Работает!!! СПАСИБО БОЛЬШОЕ!!!

Прям вообще от всей души спасибо!
mrkaban
новенький
 
Сообщения: 55
Зарегистрирован: 28.05.2016 09:48:18


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 240

Рейтинг@Mail.ru
cron