![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как составить SQL запрос? [D3, IB6.x]
BlackKing © (2003-11-27 11:28:00)
Такой вот запрос :
Update Material
Set Mat_Daudz =
(Select Sum(SSar_Daudz)
From Sp_Sar
Where Sp_Sar.Id_Mat = Material.Id_Mat) +
(Select Sum(SVSar_Daudz)
From SVp_Sar
Where SVp_Sar.Id_Mat = Material.Id_Mat)
Where Id_Mat = 10
Всё работает как надо, проблемы начинаются когда один из подзапросов не выдаёт никакого значения, Mat_Daudz остаётся пустым.
Как сделать, чтобы в Mat_Daudz попало значение суммы одного из подзапросов, который возвращает значение.
ksan (2003-11-28 20:15:00) [1]
Если разговор идет про IB, то по моему там все хранимые процедуры хранятся в BLR и не важно сколько раз ты их вызываешь, исполняется промежуточный код.
BlackKing (2003-11-28 17:33:00) [2]
попробовал...15 минут только с одним подзапросом :o)
Sandman25 (2003-11-28 17:32:00) [3]
[22] Silver Alex © (28.11.03 17:27)
Ну, я не исключаю, что некоторые "особо умные" СУБД увидят, что запросы одинаковые и заоптимизируют такой запрос, к тому же при втором расчете данные уже будут в кеше, но это не факт. Хранимая процедура в любом случае будет быстрее - и синтаксис проверен, и в псевдо-компилированный код переведен (в зависимости от СУБД).
Silver Alex (2003-11-28 17:27:00) [4]
> Sandman25 © (28.11.03 17:10) [21]
наверное так и будет, это просто как вариант.Yо однажды проводили эксперимент.Тянули на клиент 200 000 записей, так первый запрос выполнялся ощутимое время , но последущие очень быстро (на MS SQL правда).Можно в принципе попробовать
Sandman25 (2003-11-28 17:10:00) [5]
[20] Silver Alex © (28.11.03 17:08)
К сожалению, exist будет лишний раз выполнять запрос. Лучше хранимую написать, как [14] Zacho © (27.11.03 12:46) советует.
Silver Alex (2003-11-28 17:08:00) [6]
> BlackKing (27.11.03 11:28)
можно вставить проверку с помощью exists (если вы не знаете)
Update Material
Set Mat_Daudz =
(Select Sum(SSar_Daudz)
From Sp_Sar
Where Sp_Sar.Id_Mat = Material.Id_Mat) +
(Select Sum(SVSar_Daudz)
From SVp_Sar
Where SVp_Sar.Id_Mat = Material.Id_Mat)
Where Id_Mat = 10
and exists (Select Sum(SSar_Daudz)
From Sp_Sar
Where Sp_Sar.Id_Mat = Material.Id_Mat)
and exists (Select Sum(SVSar_Daudz)
From SVp_Sar
Where SVp_Sar.Id_Mat = Material.Id_Mat)
по смыслу просто посмотри потому что я особо не вникал в запрос.
Но смысл наверное понятен, есть записи изменяем, нет- игнорируем
Sandman25 (2003-11-28 17:06:00) [7]
[18] BlackKing (28.11.03 17:03)
1) a = b + c
2) a = 0;
a = a + b;
a = a + c;
Если b или с равны Null, то и a будет Null.
BlackKing (2003-11-28 17:03:00) [8]
А ведь работает.
В первом варианте было, если хоть один подзапрос выдавал Null, не считало всё. А в етом случае не Null значения сработают.
Sandman25 (2003-11-28 16:59:00) [9]
Не будет работать. Это полностью эквивалентно Вашему первому запросу :)
BlackKing (2003-11-28 16:56:00) [10]
А что вы скажете за такой вариант (разбить запрос на 3)?
Я не совсем извращенец? :o)
Update Material
Set Mat_Daudz = 0
Where Id_Mat = 10
---ExecSQL---
Update Material
Set Mat_Daudz = Mat_Daudz +
(Select Sum(SSar_Daudz)
From Sp_Sar
Where Sp_Sar.Id_Mat = Material.Id_Mat)
Where Id_Mat = 10
---ExecSQL---
Update Material
Set Mat_Daudz = Mat_Daudz +
(Select Sum(SVSar_Daudz)
From SVp_Sar
Where SVp_Sar.Id_Mat = Material.Id_Mat)
Where Id_Mat = 10
---ExecSQL---
Zacho (2003-11-27 12:53:00) [11]
> Alex_Bredin © (27.11.03 12:41) [11]
>
> не могет быть.CAST Null в ноль превращает железно(для целых).
Ничего подобного. CAST (NULL AS что-угодно) = NULL
Zacho (2003-11-27 12:46:00) [12]
В IB нет ни CASE, ни IIF. CASE есть в FB 1.5, а IIF - в Yaffil.
Так что или используй какую-нибудь UDF или вместо запроса напиши хранимую процедуру типа:
Select Sum(SSar_Daudz) From Sp_Sar Where Sp_Sar.Id_Mat =:ID INTO :SUM1;
IF (SUM1 IS NULL) THEN SUM1=0;
Select Sum(SVSar_Daudz) From SVp_Sar Where SVp_Sar.Id_Mat =:ID INTO :SUM2;
IF (SUM2 IS NULL) THEN SUM2=0;
Update Material
Set Mat_Daudz = SUM1+SUM2 Where Id_Mat =:ID;
> BlackKing (27.11.03 12:22) [4]
> в Key Words есть и CASE и WHEN. IIF не замечен. Описания
> по Key Words у меня нет, есть только список.
Иди на http://www.ibase.ruи качай Data Definition Guide и Language Reference, а так же читай статьи на http://www.ibase.ru/develop.htm
Sandman25 (2003-11-27 12:45:00) [13]
[11] Alex_Bredin © (27.11.03 12:41)
Разве значение Ineteger не может быть NULL?
[12] BlackKing (27.11.03 12:41)
Подождите кого-нибудь из спецов по IB.
Пока что можно сделать только что-то типа
update table set field = (select sum);
update table set field = 0 where field is null;
update table set field = field + (select sum);
update table set field = 0 where field is null;
Но 4 update вместо 1, по-моему, многовато. Хотя работать будут быстро (если в каждом where id=? есть, конечно).
BlackKing (2003-11-27 12:41:00) [14]
хех...а в одном запросе ето можно сделать?
ето я написал 2 подзапроса, а их 7 :o)
Alex_Bredin (2003-11-27 12:41:00) [15]
> Cast не помогает. Пробовал и к Integer и к Double Precision
> приводить.
> Поля - Double Precision.
не могет быть.CAST Null в ноль превращает железно(для целых).
Sandman25 (2003-11-27 12:37:00) [16]
Если case нет, то в данном конкретном случае лучше сделать 2 select into variable, рассчитать нужное значение и затем устроить update.
BlackKing (2003-11-27 12:36:00) [17]
Cast не помогает. Пробовал и к Integer и к Double Precision приводить.
Поля - Double Precision.
Alex_Bredin (2003-11-27 12:33:00) [18]
если вещ-е то вроде нельзя.
а может и можно -пробовать надо. только не к INTEGER
Кщд (2003-11-27 12:32:00) [19]
согласно langref IB6 case нет
Alex_Bredin (2003-11-27 12:32:00) [20]
если поля целые, можно приводить результаты подзапросов CAST-ом к INTEGER.