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

Вниз

Опять не понимаю логику Oracle   Найти похожие ветки 

 
OW ©   (2011-11-21 11:05) [0]

Знаю как переписать для нужного результата, но почему же так выходит, как выходит.

пишу
select case
        when Function1(s.id) = 1 then 1
        else 0  
      end WOR
from SERVICES s
where ДЛИННОЕ_УСЛОВИЕ

часто s.id нет, т.е. набор данных пуст
и select case
        when Function1(s.id) = 1 then 1
        else 0  
      end WOR
возвращает null

однако, не логично ли было бы возвращать 0?
ведь я прошу вернуть либо 1, либо 0.

Мне не интересно различать варианты есть ли там что-то или если есть, то  вернет ли функция любое значение кроме 1.

Если вернет 1, то наше, в остальных случаях - не наше.
Не находите ли нелогичность?


 
OW ©   (2011-11-21 11:07) [1]


> возвращает null

нет!!!
ничего не возвращает т.е.


 
Inovet ©   (2011-11-21 11:13) [2]

Наверное, Function1 возвращает null?


 
OW ©   (2011-11-21 11:22) [3]


> нет!!!
> ничего не возвращает т.е.

вот.

т.е.
where ДЛИННОЕ_УСЛОВИЕ возвращает пустой Набор Данных (НД)

s.id - нет никакого вообще, даже null нет. НД пуст оказался.

и теперь
select case
       when Function1(s.id) = 1 then 1
       else 0  
     end WOR
выдает тоже пустой НД.

А мне кажется, что логичнее выдавать 0.


 
Sergey Masloff   (2011-11-21 11:30) [4]

Все правильно. Неопределенное значение нельзя сравнивать - это в стандарте SQL есть

Функция ничего не возвращать не может даже если ее написать так чтобы ничего не возвращать при вызове будет ORA-06503


 
Sergey Masloff   (2011-11-21 11:32) [5]

OW ©   (21.11.11 11:22) [3]
Вау. У тебя возвращать что-то из пустого набора данных - логично?


 
OW ©   (2011-11-21 11:37) [6]


> Sergey Masloff   (21.11.11 11:32) [5]

не совсем так
не из пустого набора, а функция от пустого набора.

вот вообще переписал так
========================================
create or replace function GET_1_IF_EXISTS_PPP_BY_DEVID(
pDEV_ID in number
) return number is
 Result number;
 DEVICE_ID number;
begin

 if pDEV_ID < 500000000 then
   DEVICE_ID := pDEV_ID + 500000000; else
   DEVICE_ID := pDEV_ID;
 end if;

select -1 into Result from dual;

select WOR
into Result
from (

select case
        when main.service.showservstatus(s.service_id) = "Работа" then 1
        else 0
      end WOR
from main.t_services s
where s.dev_id = DEVICE_ID
     and nvl(s.date_end, sysdate) >= sysdate
     and s.svctype = "1"

);


if (Result = 1) then
   Result := 1; else
   Result := 0;
 end if;


 return(Result);
end GET_1_IF_EXISTS_PPP_BY_DEVID;
========================================

пишу
select GET_1_IF_EXISTS_PPP_BY_DEVID(66077) from dual;
не 0 и не 1 вернулось


 
OW ©   (2011-11-21 11:42) [7]

т.е.
просто прошу вернуть 1, если число = 1
и 0 иначе.

А возвращается null.

но ведь:
иначе - все остальные случаи, кроме перечисленного(ых), не так ли?


 
Sergey Masloff   (2011-11-21 11:59) [8]

OW ©   (21.11.11 11:42) [7]
Ну он (оракл) не знает равно ли нечто единице или не равно потому что это нечто не число а некое специальное значение означающее неопределенность
If работает с четкой логикой - ДА и НЕТ

1=1 ДА
1=2 НЕТ

null=1 МОЖЕТ БЫТЬ ;-)
null <> 1 МОЖЕТ БЫТЬ :-)

В твоем случае возвращение 1 и 0 было бы в равной степени неправильным


 
OW ©   (2011-11-21 12:05) [9]

>> null=1 МОЖЕТ БЫТЬ ;-)
нет :)
null ничему не может быть равен

ладно, так перепишем
.......
where s.dev_id = DEVICE_ID
     and nvl(s.date_end, sysdate) >= sysdate
     and s.svctype = "1"

);

 if (Result is null) then
   Result := 0;
 end if;

 if (Result = 1) then
   Result := 1; else
   Result := 0;
 end if;

 return(Result);
end GET_1_IF_EXISTS_PPP_BY_DEVID;
=========

пишем:
select
 case
   when GET_1_IF_EXISTS_PPP_BY_DEVID(66066) is null then "null"
   else "not null"
 end asasa      
from dual;

вывод:
ASASA
1 null

но ведь ясно сказано было
...
 if (Result is null) then
   Result := 0;
 end if;
...


 
Inovet ©   (2011-11-21 12:26) [10]

> [7] OW ©   (21.11.11 11:42)
> но ведь:
> иначе - все остальные случаи, кроме перечисленного(ых),
> не так ли?

Нет: FALSE, TRUE, NULL.


 
OW ©   (2011-11-21 12:44) [11]


> Inovet ©   (21.11.11 12:26) [10]


>  FALSE, TRUE, NULL.

??!
>> If работает с четкой логикой - ДА и НЕТ
да-нет, третьего не дано
=================================

а к "православному" претензий нет

declare @Num int        
select @Num = WOR from OPENQUERY(ASRSTART, "select GET_1_IF_EXISTS_PPP_BY_DEVID(66066) WOR from dual")

if (@num = 1)
begin  
 print "ДА, равно"
end else
begin
 print "НЕ, не равно"
end;

if (@num is null)
print "NULL" else
print @num;

вывод
НЕ, не равно
NULL


 
sniknik ©   (2011-11-21 12:58) [12]

> да-нет, третьего не дано
дано дано... даже в MSSQL
SELECT CASE ID WHEN 1 THEN "один" ELSE "не один" END FROM Tsp WHERE ID = 1

поставь ID не существующий WHERE ID = -1 например.


 
Sergey Masloff   (2011-11-21 12:58) [13]

OW ©   (21.11.11 12:44) [11]
Это нестандартная но известная специфика SQL Server


 
Kerk ©   (2011-11-21 13:05) [14]

По-моему, вы тут о разном говорите. Причём тут IF, если в выборке ноль строк? До него просто дело не доходит.


 
Sergey Masloff   (2011-11-21 13:12) [15]

Kerk ©   (21.11.11 13:05) [14]
>По-моему, вы тут о разном говорите. Причём тут IF, если в выборке ноль >строк? До него просто дело не
Мы уже про другое ;-)

if (Result = 1) then
  Result := 1; else
  Result := 0;
end if;

и дальше селект из DUAL см. OW ©   (21.11.11 11:37) [6]


 
DiamondShark ©   (2011-11-21 14:04) [16]


> Sergey Masloff   (21.11.11 13:12) [15]


> и дальше селект из DUAL см. OW ©   (21.11.11 11:37) [6]

Т.е. вы с OW нам какбэ намекаете, что в операторе IF не выполняется ни одна ветка?

Это же такой <font size="72" color="red">БАГ</font>, что трудно поверить, если бы речь не шла про оракл.


 
OW ©   (2011-11-21 14:39) [17]


> что в операторе IF не выполняется ни одна ветка?

угу, я по крайней мере


 
sniknik ©   (2011-11-21 15:27) [18]

> Мы уже про другое ;-)
?
SELECT CASE NULL WHEN 1 THEN "один" ELSE "не один" END FROM Tsp WHERE ID = 1
MSSQL при верном условии, возвращая запись вернет "не один", т.е. значение, даже если в условии функция возвращающая NULL.

а в oracle, значит все выражение будет тоже NULL, хотя явно прописано ELSE.
так?


 
Kerk ©   (2011-11-21 15:35) [19]


> sniknik ©   (21.11.11 15:27) [18]
>
> > Мы уже про другое ;-)
> ?
> SELECT CASE NULL WHEN 1 THEN "один" ELSE "не один" END FROM
> Tsp WHERE ID = 1
> MSSQL при верном условии, возвращая запись вернет "не один",
>  т.е. значение, даже если в условии функция возвращающая
> NULL.
>
> а в oracle, значит все выражение будет тоже NULL, хотя явно
> прописано ELSE.
> так?

В Oracle будет точно так же, только что даже проверил на всякий случай.
Я вообще не понимаю чего они тут говорят :)


 
OW ©   (2011-11-21 15:50) [20]

sniknik ©   (21.11.11 15:27) [18]
- не понял
вот я про что

пишем:
create or replace function GET_TEST_MASTERDELPHI
return number is
 Result number;
begin
 select user_id
 into Result
 from main.t_users
 where 1 = 0;

 if (Result = 1) then
   Result := 1; else
   Result := 0;
 end if;

 return(Result);
end GET_TEST_MASTERDELPHI;
=============================================

юзаем:
select
case
when GET_TEST_MASTERDELPHI is null then "NULL"
ELSE "GET_TEST_MASTERDELPHI"  
end TST
from dual;
=======
и видим:
1 NULL


 
OW ©   (2011-11-21 15:53) [21]

или так пишем:

create or replace function GET_TEST_MASTERDELPHI
return number is
 Result number;
begin
 select user_id
 into Result
 from main.t_users
 where 1 = 0;
 
 if (Result is null) then
   Result := 0;
 end if;
 
 if (Result = 1) then
   Result := 1; else
   Result := 0;
 end if;

-- в баден-баден поедем
 if (Result is null) then
   Result := 0;
 end if;
 
 return(Result);
end GET_TEST_MASTERDELPHI;
============================

юзаем:
select
case
when GET_TEST_MASTERDELPHI is null then "NULL"
ELSE "GET_TEST_MASTERDELPHI"  
end TST
from dual;
=======
и видим:
1 NULL


 
Kerk ©   (2011-11-21 15:54) [22]

Что-то очень похоже на баг


 
OW ©   (2011-11-21 15:55) [23]

и так пишем, наконец, без вариантов казалось бы
...
 if (Result is null) then
   Result := 0; else
   Result := 0;
 end if;
 
 return(Result);
end GET_TEST_MASTERDELPHI;

юзаем:
select
case
when GET_TEST_MASTERDELPHI is null then "NULL"
ELSE "GET_TEST_MASTERDELPHI"  
end TST
from dual;
=======
и видим:
1 NULL


 
Kerk ©   (2011-11-21 15:58) [24]

Дык там же no_data_found


 
OW ©   (2011-11-21 16:08) [25]

да...
итого, так надо?

create or replace function GET_TEST_MASTERDELPHI
return number is
 Result number;
begin

 select user_id
 into Result
 from main.t_users
 where 1 = 0;
 
 if (Result = 1) then
   Result := 1; else
   Result := 0;
 end if;

 return(Result);
 
EXCEPTION
 WHEN NO_DATA_FOUND THEN
 BEGIN
   Result := 0;
   return(Result);
 END;  
end GET_TEST_MASTERDELPHI;


 
OW ©   (2011-11-21 16:11) [26]

т.е.
if (Result = 1) then
не выполняется, вываливается до этой строки

select user_id
from main.t_users
where 1 = 0;
нормально,

а  into Result
уже исключение..

ясно. Теперь понял. Спасибо, Ром


 
Kerk ©   (2011-11-21 16:16) [27]

В некоторых, не будем показывать пальцем, местах еще практикуют такое:
select MAX(user_id) into Result from main.t_users where 1 = 0;

Тоже вариант.
:)


 
Kerk ©   (2011-11-21 16:22) [28]

Интересный факт. Мало кто знает, но кроме NO_DATA_FOUND так же существует ошибка NO_DATA_NEEDED :)


 
Кщд   (2011-11-22 11:12) [29]

>Kerk ©   (21.11.11 16:16) [27]
если добавить к этому отсутствие UQ-ключа по user_id, получим трудноуловимую ошибку
на мой взгляд, надо честно обрабатывать exception.

>NO_DATA_NEEDED
экзотика
не нужная в 99.99% случаях
имхо


 
знайка   (2011-11-22 11:35) [30]

Опять 25.


 
Kerk ©   (2011-11-22 12:34) [31]


> Кщд   (22.11.11 11:12) [29]
>
> >Kerk ©   (21.11.11 16:16) [27]
> если добавить к этому отсутствие UQ-ключа по user_id, получим
> трудноуловимую ошибку
> на мой взгляд, надо честно обрабатывать exception.

На мой тоже.



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

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

Наверх




Память: 0.55 MB
Время: 0.009 c
15-1322026771
И. Павел
2011-11-23 09:39
2012.03.11
Скиньте, пожалуйста, mc.exe


2-1322435280
Vyacheslav
2011-11-28 03:08
2012.03.11
try except end;


2-1322567877
Gu
2011-11-29 15:57
2012.03.11
длина пароля из политик


15-1321134248
Кто б сомневался
2011-11-13 01:44
2012.03.11
Ктонить из форумчан хочет поиграть в Left4Dead2 или другие игры?


15-1321469110
wl
2011-11-16 22:45
2012.03.11
На хабрахабре открыта регистрация