 |
| |
Ivan Korać
Oracle tips: lepo pisanja code-a |
|
Savet: Četiri dokumenta koja uvek treba
imati pri ruci su: ERD model aplikacije, spisak Oracle rezervisanih
reči, listu ASCII karaktera i Naming Convection white paper.
| Posle 6 meseci teškog pisanja code-a
na različitim aplikacijama, male su šanse da se pisac seti šta
je i gde hteo da kaže. |
Oracle ne preproručuje niti ima ”Naming conventions” (NC). To ne
znači da ne postoje određena pravila ”lepog pisanja”. Do njih se
obično dolazi ličnim iskustvom (na žalost obično lošim) ili savetima.
Negde gde rade velike softverske grupe obično postoji white paper
–priručnik o korišćenju pravila pri davanju imena objektima, sa
preporukama za pisanja code-a.
Pre svega treba dobro dokumentovati code u samom programu. Posle
6 meseci teškog pisanja code-a na različitim aplikacijama, male
su šanse da se pisac seti šta je i gde hteo da kaže. Uz to, kad
više ljudi radi na istom code-u pred vama se nalazi nepoznati mutant.
E sad još zamislite sve te aplikacije kako se vrte po raznim zemljama
sveta u različitim verzijama i . . . šansa za postojanje haosa je
izvanredna.
U primeru na slici 1, komentar se nalazi u package specifikaciji
i time postaje “vidljiv” za razne alate. Kad se specifikacija otvori
npr. (Quest-ovim) SQLNavigatorom može da se vidi “modification history”
i trenutni status aplikacije - odlično za početi.

Slika 1
Pošto ste u zaglavlje specifikacije uneli šta planirate da uradite,
dalje je potrebno definisati objekte globalnog nivoa u zaglavlju
body-a package-a. Treba koristiti jednostavna pravila imenovanja,
ali striktno.
PL/SQL coding standardi mogu biti: varijable počinju sa v_, function
i procedure parametri sa p_, cursor-i počinju sa c_, collection-e
sa t_.
Druga tipična pravila su sledeća:
Funkcije, procedure i promenljive treba da imaju smislena imena
kao "update_dealer_labour", "l_counter" itd.
Package-i završavaju na _pkg,
Type-ovi završavaju na _type,
Moje sveto pismo: promenljive zavisno od nivoa (scope) imaju prefiks:
g_ , l_, p_ (vidi sliku 3)
Primer 1:
create package war_load
as
g_global_variable varchar2(10);
procedure first_load( p_parameter_variable in date )
is
l_local_variable number;
begin . . .
U primeru na slici 2 nalazi se zaglavlje jednog package body-a.
Obratite pažnju na pravila imenovanja: globalnih promenljivih (“vidljivih”
u celom package-u), izuzetaka (exception), slogova (record) itd.
Mnoštvu polaznih ili default vrednosti i konstanti dodeljena su
imena koja su lako razumljiva u daljem korišćenju code-a.

Slika 2
Slika 3 pokazuje kako se dalje koriste prethodno definisani elementi.
Na primer, definiše se nivo greške ako do takve dođe: g_ErrorAndContinue
. Po završetku ovog package-a pokreće se novi koji treba da kreira
hiperkocku (cube) sa podacima. Prvo se ispituje da li je bilo greške
i kog nivoa. Priznaćete da je za nekog ko čita code lakše da razume:
ErrorAndContinue nego suvi broj 4.
Kod datawarehousa DW, pri procesu ETL-a (extract, transform, load)
obično se koriste 2 nivoa: input layer-a IL i storeage layer-a SL.
Prvo se podaci pune u IL, a zatim proveravaju integriteti i vrše
razne kalkulacije a onda tako sublimirani podaci smeštaju u SL.
U primeru se može videti da su imena IL tabela sa prefiksom: IL_
.
Ime cursor-a počinje sa c_ i nastavlja se sa IL, čime se jednostavo
objašnjava izvor podataka (source) za cursor.
Definicije tipa reda (rowtype) imaju u sufiksu _il / _sl . U proceduri:
ConvertWAR_Manuf_Labour (crveni pravougaonik) biće jasno sta je
izvorni podatak (il) i gde će posle obrade ciljni (u sl). Sledeća
procedura će zatim popunjeni sl red upisati u DW. Obratite još jednom
pažnju na argumente procedure ConvertWAR_Manuf_Labour: tri lokalna,
jedan iz pozivajuće procedure i jedan globalani. Kad pređete na
čitanje coda ove procedure otklonjene su sve mogućnosti zabune.

Slika 3
Prednosti korišćenja NC pravila su mnogobrojne. Pažljivo izabrana
NC će umanjiti administrativne obaveze oko upravljanja različitim
objektima i učiniti DBA posao osetno lakšim. Korišćenjem NC pri
kreiranju index-a, constraint- a ili partition-a izbeći će se glavobolja
sa Oracle generisanim dinamičkim imenima.
Na primer: import-ovana baza iz export-ovanog dump file-a, imaće
različita index i constraint imena, tipa: SYS_CXXXX. Siroti DBA
treba da napiše mali detektivski roman: šta je šta?
Još gore: uradite export neke tabele i to uključi i SYS_CXXXX imena.
Kad probate import dobijete grešku: to sistemsko ime već koristi
neki drugi constraint. A pri tome ste (kao i uvek) u vremenskom
škripcu, jer radite danas za juče.
Primer 2:
Kada dođe do narušavanja constraint-a vidi se nedostatak NC – šta
je SCOTT.SYS_C001264 ?
SQL> alter table emp add primary key (empno);
Table altered.
SQL> insert into emp (select * from emp);
insert into emp (select * from emp)
*
ERROR at line 1:
ORA-00001: unique constraint (SCOTT.SYS_C001264) violated
NAMING CONVENTION za DB objekte
Početi imena tabela sa kratkim prefiksom koji identifikuje aplikaciju
kojoj pripadaju (npr. prva 3 karaktera)
Asocirane objekte povezati preko imena kad god je to moguće. Npr.
koristiti isto ime za tabelu i njen synonym.
Ugraditi ime objekta u ime drugog objekta: uključiti ime tabele
u naziv njenog primary key constraint-a.
Uključiti u imena indeksa ime tabele i sufiks _idx ili jednostavno
_i ili _bi za bitmap index. Koristiti _idx01, idx02, idx03 itd...
kada ima više indeksa i/ili se koristi više od 2 kolene za indeksiranje.
Da bi se razlikovali tipovi constraint-a poželjno je dodati razumljiv
sufiks, npr: _UK za unique constraint, _FK i _PK za foreign i primary
key constraint, _CK za check constraint, _NN za NOT NULL itd.
Trigger-e bi trebalo nazivati po tabeli na kojoj se izvršavaju,
a tip trigger-a smisleno uključiti u ime trigger-a. Npr. “before
update trigger on every row” moze sadržati kratko BUR, što ukazuje
da se trigger izvršava pre update statement-a, a na svakom redu
koji će biti update-ovan u tabeli. Za before insert trigger npr:
table_name_bi ili _tbi , a ako su mogući višestruki before insert
trigger-i onda treba dodati i brojeve.
Različiti primeri:
A) Index-i:
index_name = indextype_tablename_columnname (+columnname)
npr. kreiranje bitmap index-a: bi_emp_ename_deptno on emp(ename,
deptno);
Da li je index local ili global?
Ako je to u imenu indeksa nema potrebe za upitom na: user_part_indexes.
select index_name, locality
from user_part_indexes
where table_name='ITEM';
INDEX_NAME LOCALI
------------------------------ ------
GI_ITEM_YEAR_MONTH_DAY GLOBAL
LI_ITEM_ORD_ID LOCAL
B) Constraint-i:
constraintname = typeconstraint_tablename_columnname(-columnname).
Npr. za check constraint deferred:
alter table emp add constraint cd_emp_sal check (sal<10000) deferrable
initially immediate;
Know-How
Ako ste u projektu obezbedili da vaše tabele imaju isti prefiks
lako će te doći do različitih informacija. Script na slici 4 lista
podatke za tabelu i sve njene indekse.

Slika 4
Script na slici 5 lista sve tabele modula sa ulančanim redovima.
slika 5
|