Решено: SQLite3 + Select

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

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

Решено: SQLite3 + Select

Сообщение Petrakoff Sergey » 20.03.2012 20:53:03

Имеются две таблицы. В обеих таблицах имеются поля IDKATEGOR (означает категорию товара, тип AutoIncrement).
Нужно чтобы по нажатию категории в DBGrid1, в DBGrid2 выводились бы товары только выбранной категории. Никак не могу сделать.
Пробовал так:
Код: Выделить всё
procedure TForm1.FormShow(Sender: TObject);
begin
  with DM do
  begin
    ConnectKat.DatabaseName:= 'Kategorii.db';
    ConnectKat.Connected:= true;
    QKat.Close;
    QKat.SQL.Clear;
    QKat.SQL.Add('select * from TKategorii');
    QKat.Open;
    ConnectLek.DatabaseName:= 'Lekarstva.db';
    ConnectLek.Connected:= true;
    QLek.Close;
    QLek.SQL.Clear;
    QLek.SQL.Add('select * from Lekarstva where IDKATEGOR='+QKAT.FieldByName('IDKATEGOR').AsString);
    QLek.ExecSQL;
    QLek.Open;
  end;
end;

В DBGrid2 ничего не выводится.
Если сделать, например, запрос в виде
Код: Выделить всё
QLek.SQL.Add('select * from Lekarstva where IDKATEGOR=5');

то все отлично выводится. Но мне нужно, чтобы пользователь сам выбирал категорию. Может кто подскажет, как сделать запрос?
Последний раз редактировалось Petrakoff Sergey 23.03.2012 08:58:03, всего редактировалось 1 раз.
Petrakoff Sergey
новенький
 
Сообщения: 33
Зарегистрирован: 08.12.2011 11:42:17

Re: SQLite3 + Select

Сообщение Little_Roo » 20.03.2012 21:50:01

Petrakoff Sergey писал(а):тип AutoIncrement

Такое поле как AsString быть НЕ может. Приводите к строке IntToStr... или пробовать как ....AsVariant
Аватара пользователя
Little_Roo
энтузиаст
 
Сообщения: 639
Зарегистрирован: 27.02.2009 19:56:36
Откуда: Санкт-Петербург

Re: SQLite3 + Select

Сообщение Ism » 20.03.2012 21:59:11

Для вставки и обновления лучше использовать запрос с параметрами.
Или вставлять данные через Dataset.Insert Dataset.ApplyUpdates Dataset.CommitRetaining
Ism
энтузиаст
 
Сообщения: 908
Зарегистрирован: 06.04.2007 17:36:08

Re: SQLite3 + Select

Сообщение Petrakoff Sergey » 20.03.2012 22:16:32

Little_Roo писал(а):Такое поле как AsString быть НЕ может. Приводите к строке IntToStr... или пробовать как ....AsVariant

Эти возможности я уже пробовал, еще до того, как обратился в форум. В том то и дело, поля целочисленные, а в запросе компилятор говорит, что нужен тип string.
Ism писал(а):Для вставки и обновления лучше использовать запрос с параметрами.
Или вставлять данные через Dataset.Insert Dataset.ApplyUpdates Dataset.CommitRetaining

Честно говоря, ничего не понял. На данный момент базы как бы "статические", ничего не добавляю, просто хочу вывести что есть.
Petrakoff Sergey
новенький
 
Сообщения: 33
Зарегистрирован: 08.12.2011 11:42:17

Re: SQLite3 + Select

Сообщение Little_Roo » 20.03.2012 22:24:33

Petrakoff Sergey писал(а):В том то и дело, поля целочисленные, а в запросе компилятор говорит, что нужен тип string.

..... + IntToStr(QKAT.FieldByName('IDKATEGOR').AsInteger)
Так пойдет ?
Аватара пользователя
Little_Roo
энтузиаст
 
Сообщения: 639
Зарегистрирован: 27.02.2009 19:56:36
Откуда: Санкт-Петербург

Re: SQLite3 + Select

Сообщение Petrakoff Sergey » 20.03.2012 22:29:31

Little_Roo писал(а):.... + IntToStr(QKAT.FieldByName('IDKATEGOR').AsInteger)
Так пойдет ?

Код: Выделить всё
Main.pas(55,9) Error: Incompatible types: got "LongInt" expected "AnsiString"


Добавлено спустя 3 минуты 33 секунды:
В DBF делал через индексы.
SQLite3 и SQL запросы только начал изучать. Пока все как в тумане.
Petrakoff Sergey
новенький
 
Сообщения: 33
Зарегистрирован: 08.12.2011 11:42:17

Re: SQLite3 + Select

Сообщение Little_Roo » 20.03.2012 23:08:25

Petrakoff Sergey писал(а):
Little_Roo писал(а):.... + IntToStr(QKAT.FieldByName('IDKATEGOR').AsInteger)
Так пойдет ?


Объявите переменную

Код: Выделить всё
var s : string ;//(или ansistring)
......
s :=IntToStr(QKAT.FieldByName('IDKATEGOR').AsInteger);
....
QLek.SQL.Add('select * from Lekarstva where IDKATEGOR= ' + s);
....

Ы ???
Аватара пользователя
Little_Roo
энтузиаст
 
Сообщения: 639
Зарегистрирован: 27.02.2009 19:56:36
Откуда: Санкт-Петербург

Re: SQLite3 + Select

Сообщение Petrakoff Sergey » 20.03.2012 23:18:04

Little_Roo писал(а):
Объявите переменную

Код: Выделить всё
var s : string ;//(или ansistring)
......
s :=IntToStr(QKAT.FieldByName('IDKATEGOR').AsInteger);
....
QLek.SQL.Add('select * from Lekarstva where IDKATEGOR= ' + s);
....

Ы ???

Так тоже пробовал, то же самое
Petrakoff Sergey
новенький
 
Сообщения: 33
Зарегистрирован: 08.12.2011 11:42:17

Re: SQLite3 + Select

Сообщение Little_Roo » 20.03.2012 23:30:27

Petrakoff Sergey писал(а):Так тоже пробовал, то же самое

И последний вопрос (который был должен быть первым) - ОСь, версия лазаря и fpc
Какие компоненты используются?
Аватара пользователя
Little_Roo
энтузиаст
 
Сообщения: 639
Зарегистрирован: 27.02.2009 19:56:36
Откуда: Санкт-Петербург

Re: SQLite3 + Select

Сообщение Petrakoff Sergey » 20.03.2012 23:36:38

Little_Roo писал(а):И последний вопрос (который был должен быть первым) - ОСь, версия лазаря и fpc
Какие компоненты используются?

Windows XP SP3, Lazarus-0.9.30, fpc-2.4.2, компоненты: TSQLQuery, TSQLite3Connection, TSQLTransaction, TDatasource, TDBGrid

Добавлено спустя 6 минут 20 секунд:
Думаю дело не в Осях или версиях Lazarus. Может можно через TSqlite3Dataset, вообще не используя SQL запросы, как в DBF, через индексы, но мне хочется через запросы. Так сказать, для саморазвития.
Petrakoff Sergey
новенький
 
Сообщения: 33
Зарегистрирован: 08.12.2011 11:42:17

Re: SQLite3 + Select

Сообщение Little_Roo » 20.03.2012 23:48:46

Petrakoff Sergey писал(а): Lazarus-0.9.30, fpc-2.4.2

Пробуем обновиться на 0.9.31 и 2.6.0 или выше...
TSQLite3Connection => ZEOS 7
TDBGrid => TRxDBGRID
Но это мои предпочтения в плане безглючной (тьфу-тьфу) работы

Использую FireBird 2.5

Lazarus 0.9.31 r36017 FPC 2.7.1 i386-win32-win32/win64
Аватара пользователя
Little_Roo
энтузиаст
 
Сообщения: 639
Зарегистрирован: 27.02.2009 19:56:36
Откуда: Санкт-Петербург

Re: SQLite3 + Select

Сообщение Petrakoff Sergey » 21.03.2012 00:03:27

В книжках написано (правда для Delphi + BDE), что можно перечислять таблицы в запросе, т.е. делать так
Код: Выделить всё
QLek.SQL.Add('select * from Lekarstva, Kategorii where IDKATEGOR= IDKATEGOR');

Компиляция проходит, при выполнении выдает "No such table: Kategorii" .
Еще в одной книге написано, что можно так:
Код: Выделить всё
QLek.SQL.Add('select * from Lekarstva where IDKATEGOR=(select * from  Kategorii where IDKATEGOR)');
Опять же не для Lazarus и не для SQLite3, а для MySQL. Тоже не проходит.
Little_Roo писал(а):TSQLite3Connection => ZEOS 7
TDBGrid => TRxDBGRID

По-моему, не в этом дело. Задача ведь тривиальная. Вывести данные из подчиненной таблицы по значениям поля в главной таблице. Надо только запрос правильно составить. В чем и проблема. Ладно, будем завтра опять пробовать, гуглить. Хотя сегодня уже "нагуглился" по самое...
Petrakoff Sergey
новенький
 
Сообщения: 33
Зарегистрирован: 08.12.2011 11:42:17

Re: SQLite3 + Select

Сообщение Little_Roo » 21.03.2012 00:08:22

Petrakoff Sergey писал(а):"No such table: Kategorii" .

В первом посте было TKategorii :shock:
Аватара пользователя
Little_Roo
энтузиаст
 
Сообщения: 639
Зарегистрирован: 27.02.2009 19:56:36
Откуда: Санкт-Петербург

Re: SQLite3 + Select

Сообщение Petrakoff Sergey » 21.03.2012 00:12:39

Little_Roo писал(а):В первом посте было TKategorii

Это описка. Должно быть TKategorii
Petrakoff Sergey
новенький
 
Сообщения: 33
Зарегистрирован: 08.12.2011 11:42:17

Re: SQLite3 + Select

Сообщение Vadim » 21.03.2012 04:22:36

Petrakoff Sergey
У Вас там слишком много открытий\закрытий датасетов. :)
1. Один раз открыли таблицу TKategorii и всё, больше её не трогайте.
2. На кнопке оставьте только формирование запроса к таблице Lekarstva.
3. Метод ExecSQL используется только тогда, когда Вам не нужно получать данные. Во всех других случаях этот метод совершенно бессмысленен.

Алгоритм действий:
1. Получить из таблицы TKategorii значение IDKATEGOR текущей строки.
2. Подставить это значение в запрос к Lekarstva в секцию WHERE, не забыв преобразовать в строковый тип (т.к. запрос - это строка ;) ).
3. Открыть запрос методом Open.
Всё. :)
Код: Выделить всё
    QLek.Close;
    QLek.SQL.Clear;
    QLek.SQL.Add('select * from Lekarstva where IDKATEGOR='+QKAT.FieldByName('IDKATEGOR').AsString);
    QLek.Open;

100%-но работающий код. И единственный, который нужен. ;)
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

След.

Вернуться в Lazarus

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

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

Рейтинг@Mail.ru