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

Вниз

Опять не понимаю логику 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.53 MB
Время: 0.004 c
6-1253185020
bvv
2009-09-17 14:57
2012.03.11
Проблема с потоками сканирования


15-1321859139
OW
2011-11-21 11:05
2012.03.11
Опять не понимаю логику Oracle


15-1321796904
И. Павел
2011-11-20 17:48
2012.03.11
Порекомендуйте сервер для игры в шахматы


2-1322608424
vit196sh
2011-11-30 03:13
2012.03.11
Помогите с несложной программой пожалуйста)))


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





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский