Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2007.10.21;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.051 c
2-1191273430
San1712
2007-10-02 01:17
2007.10.21
Как программно менять обои на рабочем столе ?


2-1190983310
hinst
2007-09-28 16:41
2007.10.21
Не отвечает


2-1190802048
sergnnn
2007-09-26 14:20
2007.10.21
Invalid pointer operation


2-1190724118
alles
2007-09-25 16:41
2007.10.21
Как правильно использовать TServerSocket?


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





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский