Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Базы данных и репортинг > Поиск через SQL, если база подключена через ADO


Автор: Vorona 17.10.2004, 16:56
Подскажите please, какие компоненты надо использовать для поиска через SQL, если база подключена через ADO, и как они должны быть связанны, допуская, что выборку производим выводя информацию в DBListBox

Как это сделать, если надо к примеру вводя текст в EDIT выводить в этот самый DBListBox
те записи из БД, начало которых совпадает с указанным нами текстом

Автор: MishaSt 17.10.2004, 17:09
TADOConnection<->TADOQuery<->TDataSource <->TDBGrid

ADOConnection1.ConnectionString := 'Provider = Microsoft.Jet.4.0; Data Source = C:\Base;';
ADOConnection1.Open;
ADOQuery1.Connection := ADOConnection1;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('SELECT * FROM mytable.mdb WHERE CustomerId = 12;');
ADOQuery1.ExecSQL;
ADOQuery1.Active := True;
DataSource1.DataSet := ADOQuery1;
DBGrid1. DataSource := DataSource1;

Автор: Pakshin A. S. 17.10.2004, 17:41
Попробуйте так:
1) Делаем подключение в ADOConnection
2) Ставим DataSource, ADOQuery и DBListBox
3) Устанавливаем связи:
DBListBox1.DataSource:=DataSource1;
DataSource.DataSet:=ADOQuery1;
ADOQuery1.Connection:=ADOConnection1;
4) Делаем:
Код

with ADOQuery1 do
begin
 Close;
 SQL.Text:='Select SomeField from SomeTable;';
 Open
end;

:)

Автор: Vorona 17.10.2004, 19:17
оно глючит....... хотя наверное не оно, а просто я не шарю

пишет что, что мало ему параметров. Ну я создала один, все равно пишет, что неправильно применяю
я ему присвоила содержание Edit-та а потом не могу его сравнить с полем таблицы

как их вообще применять, эти параметры?

Автор: Fedor 17.10.2004, 19:29
Цитата
пишет что, что мало ему параметров

Тут возможно, что ты неправильно назвала поле таблицы или саму таблицу. Ну например вместо запроса
Select SomeField FROM .....
ты написала
Select Someield FROM ..... (нет буквы F)

А вообще понятие параметров здесь реализовывается так:
Код

 ADOQuery1.SQL.Add('SELECT * FROM MyTable WHERE id=:ss');
 ADOQuery1.Parameters.ParamByName('ss').Value:=i;


И тогда Delphi там, где стоит ss подставит текущее значение переменной i. Тут важно, чтоб имя параметра в самом запросе и в ParamByName имело одинаковый регистр букв. Иначе Delphi будет ругаться ексепшонами.

Автор: Vorona 17.10.2004, 20:12
а что такое id
это может быть полем таблицы?
может ли при этом быть использован id like :ss
у меня пока не хочет..

Автор: Fedor 17.10.2004, 20:14
Цитата
а что такое id
пример поля таблицы
Цитата
это может быть полем таблицы?
да
Цитата
может ли при этом быть использован id like :ss
скорее всего да, хотя не уверен
Цитата
у меня пока не хочет..
а что именно не хочет?

Автор: Pakshin A. S. 17.10.2004, 20:38
Попробуй выполнить запрос на DBGrid'е. Если ошибка не исчезнет, то пости SQL код сюда: обязательно ошибочку найдем... :D

Цитата(Morpheus @ 17.10.2004, 21:14)
Цитата (Люба @ 17.10.2004, 20:12)
может ли при этом быть использован id like :ss

скорее всего да, хотя не уверен


А по-моему конструкция LIKE применипа для полей символьного типа...

Автор: Vorona 17.10.2004, 20:39

Morpheus

работать не хочет, а ты что подумал?

и кстати listbox в упор не видит, просто ничего туда не выводит
у одного моего одноклассника та же история

но зато вроде на счет кода не ругается
Добавлено @ 20:40
Pakshin A. S.

на DBGrid'е все работает, вот в том-то и проблема...

Автор: Pakshin A. S. 17.10.2004, 20:45
Лично я бы сделал так: загрузин всю потеху от SQL в DBGrid, а потом оттудова всё в обыкновенный ListBox засунул... Даже и без DBGrid'а можно обойтись.
Код

with ADOQuery1 do
begin
 Close;
 SQL.Text:='Select * from Table1 where id = ' + Edit1.Text + ';'; //id- идентификационный номер записи
 Open;
 listBox1.Items.Clear;
 while not Eof do
  begin
   ListBox1.Items.Add(ADOQuery1.Fields[1].AsString); // поле после id
   Next;
  end;
 Close;
end;

Немного дольше, но вернее... :thumbs-up

Автор: Vorona 17.10.2004, 20:49
Pakshin A. S.

прийдется... но странно все же, что он не работает

а как организовать через параметр в sql поиск не на совпадение всего слова, а вот ввели мы к примеру первую букву слова, а оно вывело в списочек все записи базы на эту букву

Автор: Pakshin A. S. 17.10.2004, 20:54
ПОЗДРАВЛЯЮ, у тебя будет прога!!!
Просто надо добавить
Код

with ADOQuery1 do
 begin
  ...
 end;
DBListBox1.MasterField:='FieldName';

Добавлено @ 20:56
Попробуй... :D
Просто без этого у меня DBListBox оставался девственно чистым, а как это вставил, вроде заработало, но это, правда, была работа через Query с таблицей Paradox, но, скорее всего,с ADO то же самое! :)
Добавлено @ 21:02
Цитата
а как организовать через параметр в sql поиск не на совпадение всего слова, а вот ввели мы к примеру первую букву слова, а оно вывело в списочек все записи базы на эту букву


Проще простого!!! :thumbs-up
Код

SELECT FIO FROM Spisok1 WHERE FIO LIKE ' + #39 + Edit1.Text + '%' + #39 + ';';

Будет выведен список всех значений поля FIO, начинающихся с текста в Edit1. :) :thumbs-up :cool

Автор: Vorona 17.10.2004, 21:30
спасибо! :D :D :D :D :D :D :D

Автор: Pakshin A. S. 17.10.2004, 21:34
Обращайся!!! :thumbs-up :D


:offtopic
P. S.
Как тебе форум? Нравится? :)

Автор: Fedor 17.10.2004, 23:05
:offtopic
Цитата
а ты что подумал

Да я подумал не то, что ты подумала, а спросил что именно не работает. ;-)

И присоединяюсь к вопросу
Цитата(Pakshin @ 17.10.2004, 21:34)
Как тебе форум? Нравится?
:hehe

Автор: Vorona 18.10.2004, 20:26
:offtopic
Pakshin A. S. Morpheus
Еще бы! Конечно нравится!!! :hehe
Я и не думала, что есть такие классные форумы
:) :)
Спасибо за отзывчивость, вы - супер :)


Pakshin A. S.
На свойство MasterField выдает ошибку (у меня его нет в перечне свойств), я аналогично поменяла DataField, но DBListBox по прежнему в спячке
видно это он по природе своей глючит :hehe
в него даже без запросов ничего не выводится
буду использовать обычный ListBox
:)

Автор: x77 18.10.2004, 20:33
в TADOQuery MasterSоurce нет, там объединение делается на уровне запроса, а в TAdoTable - есть.

Автор: Pakshin A. S. 18.10.2004, 21:17
Sorry, действительно, не MasterField, а DataField... :stena

Путем эсперимента установлено: Всё очень хорошо работает, к примеру, с DBMemo...
После подключения к базу данных делаем
Код

ShowMessage(DBListBox1.Find.ASString);

И что очень раздражает, показывается правильный результат!!!

Автор: x77 18.10.2004, 21:27
Pakshin A. S., послушай, ну неужто трудно запустить среду, кинуть пару компонентов и посмотреть что там есть, а что нет? тыщи денег за это время траффик сьест, или что? люди, которым ты выкладываешь не опробованный код тоже могут сидеть на том же диал-апе, и также тратить время и деньги на бесполезные советы. не обижайся, но впредь я буду тебе ставить минусы просто за то, что ты от балды пишешь код, который даже не компилиться. ну надо же хоть немного уважать людей, которые спрашивают у всех у нас совета.

Автор: Pakshin A. S. 18.10.2004, 21:29
Даа... компонент оказался действитьно не русским... :(


Классы TDBListBox и TDBComboBox реаоизуют списки, аналогичные спискам TlistBox иT ComboBox, с тем лишь отличием, что они используются для выбора значений поля набора данных.

Связь с полем набора данных указывается свойствами DataSource и DataField. Значения, отображаемые в списке, содержатся в свойстве Itemsю Элементы массива Items можно добавлять как в инспекторе объектов, так и программно.

Код

{Заполнение списка типа TDBListBox значениями поля Company набора данных}
procedure TFomr1.FormCreate(Sender: TObject);
begin
while not Table1.Eof do
 begin
  DBListBox1.Items.Add(Table1.FieldByName('Company').AsString);
  Table1.Next
 end
end;


Если создать список, связанный с конкретным полем, и заполнить его значениями данного поля, то затем его можно будет использовать для выбора значения поля текущей записи.

Щас ещё поглядим, может ещё что-нибудь найдем-с... :D
Добавлено @ 21:31
Цитата(x77 @ 18.10.2004, 22:27)
ставить минусы

мне наплевать на репутацию!!! :angry:

Главное - хоть как-нибудь помочь людям!!! :D

Автор: x77 18.10.2004, 21:35
Pakshin A. S., вот именно. нерабочий код - это не помощь, это издевательство. и либо он будет у тебя рабочим, либо нефиг его выкладывать. споры - приватом, закрыли здесь эту тему.

Автор: Pakshin A. S. 18.10.2004, 21:38
OK





Вот пример для тебя:
Код

procedure TForm1.Button1Click(Sender: TObject);
begin
 ADOQuery1.Close;
 ADOQuery1.SQL.Text:='Select FIO from Spisok where FIO Like ''À'';';
 ADOQuery1.Open;
 DBListBox1.DataField:='FIO';
 while not ADOQuery1.Eof do
   begin
     DBListBox1.Items.Add(ADOQuery1.Fields[0].AsString);
     ADOQuery1.Next
   end
end;

В DBListBox1 будут выведены все ФИО из списка, начинающиеся на букву "А".

Автор: Vorona 18.10.2004, 22:25
Pakshin A. S.

спасибо, у меня сейчас правда жуткие глюки с 7ым дэлфи вплоть до того что прога не запускается вообще, но как все исправится - обязательно испробую :)

Автор: Pakshin A. S. 19.10.2004, 16:58
Такой способ работы с DBListBox'ом описан в двух книгах => должно работать на 99%!!! :thumbs-up

Автор: Vorona 23.10.2004, 19:38
Pakshin A. S.

Наконец-то дошли руки до испробования твоего кода.
Аж не поверилось, когда в DBLB хоть что-то вывелось...
Но дак оно теперь другой глюк выдает: во-первых, реагирует только первый раз, а потом уже нет, а, во-вторых, почему-то выдает поля не по алфавиту.
Ну в общем я все больше убеждаюсь, что на DBLB надо забить
Он и правда не русский.. :)

Но вот еще одна сложность: у меня некоторые записи в базе, по которым происходит поиск, состоят из двух слов, напр., геометрическая прогрессия. Скажем, человек вводит иначе : 'прогрессия геометрическая' и тогда уже он ничего не может найти. Когда я делала базу, я создала два столбика, во втором поменяла слова в термине местами.

но тогда я еще наивно думала, что будет просто сделать такой поиск.

а вот теперь думаю, что может можно как-то это через один столбик сделать? Короче :qstn

p/s Ну и замучила же я тебя с моим поиском... :hehe

Автор: Pakshin A. S. 23.10.2004, 19:42
Цитата
почему-то выдает поля не по алфавиту


Инфа выдается в том порядке, в котором они добавлялись в таблицу.
Щас исправим... :D
Добавлено @ 19:46
Как мне помнится, делаем через SQL.
Вот пример запроса:
Код
SELECT * FROM TableName ORDER BY FieldName


Т. е. происходит сортировка записей в алфавитном порядке по полю FieldName...
:)
Добавлено @ 19:47
Цитата
реагирует только первый раз

Это как?
Добавлено @ 19:48
Цитата
а вот теперь думаю, что может можно как-то это через один столбик сделать?

Пока ответа на этот вопрос нет... :( :stena
Надо дождаться ответов профи! :thumbs-up :cool

Автор: Vorona 23.10.2004, 20:29
Pakshin A. S.

Цитата
Это как?

Когда набираю первую букву текста в Edit-е - выборка делается, но потом (вторая и все остальные буквы) - DBLB реагировать отказывается

Но я еще попробую сама помучиться... :stena :stena

:)

Автор: Pakshin A. S. 24.10.2004, 09:52
Цитата
DBLB

А это что за штуковина?!

Автор: Vorona 24.10.2004, 11:23
Pakshin A. S.
DBListBox конечно, просто мне надоело писать его полностью :)

Автор: Vorona 24.10.2004, 11:47
Pakshin A. S.

Вроде бы уже и работает эта несчастная прога, только ищет почему-то только все слово, а не все слова на введенную букву
Я делаю через параметры, в свойстве SQL запроса еще до запуска проги пишу

Код
SELECT Termin
FROM Slovnyk
WHERE Termin LIKE :param


Потом в программе пишу

Код
dmodule.ADOQuery1.Active:=false;
dmodule.ADOQuery1.Parameters.ParamByName('param').Value:=Edtslovo.Text;
dmodule.ADOQuery1.Active:=true;

DbLstbx.DataField:='termin';
while not dmodule.ADOQuery1.Eof do
begin
 DBLstBx.Items.Add(dmodule.ADOQuery1.Fields[0].AsString);
 dmodule.ADOQuery1.Next;
end;


Наверное, надо что-то добавить в тексте запроса, но что?
Я уже все перепробовала, что только можно :(




Автор: Pakshin A. S. 24.10.2004, 12:40
Короче, вот пример проектика "поиск по базе данных"
Он включает в себя три вида поиска: 1) строка целиком; 2) каждое слово из строки; 3) Смешанный поиск.
Из компонентов быз данных используется всего лишь три вещи: Query, DataBase, DBGrid (для вывода инфы).
Короче, там всё понятно.

Постарался реализовать
Цитата
а вот теперь думаю, что может можно как-то это через один столбик сделать?


P. S.
Использована таблица Paradox, но всё это через ADOQuery будет выглядеть так же... :D

Автор: Vorona 24.10.2004, 17:27
Pakshin A. S.
Подскажи пожалуйста, что такое '%' и '*'. Это ASCII-коды? Если да, то чего?
А #39 - это пробел?
:)

Автор: Pakshin A. S. 24.10.2004, 19:39
'%' - символ для SQL запроса, означающий, что после некоторого сочетания символов до знака % может стоять сколько угодно символов
Пример:
есть две записи
asdf
ased
Используя запрос с where Something Like 'as%'
Мы получим эти две записи.

'*' - символ, взятый из поиска файлов в Wind'е. Т. е. привычный заменитель сивола % для SQL...
#39 - одна ковычка '

ASCII код - число, напимер 39 - это код символа '

Автор: Pakshin A. S. 24.10.2004, 20:23
Цитата

Pakshin A. S.

Вроде бы уже и работает эта несчастная прога, только ищет почему-то только все слово, а не все слова на введенную букву
Я делаю через параметры, в свойстве SQL запроса еще до запуска проги пишу


Код
SELECT Termin
FROM Slovnyk
WHERE Termin LIKE :param



Потом в программе пишу


Код
dmodule.ADOQuery1.Active:=false;
dmodule.ADOQuery1.Parameters.ParamByName('param').Value:=Edtslovo.Text;
dmodule.ADOQuery1.Active:=true;

DbLstbx.DataField:='termin';
while not dmodule.ADOQuery1.Eof do
begin
DBLstBx.Items.Add(dmodule.ADOQuery1.Fields[0].AsString);
dmodule.ADOQuery1.Next;
end;



Наверное, надо что-то добавить в тексте запроса, но что?
Я уже все перепробовала, что только можно 

Код

dmodule.ADOQuery1.Active:=false;
dmodule.ADOQuery1.Parameters.ParamByName('param').Value:=Edtslovo.Text+'%';// вся фишка в проценте!
dmodule.ADOQuery1.Active:=true;

DbLstbx.DataField:='termin';
while not dmodule.ADOQuery1.Eof do
begin
DBLstBx.Items.Add(dmodule.ADOQuery1.Fields[0].AsString);
dmodule.ADOQuery1.Next;
end;


Автор: Vorona 24.10.2004, 20:26
щас проверим :D

Автор: Vorona 25.10.2004, 00:03
Pakshin A. S.

Маленький вопросик:

имеем к примеру в базе списочек
-абрикос
-ананас
-апельсин

при использовании ORDER BY при введении буквы а оно почему-то переводит курсор на апельсин, а надо бы на абрикос

как быть? :)

Автор: Pakshin A. S. 25.10.2004, 17:17
А если так?
Код

ORDER BY FieldName DESC

Автор: Pakshin A. S. 25.10.2004, 17:53
Код

SELECT * FROM SomeTable WHERE SomeField LIKE 'а%' ORDER BY SomeField


100% запрос!!! :stena

Автор: Alex 25.10.2004, 18:46
Так ну 1 что я вижу это то, что в строке подключения не задан Locale Identifier я бы написал так
Код
ADOConnection1.ConnectionString := 'Provider = Microsoft.Jet.4.0; Data Source = C:\Base; Locale Identifier = 1049';

Второе не совсем понятно как была создана таблица, установлена ли кодировка символов и COLLATE при создании поля.
Но на сколько мне известно COLLATE можно установить и при выполнении sql запроса.

Как это делается в InterBase и его клонах написано здесь http://www.ibase.ru/devinfo/ibrusfaq.htm

Для вашего случая я бы вам посоветовал написать ORDER BY SomeField COLLATE cp1251

Автор: Vorona 25.10.2004, 19:50
Pakshin A. S.

со * не проходит, у меня первое поле - счетчик, оно мне и выдает его
я пробовала нажать два раза на объект ADOQuery, там в окошке ( не знаю как оно называется) добавить все записи, а потом оставить только нужную, но тогда курсор все равно переезжает на апелисин, а не абрикос
все это странно
:)

Автор: Pakshin A. S. 25.10.2004, 21:04
1) Alex - умный, попробуй как он советует...
2) Если правильно пнял, то нуна следующее:
Код
Select Field1,Field2,Field3 from SomeTable where Field1 Like 'а%' order by Field1 COLLATE cp1251


Вообще это всё походит на уроки SQL. В разделе "базу данных" есть замечательный учебник. Советую его почитать на досуге, если хочешь реально овлательно навыками создания баз даннух и работы с ними через язык SQL-запросов!
:D

Автор: Alex 25.10.2004, 21:43
Цитата(Pakshin @ 25.10.2004, 22:04)

1) Alex - умный, попробуй как он советует...

:D Да ладно тебе, просто человек сам наступал на эти грабли

Автор: Veniamin 12.5.2008, 22:36
Добого времени суток! Подскажите пожалуйста. Пишу программу работы с БД в Acess, связь через ADO. Записи главной таблицы разнесены по вкладкам TabSheet, на каждой вкладке сгрупппированы по параметрам. Необходимо реализовать поиск следующим образом: с помощью RadioButton-ов выбирается параметр поиска, или же можно CheckBox-ами. Есть Edit, в который вводится слово для поиска. Как реализовать, чтоб в DBGrid-е курсор ставился не только на первую найденную запись, а можно было по нажатию кнопки, к примеру, переходить к следующей записи и т.д. удовлетворяющей параметру поиска. Или же выбирается параметр поиска (столбец  таблицы), затем в Edit-е пишется слово для поиска, и выводятся все найденные слова. Locate выводит лишь одну запись:
Код

procedure TMainForm.FindEditChange(Sender: TObject);
begin
 if RadioButton1.Checked then
   DM.MainTable.Locate('кабинет',FindEdit.Text,[]);
 if RadioButton2.Checked then
   DM.MainTable.Locate('телефон',FindEdit.Text,[]);
 if RadioButton3.Checked then
   DM.MainTable.Locate('статус',FindEdit.Text,[]);
end;

 
С Table.Filtered у меня не получилось, при вводе целого слова в DBGrid-е все поля исчезают smile 

Код

procedure TMainForm.FindEdit2Change(Sender: TObject);
begin
  if Length(FindEdit2.Text)>0 then begin
    DM.MainTable.Filtered:=true;
    {отключаем условия на других вкладках}
    RadioButton1.Checked:=false;
    RadioButton2.Checked:=false;
    RadioButton3.Checked:=false;
    end
  else DM.MainTable.Filtered:=false;

  if RadioButton4.Checked then
  DM.MainTable.Filter:='[системная плата]>'''+FindEdit2.Text+'''';
  if RadioButton5.Checked then
   DM.MainTable.Filter:='процессор>'''+FindEdit2.Text+'''';
  if RadioButton6.Checked then
   DM.MainTable.Filter:='память>'''+FindEdit2.Text+'''';
  if RadioButton7.Checked then
   DM.MainTable.Filter:='видеокарта>'''+FindEdit2.Text+'''';
  if RadioButton8.Checked then
   DM.MainTable.Filter:='[сетевая карта]>'''+FindEdit2.Text+'''';
  if RadioButton9.Checked then
   DM.MainTable.Filter:='[жёсткий диск]>'''+FindEdit2.Text+'''';
  if RadioButton10.Checked then
   DM.MainTable.Filter:='[оптический привод]>'''+FindEdit2.Text+'''';
end;


Или можно это  реализовать как-то с помощью SQL-запроса? Т.е. пользователь вводит слово для поиска в Edit, указывает галочкой или несколькими нужный параметр, это передаётся в SQL-запрос заготовку, затем в DBGrid-е отображается результаты поиска записей удовлетворяющих параметрам? smile 

Автор: Данкинг 12.5.2008, 22:48
Цитата(Veniamin @ 12.5.2008,  23:36)
Как реализовать, чтоб в DBGrid-е курсор ставился не только на первую найденную запись, а можно было по нажатию кнопки, к примеру, переходить к следующей записи и т.д. удовлетворяющей параметру поиска. 

Кидаешь AdoQuery, в который запросом выводишь нужную инфу (т.е. все записи, в которых встречается FindEdit.Text). Его можно привязать к DBGrid'у. Только лучше взять так:

Код

trim(FindEdit.Text);

Автор: Veniamin 12.5.2008, 23:07
Т.е. для каждого столбца таблицы будет свой ADOQuery? А если к примеру не RadioButton-ами указывать  параметры поиска, а CheckBox-ами, то запросов будет больше? Можно ли как-то уменьшить число запросов? Или всё делается одним запросом?

p.s. Всё разобрался сам. Нужен всего один запрос, просто для каждого RadioButton-а в процедуре нажатия кнопки запрос переписывается заново, а результат вывожу в другой форме, не затрагивая основной DBGrid. Например:
Код

procedure TMainForm.Button1Click(Sender: TObject);
begin
    if RadioButton1.Checked=true then
    begin
      Uncheck; //процедура снятия Radiobutton-ов на других вкладках
      DM.FindQuery.Active:=false;
      DM.FindQuery.SQL.Clear;
      DM.FindQuery.SQL.Add('SELECT * FROM [главная таблица]');
      DM.FindQuery.SQL.Add('WHERE кабинет LIKE'''+FindEdit.Text+'''');
      DM.FindQuery.Active:=true;
      FindResultForm.ShowModal;
      RadioButton1.Checked:=false;
    end;
  if RadioButton2.Checked=true then
    begin
      Uncheck;
      DM.FindQuery.Active:=false;
      DM.FindQuery.SQL.Clear;
      DM.FindQuery.SQL.Add('SELECT * FROM [главная таблица]');
      DM.FindQuery.SQL.Add('WHERE телефон LIKE'''+FindEdit.Text+'''');
      DM.FindQuery.Active:=true;
      FindResultForm.ShowModal;
      RadioButton2.Checked:=false;
    end;



Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)