![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Decode в InterBase [D6]
ruslan_as © (2003-11-10 11:39:00)
Досталось на мою долю перевести Oracle на InterBase. Там есть функция decode. А в InterBase что-нибудь похожее есть?
Romkin (2003-11-10 14:57:00) [1]
Ну почему же жирно для каждого случая? У меня, например, роль всех view выполняют подобные ХП. Об отчетах я уже и не говорю, там это строго. В результате, во-первых, все работает быстро, а во-вторых, имхо, гораздо приятнее на клиенте писать простейщий запрос к ХП, а не дикий join дюжины таблиц :)
Romkin (2003-11-10 14:54:00) [2]
В частности, я бы написал
SELECT
o.ID,
o.Description,
CASE
WHEN (o.Status IS NULL) THEN "new"
WHEN (o.Status = 1) THEN "confirmed"
WHEN (o.Status = 3) THEN "in production"
WHEN (o.Status = 4) THEN "ready"
WHEN (o.Status = 5) THEN "shipped"
ELSE "unknown status """ || o.Status || """"
END
FROM Orders o;
как
create procedure LIST_ORDER_STATUS
returns (ID integer, DESCRIPTION varchar(скока там...), STATUS_NAME varchar(<чтобы влезло>))
as
declare variable status integer;
begin
for select ID, DESCRIPTION, STATUS
from ORDERS
into :ID, :DESCRIPTION, :STATUS
do begin
STATUS_NAME = "unknown status """ || o.Status || """";
if (STATUS = 1) then STATUS_NAME = "confirmed";
if (STATUS = 3) then STATUS_NAME = "in production";
if (STATUS = 4) then STATUS_NAME = "ready";
if (STATUS = 5) then STATUS_NAME = "shipped";
suspend;
end
end
И вызов, ессно,
select * from LIST_ORDER_STATUS
И все, ничего сложного
Vlad (2003-11-10 14:52:00) [3]
> Romkin © (10.11.03 14:47) [15]
Это тогда для каждого подобного случая свою ХП писать ? Слишком жирно по-моему :)
Речь идет именно о аналоге ф-ции decode, которого судя по всему в IB нет, если не считать [13], потому как это справедливо только для FB и Ya, на сколько я помню.
Romkin (2003-11-10 14:47:00) [4]
При чем здесь функция? Просто вместо запроса делаешь ХП с for select, а внутри цикла - IF с нужной установкой выходного параметра, и все.
Vlad (2003-11-10 14:45:00) [5]
> Romkin © (10.11.03 14:42) [13]
Я бы тоже хранимку сделал для надежности, но разве в IB можно сделать ф-цию с переменным кол-вом аргументов ?
Romkin (2003-11-10 14:42:00) [6]
Энто вам Firebird 1.5 пользовать надо, там и CASE и COALESCE есть. По стандарту. На отклонения от стандарта SQL надеяться не надо, decode не будет :)
Вот что можно в полуторке:
SELECT
o.ID,
o.Description,
CASE
WHEN (o.Status IS NULL) THEN "new"
WHEN (o.Status = 1) THEN "confirmed"
WHEN (o.Status = 3) THEN "in production"
WHEN (o.Status = 4) THEN "ready"
WHEN (o.Status = 5) THEN "shipped"
ELSE "unknown status """ || o.Status || """"
END
FROM Orders o;
Хотя я бы все равно предпочел select SP, оно и надежнее, да и быстрее работать должно, а пользователю все равно, откуда select идет
Danilka (2003-11-10 14:40:00) [7]
[11] Vlad © (10.11.03 14:37)
да ладно. просто хотел побыть немного занудой. :))
Vlad (2003-11-10 14:37:00) [8]
> Danilka © (10.11.03 13:57) [9]
Согласен, я в курсе этого :)
А теперь сравним Danilka © (10.11.03 13:00) [4] и Vlad © (10.11.03 13:06) [5] и поймем что это одно и тоже, только написано разным языком. Но придрались именно ко мне, за мою неточность, да простят меня боги если я их чем прогневил и что не привел целиком справку по ф-ции decode.
Danilka (2003-11-10 14:01:00) [9]
а nvl я в пример засунул, т.к. как еще показать, что декоде вернул нулл? :))
Danilka (2003-11-10 13:57:00) [10]
[7] Vlad © (10.11.03 13:45)
[8] Johnmen © (10.11.03 13:46)
если кол-во аргументов будет четное, то в том случае, когда первый аргумент не равен ни одному из четных аргументов, вернется последний аргумент. Если ко-во аргументов - нечетное, то в случае, когда первый аргумент неравен ниодному из четных (по счету) аргументов, вернет не последний аргумент, а null.
теперь смотрим внимательно:
смотрим внимательно: [5] Vlad © (10.11.03 13:06)
Если а не равно ни b, ни d, ни f, и т.д., и кол-во аргументов будет нечетное, то вернет не h, а null.
Вот что я имел ввиду. :))
Johnmen (2003-11-10 13:46:00) [11]
>Danilka © (10.11.03 13:14)
А где в его посте nvl?
:)))
Vlad (2003-11-10 13:45:00) [12]
> Danilka © (10.11.03 13:14) [6]
> [5] Vlad © (10.11.03 13:06)
>
> SELECT nvl(decode(dummy,"Z",1,"Y",2),-1) FROM dual
>
> вернул -1, а не 2, как должен-бы был исходя из твоего поста.
> :))
Не понял, причем тут это ? Я об NVL ни слова не говорил.
Вот если напишешь
SELECT decode(dummy,"Z",1,"Y",2,3) FROM dual
То вернет - 3 - чесслово :)
Danilka (2003-11-10 13:14:00) [13]
[5] Vlad © (10.11.03 13:06)
SELECT nvl(decode(dummy,"Z",1,"Y",2),-1) FROM dual
вернул -1, а не 2, как должен-бы был исходя из твоего поста. :))
Vlad (2003-11-10 13:06:00) [14]
> Romkin © (10.11.03 12:23) [3]
decode(a,b,c,d,e,f,g,.....,h)
если а=b, вернуть c
если а=d, вернуть e
если а=f, вернуть g
.....
иначе вернуть h
Danilka (2003-11-10 13:00:00) [15]
[3] Romkin © (10.11.03 12:23)
классная вещь!
пример из документации:
SELECT DECODE(rating, NULL, 1000, "C", 2000, "B", 4000, "A", 5000)
INTO credit_limit FROM accts WHERE acctno = my_acctno;
Если rating is null, то вернет 1000, если rating = "C", вернет 2000, равен "B" вернет 4000, равен "A" вернет 5000. Если добавить еще однин аргумент, то будет возвращать его, если rating не равен ни одному из приведеных значений.
Удобная штука, привыкаешь к ней быстро.
Romkin (2003-11-10 12:23:00) [16]
А что делает decode?
ruslan_as (2003-11-10 12:22:00) [17]
>>Danilka "успокоил". Все равно спасибо! Время даром не потратил.
Danilka (2003-11-10 11:41:00) [18]
ruslan_as © (10.11.03 11:39)
Вроде нету. Думаю, придется для этого писать ХП и делать селект из него.
У меня то-же ломки - трудно отвыкать от decode. :))