2012-11-21 16 views
8

Moja ciągła frustracja polega na tym, że Oracle PL/SQL obsługuje typ danych bool, a Oracle SQL nie. To wielki ból w przysłowiowym, gdy chcesz przetworzyć zwrotną wartość logiczną PL/SQL z powrotem do codziennego SQL (przykład poniżej).Obsługa Bool Oracle SQL

Nawet strona z pytaniem-Tomem jest zblazowana na temat tego braku, informując, że powinieneś zakodować kolumny boolowskie jako kolumny o ustalonej wartości 'Y'/'N' CHAR, co jest tak kiepską odpowiedzią na tak wielu różnych poziomach, że nie wiedzieć, gdzie zacząć ją krytykować. W rzeczywistości jedyną rewolucyjną jakością tej odpowiedzi jest fakt, że (o ile niedawno odkryłem) wiele innych silników baz danych nie obsługuje również typu danych binarnych.

Tak czy inaczej - pytanie ...

mam obejście dla następującego problemu (choć brudny i gadatliwy), więc pytam to pytanie z ciekawości niż konieczności. Ale jedną z niewielu rzeczy, które mnie już zaskakują, jest pomysłowość sprytnych programistów, więc mam nadzieję, że jedno z was znajdzie rozwiązanie dla następnych.

W poniższym przykładzie, funkcja stock_pkg.is_in_stock() (która jest nieodłączną częścią mojego wniosku) zwraca wartość BOOL, rendering SQL nieprawidłowy (pamiętaj, SQL nie obsługuje Bool):

SELECT part_no, stock_pkg.is_in_stock(part_no) in_stock 
FROM parts_table 

Co potrzebne jest, aby znaleźć sposób korzystania z powyższej funkcji-call, aby wygenerować prawidłowy ciąg (varchar) wyjście w formacie:

PART_NO IN_STOCK 
------- ------------ 
AA  YES 
BB  NO 
CC  NO 

(można zastąpić „tak/nie” za „prawda/fałsz "," zielony/czerwony "," torys/labour, a nawet numeryczna 1/0, na wszystko, na czym mi zależy - tak długo, jak dane wyjściowe przypadają na jedną z dwóch różnych kategorii.)

Niestety, nie mam uprawnień do przepisywania oryginalnej funkcji w celu zwrócenia inny typ danych. Poza tym istnieją tysiące takich funkcji, które są rozmieszczone wokół większej aplikacji, co sprawia, że ​​niepraktyczne jest przepisywanie ich wszystkich.

W tym sensie rozwiązanie musi być rozwiązaniem "generycznym" (tj. Nie jest specyficzne dla tej funkcji). Na przykład nie wystarczy napisać tej funkcji jako stock_pkg.is_in_stock_chr(), ponieważ oznaczałoby to konieczność ponownego napisania wszystkich innych podobnych funkcji w mojej aplikacji.

Ja już próbowałem:

SELECT part_no, 
     CASE WHEN stock_pkg.is_in_stock(part_no) THEN 'y' ELSE 'n' END in_stock 
FROM parts_table 

a nawet własną funkcję Wrapper:

SELECT part_no, 
     my_bool_to_str(stock_pkg.is_in_stock(part_no)) in_stock 
FROM parts_table 

Ale nawet owijanie wartości logicznych wewnątrz innych konstruktów funkcjonalne nie wydają się być dozwolone przez Oracle SQL (przynajmniej nie w Oracle 10g).

Istnieje również możliwość napisania podzbioru wewnątrz kolumny in_stock, ale może to również skomplikować się w ekstremalnych przypadkach, a także będzie zależała od przypadku.

Tak jak mówię, mam nadzieję, że istnieje genialne rozwiązanie gdzieś (lub przynajmniej bardzo proste, które przypadkiem przeoczyłem).

Dzięki za poświęcony czas.

+0

Nie jest dla mnie jasne, jakie jest twoje pytanie. Pytasz, jak zwrócić wartość SQL do typu danych Boolean PL/SQL? –

+0

@DavidAldridge: Pytam, jak zwrócić boolean typu PL/SQL (zwrócony z funkcji PL/SQL) do kwerendy SQL. Mam prostą platformę zapytań SQL, która musi zwrócić wartość tej wartości logicznej generowanej przez PL/SQL użytkownikowi końcowemu. – cartbeforehorse

Odpowiedz

6

Można napisać własne otoki tak:

CREATE OR REPLACE FUNCTION my_bool_to_str(f varchar2) RETURN VARCHAR2 IS 

    b varchar2(2); 

BEGIN 

    EXECUTE IMMEDIATE 'declare bl boolean; begin bl := ' || f || 
        '; if bl then :1 := ''y''; else :1 := ''n''; end if; end;' 
    using out b; 

    return b; 

END; 

Następnie można nazwać tak:

SELECT part_no, 
     my_bool_to_str('stock_pkg.is_in_stock('|| part_no|| ')') in_stock 
FROM parts_table 

Różnica z owijki jest to, że dostaje varchar jako wejście i nie wartość logiczna, której silnik SQL nie rozpoznaje:

+1

To obejście jest inteligentne, ale naprawdę wymaga bindów =) –

+0

Dzięki za naprawienie @VincentMalgrat! –

+0

Nie myślałem, że można związać booleans, z 'execute natychmiastowy' lub' dbms_sql'. Dostaję od tego ORA-00457, tak jak to zrobiłem z moim podobnym pierwszym nożem. Czy czegoś brakuje? –