Fujitsu-Siemens
 
M A G A Z I N
 
SOFTWARE 
  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

 

VRH STRANE

(c) 2003 OMEGA - sva prava zadržana