2016-09-16 13 views
15

To wygląda trochę śmiesznie, ale naprawdę Oracle 11g pozwala na takie zapytanie do uruchomieniaDlaczego Oracle pozwala na posiadanie kilku podkwerend z tą samą aliasową nazwą w klauzuli WITH?

with 
    a as (select 1 from dual), 
    a as (select 2 from dual) 
select * 
from a; 

Zwraca wynik pierwszego podzapytania (czyli 1).

Po prostu nie mogę sobie wyobrazić sytuacji, w której taka funkcja mogłaby być przydatna. W moim przypadku spowodowało to raczej problem, gdy zapomniałem zmienić nazwę podkwerendy po skopiowaniu/wklejeniu, a ogólne zapytanie zwróciło błędne/nieoczekiwane wyniki. Na szczęście zapytanie było dość proste, a powód został natychmiast wykryty.

W każdym razie, spodziewałbym się, że Oracle wyrzuci i będzie wyjątek w takim przypadku.

Moje pytanie brzmi, czy takie zachowanie jest cechą czy błędem? Jeśli funkcja, gdzie może być przydatna?

Dzięki.

BTW, SQLite nie pozwala na uruchamianie podobnych zapytań i zgłasza wyjątek "zduplikowanej nazwy tabeli WITh". Nie próbowałem jeszcze żadnych innych silników db.

+0

Postgres też tego nie akceptuje. –

+1

Założę się, że to błąd - z pewnością możesz zgłosić problem w witrynie My Oracle Support. –

+0

Powielane w 12.1.0.2. –

Odpowiedz

-2

Nie jest przydatny, ale jest zgodny z tym, jak Oracle przetwarza zduplikowane nazwy kolumn.

+1

Czy mógłbyś to wyjaśnić?Co robi firma Oracle ze zduplikowanymi nazwami kolumn, których zwykle nie obsługują inne usługi DBMS? –

1

Klauzuli WITH można używać również z funkcjami. Nie jestem pewien, czy był dostępny z 11g, ale jest z 12c. Tak więc ten "bug" może być niezbędny do przeciążenia funkcji.

Na przykład ta procedura używa dokładnie tej samej funkcji dwa razy, z tymi samymi typami danych wejściowych/wyjściowych.

WITH 
    FUNCTION get_date(pid IN VARCHAR2) RETURN VARCHAR2 IS 
BEGIN 
RETURN 'date is '|| pid; 
END; 
    FUNCTION get_date(pid IN VARCHAR2) RETURN VARCHAR2 IS 
BEGIN 
RETURN 'date is '|| pid; 
END; 
SELECT get_date(cast(sysdate as varchar2(20))) 
FROM dual 
; 
/

Zgodnie z oczekiwaniami, to zwraca błąd:

ORA-06553: PLS-305: previous use of 'GET_DATE' (at line 1) conflicts with this use 

Ale jeśli przeciążenie funkcji, a więc ma taką samą nazwę, ale akceptuje różne rodzaje parametrów, to będzie działać. Procedura zostanie uruchomiona bez błędu, a w zależności od typu danych zmiennych zostanie użyta prawidłowa funkcja.

WITH 
    FUNCTION get_date(pid IN VARCHAR2) RETURN VARCHAR2 IS 
BEGIN 
RETURN 'date is '|| pid; 
END; 
    FUNCTION get_date(pid IN DATE) RETURN VARCHAR2 IS 
BEGIN 
RETURN pid+1; 
END; 
SELECT 
get_date(cast(sysdate as varchar2(20))) /*example1*/ 
--get_date(sysdate)     /*example2*/ 
FROM dual 
; 
/

Przykład 1 Wydajność: date is 16-MAR-17 Przykład 2 Wydajność: 17-MAR-17

więc może być zdolny do wykorzystania podzapytania z tej samej nazwie związane umożliwiając przeciążone funkcje. Choć nadal wydaje się być błędny i nie udało mi się znaleźć dokumentacji na ten temat.

Powiązane problemy