Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.10.21;
Скачать: CL | DM;

Вниз

Переменное число параметров запроса   Найти похожие ветки 

 
Lavrenty ©   (2007-06-09 15:57) [0]

Здравствуйте мастера! Подскажите пожалуйста как составить запрос с переменным числом параметров, так как параметрами запроса Q1 являются значения поля f_id запроса Q2 из другой базы. Т. е. количество записей в Q2 заранее неизвестно, ну а так как запросы из разных баз, то конструкции типа where или join не подходят (IB7.1, компоненты IBExpress).


 
Sergey13 ©   (2007-06-09 15:58) [1]

> [0] Lavrenty ©   (09.06.07 15:57)

Есть еще IN в запросах для этого. Или EXISTS.


 
Lavrenty ©   (2007-06-09 16:05) [2]

Насколько знаю IN применяется так

... where f_id in ( x1, x2, x3)

но для этого надо знать заранее сколько этих иксов. Вот как EXIST пользоваться не знаю, надо прочитать.


 
S@shka ©   (2007-06-09 16:52) [3]

Создавать второй запрос после первого через
SQL.TEXT :=


 
Lavrenty ©   (2007-06-09 17:08) [4]


> S@shka ©   (09.06.07 16:52) [3]
> Создавать второй запрос после первого через SQL.TEXT :=

Вообще-то я примерно так и делаю

IBQ.SQL.ADD("select");
IBQ.SQL.ADD("        field1");

IBQ.SQL.ADD("where f_id in(");

и т.д. всего около 40 строк. Далее по циклу выуживаю значения f_id

while not (IBQ2.Eof) do  begin
  IBQ.SQL.Add(IBQ2l.FieldByName("f_id").AsString);
  IBQ2.Next;
  if not IBQ2.Eof then
      IBQ.SQL.Add(" ,");
end;
IBQ.SQL.ADD(")");
IBQ.Open;

Но всё это некрасиво и занимает много места в тескте проги. Куда лучше запихать текст запроса в компонент при конструировании, и подставлять туда лишь только параметры. Вот только как?


 
S@shka ©   (2007-06-09 17:14) [5]

Интересно как ты хочешь запихать, если сам не знаешь что может быть.

Я не вижу тут 40 строк.


 
Lavrenty ©   (2007-06-10 18:19) [6]


> S@shka ©   (09.06.07 17:14) [5]
> Интересно как ты хочешь запихать, если сам не знаешь что
> может быть.

Что вопрос заново повторить ?

> Я не вижу тут 40 строк.

Неужели непонятно, что строки формирования запроса приведены непоностью?

А вообще, нельзя ли по существу?


 
Sergey Masloff   (2007-06-11 09:50) [7]

Гетерогенные запросы маст дай. Если данные обрабатываются совместно - они должны быть в одной (физически и логически) базе. Если IB не позволяет логически объединить две базы - то нужно делать копию данных.

Все остальное (в 90 % случаев) - костыли и грабли


 
Sergey13 ©   (2007-06-13 09:04) [8]

> [2] Lavrenty ©   (09.06.07 16:05)
> Насколько знаю IN применяется так
> ... where f_id in ( x1, x2, x3)
Ты не все знаешь. Можно еще и так
... where f_id in ( select f_id from table_2 where ...)


 
Lavrenty ©   (2007-06-13 15:32) [9]


> Sergey13 ©   (13.06.07 09:04) [8]
> Можно еще и так ... where f_id in ( select f_id from table_2 where  ...)

Эх, да я бы с радостью, только table_2 в другой базе


 
Sergey13 ©   (2007-06-13 15:35) [10]

> [9] Lavrenty ©   (13.06.07 15:32)

Через внешние таблицы можно попробовать, если они есть в ИБ7.


 
Lavrenty ©   (2007-06-13 15:41) [11]

> [10] Sergey13 ©   (13.06.07 15:35) 

А вот этого я не знаю. Пойду рыть доку.  

Спасибо всем!


 
megabyte ©   (2007-06-14 16:03) [12]

Дабы не плодить тему. Интересует переменное количество параметров в ХП.
Если какой-то параметр запроса не выбран, то выводить по всем.
Одна из ХП:
CREATE PROCEDURE WARRANT_ON_PERIOD (
   begin_date date,
   end_date date,
   terr varchar(48),
   is_person smallint,
   brand_name varchar(48),
   client_name varchar(48))
returns (
   kolvo smallint)
as
begin
   if (:is_person = 0) then /*??? ????????????? ????????*/
   begin
       select count(r.repair_id)
       from repairs r join phone_model p on r.phone_model_id = p.phone_model_id
           join brand_list b on p.brand_list_id = b.brand_list_id
           join territory t on r.terr_id = t.territory_id
           join corporate_client c on r.corporate_client_id = c.corporate_client_id
       where (CAST(r.reception_date as date) between :begin_date and :end_date) and
           (r.check_warranty = 0) and (r.repair_type_id <> 2000) and
           (t.territory_title in (:terr))
           and (b.brand_list_title in (:brand_name))
           and (c.corporate_client_title in (:client_name))
       into
           :kolvo;
       suspend;
   end
   else /*??? ??????? ????????*/
   begin
       select count(r.repair_id)
       from repairs r join phone_model p on r.phone_model_id = p.phone_model_id
           join brand_list b on p.brand_list_id = b.brand_list_id
           join territory t on r.terr_id = t.territory_id
       where (CAST(r.reception_date as date) between :begin_date and :end_date) and
           (r.check_warranty = 0) and (r.repair_type_id <> 2000) and
           (t.territory_title in (:terr)) and (b.brand_list_title in (:brand_name))
           and (r.is_person = 1)
       into
           :kolvo;
       suspend;
   end
end

Делаю так, если параметр процедуры на клиенте пустой, то в параметр запроса ХП пишу:
if (abrand = "") then
   fdst_operat.ParamByName("BRAND_NAME").AsString:= DstToStr(fdst_brand)
 else
   fdst_operat.ParamByName("BRAND_NAME").AsString := abrand;

DstToStr(fdst_brand) - процедура формирования строки с разделителями(всех брендов) на основе справочного НД.
Ругается, говорит что arithmetic exception, numeric overflow or string truncetion...
Но это еще не все. Ввел просто в параметр вручную несколько Брендов("Nokia", "Samsung"), запрос выдает не сумму, а нули, т.е. это воспринимается как один бренд.
Пробовал применить еще такую конструкцию:
...(b.brand_list_title = (iif(:brand_name is not null, :brand_name, any(
               select bl.brand_list_title
               from brand_list bl)) ))

Ругается на any, т.е. как-будто в iif можно только единичное значение вводить.
Как мне сделать?
Не хочется делать кучу if в ХП. Других вариантов не вижу пока...


 
Megabyte ©   (2007-06-15 11:26) [13]

Пробовал даже в IBExperte:
select count(r.repair_id)
       from repairs r join phone_model p on r.phone_model_id = p.phone_model_id
           join brand_list b on p.brand_list_id = b.brand_list_id
           join territory t on r.terr_id = t.territory_id
       where (CAST(r.reception_date as date) between "01.05.2007" and "31.05.2007") and
           (r.check_warranty = 0) and (r.repair_type_id <> 2000) and
           (t.territory_title in ("??????????, ??????? ??????"))
           and (b.brand_list_title in (
               select bl.brand_list_title
               from brand_list bl) )
           and (r.is_person = 1)

Так работает.
select count(r.repair_id)
       from repairs r join phone_model p on r.phone_model_id = p.phone_model_id
           join brand_list b on p.brand_list_id = b.brand_list_id
           join territory t on r.terr_id = t.territory_id
       where (CAST(r.reception_date as date) between "01.05.2007" and "31.05.2007") and
           (r.check_warranty = 0) and (r.repair_type_id <> 2000) and
           (t.territory_title in ("??????????, ??????? ??????"))
           and (b.brand_list_title in (:brand) )
           and (r.is_person = 1)

где параметр = select bl.brand_list_title
               from brand_list bl
Не работает, выдает 0. :(

Конечно можно тупо запросы формировать на клиенте, но хотелось бы автоматизировать через ХП!


 
Megabyte ©   (2007-06-15 13:04) [14]

Нашел решение:
iif(:brand_name <> "", b.brand_list_title, 0) =
               iif(:brand_name <> "", :brand_name, 0)

Если параметр пустой, то тождество 0=0.


 
mysql   (2007-06-18 13:20) [15]


> Lavrenty ©   (13.06.07 15:32) [9]
>
> > Sergey13 ©   (13.06.07 09:04) [8]
> > Можно еще и так ... where f_id in ( select f_id from table_2
> where  ...)
>
> Эх, да я бы с радостью, только table_2 в другой базе


вроде так можно:
имя_базы.имя_табл


 
Грициан   (2007-06-18 15:07) [16]

Ну дык, раз IB 7+, то есть GTT, заполняй и джойнь. Или жди IB 8/FB 3, там (возможно) будут полноценные гетерогенные запросы


 
Lavrenty ©   (2007-06-18 22:23) [17]


> Грициан   (18.06.07 15:07) [16]
> Ну дык, раз IB 7+, то есть GTT, заполняй и джойнь.

прошу прощения, что такое GTT? В справке не нашёл.


 
Грициан   (2007-06-19 13:25) [18]

Global temporary tables
временные таблицы



Страницы: 1 вся ветка

Текущий архив: 2007.10.21;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.03 c
15-1190304543
Yegorchic
2007-09-20 20:09
2007.10.21
Недопустимое разрешение


15-1190382611
ElectriC
2007-09-21 17:50
2007.10.21
Point n Grafik


2-1190813132
0x00bin
2007-09-26 17:25
2007.10.21
DLL и её вызовы


4-1176893124
Иван16
2007-04-18 14:45
2007.10.21
Перехват вызова модального окна


2-1190726011
Yurikon
2007-09-25 17:13
2007.10.21
Вопрос по RecNO