sql запрос..

Работа VB и СУБД (Access, MSSQL, MySQL, Oracle и пр.)
Правила форума
При создании новой темы не забывайте указывать используемую СУБД.
skulida
Обычный пользователь
Обычный пользователь
 
Сообщения: 56
Зарегистрирован: 28.06.2003 (Сб) 12:16
Откуда: Санкт-Петербург

sql запрос..

Сообщение skulida » 07.01.2004 (Ср) 0:34

подскажите как можно организовать запрос к mdb базе, используя оператор like (или по другому) что можно было получить выборку
по текстовому полю вида:
поле в базе: продажа бытовой техники ремонт гарантия
запрос: продажа ремонт техники
или
продажа быт техники гарантия
или
ремонт гарантия
Если использовать:
If searchtxt.Text <> "" Then sSQL = sSQL & "AND key like '%" & searchtxt.Text & "%'"
то ищются только последовательные связки слов.
Прошу помочь.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 08.01.2004 (Чт) 11:35

Код: Выделить всё
Function GetSQL(ByVal SearchString As String) As String
Dim W() As String, L As Long, SQL As String
Do Until L = Len(SearchString)
  L = Len(SearchString)
  SearchString = Replace(SearchString, vbSpace & vbSpace, vbSpace)
Loop
SQL = "select * from testtable where ..."
If Len(SearchString) > 0 Then
  W() = Split(SearchString, vbSpace)
  SQL = SQL & " and ("
  For L = LBound(W) To UBound(W)
    If L > LBound(W) Then SQL = SQL & " or "
    SQL = SQL & "(key like '%" & W(L) & "%')"
  Next L
  SQL = SQL & ")"
  Erase W()
End If
End Function


Только такой поиск к SQL имеет не слишком большое отношение. Для подобного поиска нужно индексировать слова во вспомогательной таблице и искать по ней.
Lasciate ogni speranza, voi ch'entrate.

skulida
Обычный пользователь
Обычный пользователь
 
Сообщения: 56
Зарегистрирован: 28.06.2003 (Сб) 12:16
Откуда: Санкт-Петербург

Сообщение skulida » 08.01.2004 (Чт) 22:53

alibek
спасибо за ответ..
насколько я понял предложенный код
сначала удаляет пробелы в переменной (строке поиска), затем формирует массив из букв строки поиска, затем перебирая массив
сравнивает с полем в базе данных.

Но. поиск по-прежнему осуществляется только по последовательным связкам слов. почему то оператор 'or' не работает.

Т.е. напомню поле в базе "продажа бытовой техники ремонт"
сейчас ищется "продажа бытовой" или "бытовой техники" или "техники ремонт". А надо чтобы было также и "продажа ремонт" или "ремонт бытовой" т.е. разный порядок слов должен отслеживаться..
спасибо..

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 09.01.2004 (Пт) 10:13

Блин... :)
В конце функции допиши "GetSQL = SQL"
Lasciate ogni speranza, voi ch'entrate.

skulida
Обычный пользователь
Обычный пользователь
 
Сообщения: 56
Зарегистрирован: 28.06.2003 (Сб) 12:16
Откуда: Санкт-Петербург

Сообщение skulida » 09.01.2004 (Пт) 17:35

неа....сам SQL запрос работает, но выборка не меняется, т.е. ищются только последовательно стоящие слова в поле базы.
Как мне кажется, что не правильно формируется массив из букв, т.е. в массиве один элемент и это все содержимое searchstring.
Как сформировать массив из букв текстового поля?

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 09.01.2004 (Пт) 18:16

Может что-то с процедурой не то? Она должна возвращать строку для запроса и в ней должны быть блоки (Key Like %...%) or (Key Like %...%) or .... Проверь, что она возвращает, может с процедурой я напортачил?
А вообще поисковые машины пишутся не так. В базе данных создаешь две вспомогательные таблицы. Одна такого вида:

Код: Выделить всё
Список слов для поиска
HLP_WORDS
---------
WRD_ID - Long (Auto-Increment counter) - идентификатор
WORD - Text*250 - слово


Код: Выделить всё
Список объектов, содержащих искомые слова
HLP_OBJECTS
-----------
OBJ_ID - Long (Auto-Increment counter)
WRD_WRD_ID - Long - внешний ключ на HLP_WORDS
ITEM_TABLE - Text*250 - Имя таблицы БД, в которой содержится запись с искомым словом
ITEM_KEY - Long - Идентификатор записи


Для использования берется примерно такой запрос:
Код: Выделить всё
select HLP_OBJECTS.ITEM_TABLE, HLP_OBJECTS.ITEM_KEY
from HLP_OBJECTS inner join HLP_WORDS on HLP_OBJECTS.WRD_WRD_ID = HLP_WORDS.WRD_ID
where HLP_OBJECTS.ITEM_TABLE = ...
  and HLP_WORDS.WORD in (...)

Это для MSAccess, обычно таблицы связывают не через inner join, а в выражении where

В полученном рекордсете перечислены все записи в БД, в который имеется искомая строка. Для них открываешь новый рекордсет, ищешь записи и добавляешь в список результатов.
Lasciate ogni speranza, voi ch'entrate.

skulida
Обычный пользователь
Обычный пользователь
 
Сообщения: 56
Зарегистрирован: 28.06.2003 (Сб) 12:16
Откуда: Санкт-Петербург

Сообщение skulida » 10.01.2004 (Сб) 0:19

[quote="alibek"]
извини, но я так и не разобрался с первым вариантом:
с функцией действительно что-то не то, возвращает она
".....and ((key like '%продажа авто форд%'"))"" , где "продажа авто форд" - все поисковое выражение. Т.е. нет оператора 'or' и фраза не разбита на слова. А W(L) = <subscript out range>. ???
наверное, что -то все таки с массивом...????

второй вариант буду пробовать, кстати как сами эти таблицы должны быть связаны??

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 11.01.2004 (Вс) 12:21

Странные вы вещи рассказываете, гражданин :)
Функция Split разделяет строку на массив, в данном случае строка W() = Split(SearchString, vbSpace) должна возвратить массив слов W() (т.е. W(0)="продажа", W(1)="авто", W(2)="форд"). Какая версия VB? Если VB5, то в нем нет функции Split, надо писать свою функцию.

А таблицы связаны полями HLP_WORDS.WRD_ID=HLP_OBJECTS.WRD_WRD_ID, "один-ко-многим"
Lasciate ogni speranza, voi ch'entrate.

qx14az17
Начинающий
Начинающий
 
Сообщения: 6
Зарегистрирован: 22.12.2003 (Пн) 22:05

Сообщение qx14az17 » 11.01.2004 (Вс) 22:06

Слушай, я тут заинтересовался темой - лучше всего у меня получается следующий вариант:

1) Строка запроса пользователя разбивается на массив ключевых слов
2) В цикле выполняется набор вложенных SQL-запросов вида:

SELECT *
FROM (select * from TABLE1 where cl_text like '%ремонт%') as d1
where cl_text like '%техн%'


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

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 12.01.2004 (Пн) 11:35

На выходных я понял, почему процедура не работает -- это потому, что ты не используешь Option Explicit. В VB нет константы vbSpace (просто я определяю ее в каждом модуле и уже забыл, что она не встроенная). Напиши строку W()=Split(SearchString," ") и все будет работать.
Lasciate ogni speranza, voi ch'entrate.

skulida
Обычный пользователь
Обычный пользователь
 
Сообщения: 56
Зарегистрирован: 28.06.2003 (Сб) 12:16
Откуда: Санкт-Петербург

Сообщение skulida » 12.01.2004 (Пн) 23:55

да... спасибо. я уже тоже разобрался методом тыка, кроме " ", еще пришлось начальное и конечное значение массива присвоить переменным, и их уже перебирать в цикле..а иначе почему то отказывается работать..

W = Split(SearchString, " ")
d = LBound(W)
L = UBound(W)
sSQL = sSQL & " and ("

For i& = d To L
If i& > d Then sSQL = sSQL & " and "
sSQL = sSQL & "(key like '%" & W(i&) & "%')"
Next
sSQL = sSQL & ")"
Erase W
End If

:))
теперь у меня другая задача -
есть поиск по рекордсету на форме:
adodc1.Recordset.MoveNext
Adodc1.Recordset.Find "tel LIKE '%" & Text2.Text & "%'"
If Adodc1.Recordset.EOF Then
MsgBox "Поисковое выражение не найдено" & Chr(13) & "или более вхождений нет..", _
vbOKOnly + vbInformation, "Результат!"
End If

Как сделать чтобы поиск осуществлялся еще по одному полю 'fax'?,
т.е. объединить их оператором "or"??


Вернуться в Базы данных

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

    TopList  
cron