Dlouho jsem tu neukázal nějakou novinku a sám si ani nehrál – když pominu zklamání z novinky, která slibovala více indexů nad stejným setem sloupců. Přiznám se, že se mi moc nelíbí :/. Před vydáním v novinkách Oracle sliboval možnost více indexů nad stejnými sloupci, pokud budou mít jiné attributy – nedávno jsem koukal na implementaci a jiné atributy jsou chápány jako – jiný typ bitmap/b*tree, jiné partišnování, a unikátní/neunikátní. Čekal jsem víc – jako, že bude stačit, když se budou lišit tablespacem, kaluzulí paralllel apod. Navíc visible může být jen jeden (čekal jsem, že CBO si bude on-line vybírat lepší). Takže nakonec – seriously – nic moc.
Ale to byla jen taková stížnost. Dnes zařazuji do novinek něco, čemu Oracle řiká WHITE LIST, ale v manuálu je lepší hladat ACCESSIBLE BY klauzule.
O co jde? Určitě jste někdy pracovali na systému, který je otevřený a semtam je třeba opravit data, něco naspouštět, něco ohnout. Čapnout nějký kus kódu do clipboardu, hodit to žábě nebo (PL/)*SQL Developeru a spustit to. Nebo prostě spustit nějakou funkci z ruky. A nikdo z nás není neomylný, takže kdybych měl udělat top-list chyb bylo by to něco jako:
A jedna z typicky dalších chyb je, že programátor něco pustí a už nepustí nějakou další část, která je z buisness logiky důležitá. Spustíte proceduru, která sype data do tabulky a neuvědomíte si, že večer předtím běží job, který nad to tabulkou zakládá partitions. Spustíte procku na úpravu objednávky a neuvědomíte si, že když to spuští orgininál aplikace, že to někam loguje atd..
Oracle ACCESSIBLE BY klauzule umožňující nadefinovat procky/funkce/triggery/typy pouze ze kterých je možné daný kód pustit. Takže příklad, mějme funkci, která dejmetomu upravuje zákazníka:
create or replace procedure prc_print_ha accessible by (prc_call_with_log)
as
begin
dbms_output.put_line('Zde by se upravoval zákazník');
end;
Co je nového je červeně označená nová klauzule accessible by, která říká že jediný, kdo může vyvolat funkci prc_print_ha je prc_call_with_log (pro takovéto syntax clarity před to je vhodné napsat slovo procedure, aby bylo na první pohled vidět). Takže když vyvolám z ruky (ve stejném schématu) samostatnou funkci prc_print_ha:
begin
prc_print_ha;
end;
Tak díky nastavenému white listu jsem vyfuckován:
Error report:
ORA-06550: řádka 2, sloupec 1:
PLS-00904: insufficient privilege to access object PRC_PRINT_HA
ORA-06550: řádka 2, sloupec 1:
Takže následuje založení procedury, která se jmenuje prc_call_with_log. Ano, můžu založit až ex-post. Když zakládám proceduru/funkci s accessible by kaluzulí, tak nemusí programové jednotky ve white listu ještě existovat a přesto se to správně zkompiluje.
create or replace procedure prc_call_with_log as
begin
dbms_output.put_line('!zde se upravuje zákazník by '||user);
prc_print_ha;
dbms_output.put_line('done');
end;
A pokud nyní zavolám prc_call_with_log, tak jsem v cajku. Prc_call_with_log má právo volat prc_pring_ha a tedy výsledek na output je:
!zde se upravuje zákazník by AZOR
Zde by se upravoval zákazník
done
A tedy není žádná možnost upravit zákazníka (Zde by se upravoval zákazník) aniž bych to nezalogoval (!zde se upravuje zákazník by AZOR; done). Moc šikovná věcička! Která doufám, že bude hojně využivána. Těch chyb vzniklých spuštěním pouze části kódu aplikace z ruky už jsem viděl dost
Co k tomu říct? Je možné v accessible by vyjmenovat i procedury/funkce/triggery/typy/package z jiného schématu, pak je třebas schéma explicitně uvéct, něco jako accessible by (procedure azor3.haf, package uservasik.pck_metal). Co je ještě zajímavé je, že to vyfuckuje i SYSa – ani SYS nemá tu sílu pustit funkci s white listem jinak než přes vyjmenované jednotky ve white listu (a pochopitelně případný alter programové jednotky a změnu white listu).