Страница 1 из 1

Нужен поиск по всем полям таблицы

Добавлено: 12 мар 2006, 20:58
SHShadow
Список полей таблицы MAIN получаю так:
FOR
select rdb$relation_fields.rdb$field_name from rdb$relation_fields
where rdb$relation_fields.rdb$relation_name = 'MAIN'
INTO :FIELD_NAME
DO
/*А вот как запросить значения ?*/
BEGIN
for select :FIELD_NAME :?:
from main where upper(:field_name :?: ) like '%A%'
into :FOUNDING
do
SUSPEND;
END
Так не получается, :cry: что в принципе логично, поскольку идет выборка значения.

Помогите! :(

Добавлено: 13 мар 2006, 09:15
Dimitry Sibiryakov
Для начала: "поиск по всем полям" это бред сам по себе и свидетельствует о неправильном заказчике.
По сути: твой запрос имеет смысл только для текстовых полей. Соответственно - читай статью Тенцера (вроде бы была на delphiplus.org) об ОО-структуре базы и будет тебе счастье: одним фиксированным запросом можно искать во всех текстовых полях.

Добавлено: 15 мар 2006, 03:26
SHShadow
Dimitry Sibiryakov писал(а):Для начала: "поиск по всем полям" это бред сам по себе и свидетельствует о неправильном заказчике.
По сути: твой запрос имеет смысл только для текстовых полей. Соответственно - читай статью Тенцера (вроде бы была на delphiplus.org) об ОО-структуре базы и будет тебе счастье: одним фиксированным запросом можно искать во всех текстовых полях.
Не согласен.
Запрос типа
  • for select distinct <имя поля>
    from main cast( <имя поля> as varchar(512)) like <запрос поиска>
    into FOUNDING do begin suspend; end
будет работать по любым полям (кроме пожалуй blob)

Добавлено: 15 мар 2006, 10:08
Dimitry Sibiryakov
И в каком месте даты, времени или числа ты надеещься найти '%A%'?

Добавлено: 17 мар 2006, 22:06
SHShadow
'%А%' - это только один из многих вариантов запроса, ведь тема и звучит: ПОИСК :wink:

Добавлено: 14 апр 2006, 15:57
entryway
я стораж процедурой делаю поиск в стиле "безиндексный поиск по всем полям типа варчар по всем таблицам". на моих данных (до 100мб на убогом сервере с обычным винтом) поиск проходит можно сказать мгновенно (меньше секунды). если надо, могу кинуть сюда текст процедуры, но там нет ничего сложного. все тупо. стоит заметить, что процедурой я выбираю только список таблиц где встречается то, что ищет клиент, помещаю это все в листбокс и уже после клика на конкретную таблицу из листбокса клиент получает выборку из неё. из клиента поиск работает приблизительно так. Клиент хочет найти банкоматы на проспекте победы. Вводит например БАН ПОБЕД и получает ответ в виде поддерева основного дерева. Все это было нужно только потому, что изначально данные не были унифицированны и располагались в разных таблицах и без какой либо централизованной системы по именам полей.

Добавлено: 24 апр 2006, 20:09
SHShadow
Будь добр, выложи на обозрение, если не трудно :)

Добавлено: 25 апр 2006, 14:05
entryway
SHShadow писал(а):Будь добр, выложи на обозрение, если не трудно :)
да меня сейчас если не разорвут, то заклюют :)) Короче даю как есть, так сказать в первозданной красе. Написал 100 лет назад и забыл. Работает до сих пор.

Код: Выделить всё

CREATE PROCEDURE FINDSQL (
    IN_ID_CITY INTEGER,
    IN_1 VARCHAR(32),
    IN_2 VARCHAR(32),
    IN_3 VARCHAR(32),
    IN_4 VARCHAR(32),
    IN_5 VARCHAR(32))
RETURNS (
    TABLENAME VARCHAR(32),
    SERVICE VARCHAR(50),
    CCOUNT INTEGER)
AS
DECLARE VARIABLE VAR_FIELDNAME VARCHAR(32);
DECLARE VARIABLE VAR_WHERE1 VARCHAR(4096);
DECLARE VARIABLE VAR_WHERE2 VARCHAR(4096);
DECLARE VARIABLE VAR_WHERE3 VARCHAR(4096);
DECLARE VARIABLE VAR_WHERE4 VARCHAR(4096);
DECLARE VARIABLE VAR_WHERE5 VARCHAR(4096);
DECLARE VARIABLE VAR_FULLWHERE VARCHAR(32000);
DECLARE VARIABLE VAR_ST VARCHAR(1024);
begin
  for
    select table1name, service
    from tree
    where ((tabletype = 3) or (tabletype = 4)) and (ishide <> 1)
      and ((city = 0) or (city = :in_id_city))
    order by service
    into :tablename, :service
  do begin
    var_where1 = null;
    var_where2 = null;
    var_where3 = null;
    var_where4 = null;
    var_where5 = null;
    for
      select rtrim(relation.rdb$field_name)
      from rdb$fields fields
      inner join rdb$relation_fields relation on relation.rdb$field_source=fields.rdb$field_name
      where (relation.rdb$relation_name = :tablename) and (fields.rdb$field_type = 37)
      into :var_fieldname
    do begin

      if (in_1 is not null) then begin
        var_st = '('||var_fieldname||' like ''%'||in_1||'%'')';
        if (var_where1 is null) then var_where1 = var_st;
        else var_where1 = var_where1||'or'||var_st;
        if (in_2 is not null) then begin
          var_st = '('||var_fieldname||' like ''%'||in_2||'%'')';
          if (var_where2 is null) then var_where2 = var_st;
          else var_where2 = var_where2||'or'||var_st;
          if (in_3 is not null) then begin
            var_st = '('||var_fieldname||' like ''%'||in_3||'%'')';
            if (var_where3 is null) then var_where3 = var_st;
            else var_where3 = var_where3||'or'||var_st;
            if (in_4 is not null) then begin
              var_st = '('||var_fieldname||' like ''%'||in_4||'%'')';
              if (var_where4 is null) then var_where4 = var_st;
              else var_where4 = var_where4||'or'||var_st;
              if (in_5 is not null) then begin
                var_st = '('||var_fieldname||' like ''%'||in_5||'%'')';
                if (var_where5 is null) then var_where5 = var_st;
                else var_where5 = var_where4||'or'||var_st;
              end
            end
          end
        end
      end
    end

    var_fullwhere = '(id_city=0 or id_city='||in_id_city||')';

    if (var_where1 is not null) then begin
      var_fullwhere = var_fullwhere||'and('||var_where1||')';
      if (var_where2 is not null) then begin
        var_fullwhere = var_fullwhere||'and('||var_where2||')';
        if (var_where3 is not null) then begin
          var_fullwhere = var_fullwhere||'and('||var_where3||')';
          if (var_where4 is not null) then begin
            var_fullwhere = var_fullwhere||'and('||var_where4||')';
            if (var_where5 is not null) then begin
              var_fullwhere = var_fullwhere||'and('||var_where5||')';
            end
          end
        end
      end
    end

    ccount = null;
    execute statement
      'select 1 from rdb$database where exists(select 1 from '||
      tablename||' where '||var_fullwhere||')' into :ccount;
    if (ccount is not null) then suspend;
  end
END