IMHO.WS

IMHO.WS (https://www.imho.ws/index.php)
-   Программирование (https://www.imho.ws/forumdisplay.php?f=40)
-   -   Подскажите.. Paradox (https://www.imho.ws/showthread.php?t=105808)

SteFF 11.07.2006 05:33

Подскажите.. Paradox
 
Года 2 назад делал курсач по программированию с базами данных.. Сейчас понял, что все совершенно забыл!.. Так тчо не бейте сильно...
Так вот! У меня следующая проблема.
Имеется база данных клиентов, в которой ведется поиск по введенным значениям. По каким именно полям - узнается после проверки, какие Edit'ы заполнены. Про кривость кода: пока сделал, чтобы хоть работало. Потом буду "шлефовать". Критику (с конкретными предложениями) принимаю!
Код:

procedure client_from_db(var cldb: clientzap);
BEGIN
  With Form1 do
  begin
  cl_srch_qry:='';
  if Edit12.Text<>'' then
    begin
      cl_srch_qry:=cl_srch_qry+'name="'+Edit12.Text+'" AND ';
    end;
  if Edit13.Text<>'' then
    begin
      cl_srch_qry:=cl_srch_qry+'lname="'+Edit13.Text+'" AND ';
    end;
  if MaskEdit5.Text<>'(  )    -    ' then
    begin
      cl_srch_qry:=cl_srch_qry+'hphone="'+MaskEdit5.Text+'" AND ';
    end;
  if MaskEdit6.Text<>'(  )    -    ' then
    begin
      cl_srch_qry:=cl_srch_qry+'ophone="'+MaskEdit6.Text+'" AND ';
    end;
  if MaskEdit7.Text<>'(  )    -    ' then
    begin
      cl_srch_qry:=cl_srch_qry+'cphone="'+MaskEdit7.Text+'" AND ';
    end;
  if Edit14.Text<>'' then
    begin
      cl_srch_qry:=cl_srch_qry+'email="'+Edit14.Text+'" AND ';
    end;
  //udalyaem nenujnii ' AND '
  if length(cl_srch_qry)<>0 then
    begin
      cl_srch_qry:='('+cl_srch_qry;
      delete(cl_srch_qry,length(cl_srch_qry)-4,5);
      cl_srch_qry:=cl_srch_qry+')';
    end;
  end;

Потом делается запрос в этой же процедуре (сама эта процедура вызывается при нажатии кнопочки..):
Код:

With Form1.Query3 do
begin
  Close;
  SQL.Clear;
  SQL.Add('SELECT * FROM client.db WHERE '+cl_srch_qry); //search in DB
  ExecSQL;
  cldb.idn:=FieldByName('CLid').AsInteger;
  cldb.name:=FieldByName('Name').AsString;
  cldb.lname:=FieldByName('Lname').AsString;
  cldb.hphone:=FieldByName('hphone').AsString;
  cldb.ophone:=FieldByName('ophone').AsString;
  cldb.cphone:=FieldByName('cphone').AsString;
  cldb.email:=FieldByName('email').AsString;
  ...
  cldb.sendemail:=FieldByName('sendemail').AsBoolean;
  cldb.deleted:=FieldByName('deleted').AsBoolean;
end;

Так вот.. не работает это :(( Вылетают сообщения, что поля с такими именами не существуют.. как быть?..

TRiPLE 13.07.2006 15:05

Я в таких случаях делаю следующее:
1. обязательно вывожу текст sql запроса перед его передачей в БД
2. проверяю его в какой-нить тулзе, чтобы увидеть ошибки выдаваемые самой БД, если она такое умеет (mssql, например, можно прямо в enterprise manager попытаться выполнить запрос)
Кстати, чем проверять на пустоту каждое окошко ввода, не лучше ли ставить флаги по событию редактирования объекта и потом по установленным флагам собирать запрос?

SteFF 14.07.2006 08:34

1. Решение проблемы нашел :)) Надо было делать Open, а не ExecSQL.
2. Это тоже вариант. Но мне сейчас главное сделать чтобы все требуемые операции с БД проходили нормально. Все остальное возможно переделаю :cool: Все равно спасибо! ;)

И еще вопросы!
1.Как узнать сколько всего записей в таблице?
2.Гдето кажется читал, что, для того чтобы ускорить поиск поиск в БД надо сделать поля индексируемыми. Если не так, то как ускорить поиск? Можно ли все поля проиндексировать?
3.Какие еще есть команды SQL.. ну типа First - встать на первую запись, Next - следуюущая. Как узнать сколько всего записей в таблице? МОжно ли узнать сколько в таблице записей подходящих "по маске"?
Где можно обо всем жтом поподробнее почитать? На русском желательно ;)
Спасибо :)

ЕЖ 14.07.2006 09:45

SteFF
Сейчас книжек по программированию БД в Delphi предостаточно, выкладывались и у нас на форуме. Методы First/Next - это не к SQL, а к классу TDataSet (родитель для TTable и TQuery). Есть свойство RecordCount для определения количества записей.

Индексировать нужно только те поля, по которым ты чаще всего делаешь поиск, т.е. пишешь в SELECT условие типа WHERE ID = ... Вот тогда ID стоит проиндексировать. Все индексировать не имеет смысла. Индексы дают выигрыш при выборках данных. Но есть и обратная сторона - при добавлении/изменении записей индексы вынуждены перестраиваться. Так что оценивай как часто будут у тебя данные меняться, или больше будут только выбираться.

kot_ 15.07.2006 23:07

Цитата:

Сообщение от ЕЖ
SteFF
Сейчас книжек по программированию БД в Delphi предостаточно, выкладывались и у нас на форуме. Методы First/Next - это не к SQL, а к классу TDataSet (родитель для TTable и TQuery). Есть свойство RecordCount для определения количества записей.

Индексировать нужно только те поля, по которым ты чаще всего делаешь поиск, т.е. пишешь в SELECT условие типа WHERE ID = ... Вот тогда ID стоит проиндексировать. Все индексировать не имеет смысла. Индексы дают выигрыш при выборках данных. Но есть и обратная сторона - при добавлении/изменении записей индексы вынуждены перестраиваться. Так что оценивай как часто будут у тебя данные меняться, или больше будут только выбираться.

К вышесказанному добавлю - индекс имеет смысл устанавливать в том случае, если данные в поле изменяются в широком диапазоне. Т.е. если поле может содержать всего два значения, например "М" и "Ж" - индекс не нужен, даже если по этим полям выполняются сравнения.

SteFF 19.07.2006 09:06

У меня будет много полей.. имена, фамилии, адреса, телефоны, е-mail и еще много полей, в которых будут небольшие числа. Поиск будет происходить по: имя, фамилия, телефоны(3), емейл, адрес. Значит лучше будет сделать эти поля индексируемыми?
Слышал что в парадоксе индексы слетают.. чем это грозит? Полной потерей данных? :eek: Или их можно бдует восстановить? :idontnow:
:)

Borland 19.07.2006 09:49

Цитата:

SteFF:
Значит лучше будет сделать эти поля индексируемыми?
Для нормальной работы поиска их просто необходимо проиндексировать.
Цитата:

SteFF:
Слышал что в парадоксе индексы слетают.. чем это грозит? Полной потерей данных?
Случается что и слетают. Но данным при этом ничего не грозит.
На случай "слёта" индексов обычно предусматривается процедура переиндексации.

_Lynx_ 21.07.2006 12:09

Индекс имеет смысл делать если после фильтрации по нему останется не более 5-10%. И не стоит делать более 5-7 индексов на таблицу. Так же разумно бывает делать составные индексы.

SteFF 22.07.2006 04:59

Цитата:

_Lynx_:
Так же разумно бывает делать составные индексы.
А это как?))

SteFF 22.07.2006 06:57

Как искать подстроку в строке? Например: мне надо найти фамилию человека в БД.. а я помнб только пару букв его фамилии? Как можно это реализовать? :confused: И возможно ли?

ЕЖ 22.07.2006 09:25

Цитата:

Сообщение от SteFF
Как искать подстроку в строке? Например: мне надо найти фамилию человека в БД.. а я помнб только пару букв его фамилии? Как можно это реализовать? :confused: И возможно ли?

...WHERE SecondName LIKE '%буквы%'

При этом обрати еще внимание на регистр. Возможно лучше будет написать что-то типа ...WHERE UPPER(SecondName) LIKE '%БУКВЫ%'

Также отмечу, что при таком поиске с неизвестной первой буквой, даже MS SQL Server не использует индес по полю, а сканирует таблицу. Так что и Paradox вряд ли будет. Т.е. поиск по первым буквам должен теоретически быть эффективнее чем поиск по вхождению, если поле проиндексировано.

SteFF 22.07.2006 18:51

А как тогда мне в запросе указать, что '%буквы%' это как раз первые буквы слова (строки в БД), а не просто подстрока? :confused:

ЕЖ 23.07.2006 22:25

Для поиска по первым буквам пиши 'буквы%'. Тут % - это просто маска, означает произвольное количество каких-либо символов.

SteFF 24.07.2006 09:41

А. все. Теперь понял.
Спасибо! ;)


Часовой пояс GMT +4, время: 15:06.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.