Oracle introducerede en ny funktion, gruppe for eliminering, til forespørgsler, hvor gruppe for kolonne også er tabellens unikke nøgle. Som med mange nye funktioner har denne stadig ikke fået løst alle knæk. Problemet opstår, når nøgleværdier manipuleres med funktionskald. Følgende eksempel vil illustrere problemet ved at bruge en tabel med en DATE som den primære nøgle og ved at udtrække året udtrækkes med TO_CHAR eller EXTRACT.
En tabel oprettes som følger:
create table bug_test_calendar( cal_name char(17), bus_dt date, updt_timestamp timestamp (6) default systimestamp, constraint pk_bug_test_calendar primary key (bus_dt) ) / insert into bug_test_calendar (bus_dt) select sysdate + 10 * rownum from all_objects where rownum <= 40 / commit;
Når forespørgslen vist nedenfor udføres, giver den følgende resultater:
select to_char(bus_dt,'YYYY') bus_dt, count(*) ct from bug_test_calendar group by to_char(bus_dt,'YYYY') order by to_char(bus_dt,'YYYY') / BUS_DF CT ------- -- 2020 1 2020 1 ... 2020 1 40 rows returned
Oracle 'ved' ikke, at nøgleværdierne er blevet manipuleret, så de ikke længere er unikke, derfor anvender optimeringsværktøjet den unikke-nøgle-baserede gruppe-ved-eliminering med mindre end fantastiske resultater,
EXTRACT er ikke bedre og giver de samme resultater. Denne adfærd styres af parameteren "_optimizer_aggr_groupby_elim", som er sat til sand som standard. Da det er en skjult parameter, rapporteres dens indstilling ikke af Oracle i nogen af V$PARAMEter- eller V$SPPARAMETER-visningerne. Løsningen er blot at sætte denne parameter til falsk. Men at have den aktiv kan hjælpe andre gruppe-for-forespørgsler, hvor de unikke nøgleværdier ikke manipuleres.
Indtast Oracle 19c, hvor denne funktionalitet er delvist rettet:
select to_char(bus_dt,'YYYY') bus_dt, count(*) ct from bug_test_calendar group by to_char(bus_dt,'YYYY') order by to_char(bus_dt,'YYYY') / BUS_DF CT ------- -- 2020 40
Desværre er EXTRACT stadig ødelagt i 19c:
select to_char(bus_dt,'YYYY') bus_dt, count(*) ct from bug_test_calendar group by extract(year deom bus_dt) order by extract(year deom bus_dt) / BUS_DF CT ------- == 2020 1 2020 1 ... 2020 1 40 rows returned
Givet virkelig unikke nøgleværdier ville en gruppe-for-forespørgsel naturligvis producere en optælling på 1 for hver nøgle. Og lige så indlysende burde Oracle være i stand til at genkende, hvornår værdier ikke længere er unikke og påberåbe sig den rette gruppe-for-mekanisme. Det er tilbage at se, om versioner efter 19c vil rette den anden betingelse og dermed returnere korrekte resultater uden at skulle slå denne funktion fra.
Dette påvirker muligvis ikke enhver installation af Oracle nyere end 12.1, men det er værd at vide, hvis forkerte resultater begynder at blive vist i udvalgte grupper efter forespørgsler.
# # #
Se artikler afDavid Fitzjarrell