Форум: "Прочее";
Текущий архив: 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