background image

 

Rozdział 20 

Reguły logiki aplikacji na serwerze 
bazy danych 

Reguły logiki aplikacji są ograniczeniami, warunkami lub testami, które opisują 
zasady realizowania celu organizacji. Mogą one być wyrażone w słowach języka 
naturalnego, które techniczni laicy, zaznajomieni ze związanymi z nimi procesami 
wykonawczymi, bez trudu zrozumieją. Natomiast fachowcy od baz danych biorą 
owe reguły słowne i kodyfikują je w swych bazach danych i aplikacjach. A oto 
przykłady niektórych powszechnie spotykanych reguł: 

„Wszyscy najemcy muszą dostarczyć pełnej informacji o swym zatrudnieniu. 

„Wszystkie czynsze za najem ustalone są domyślnie na 950$ miesięcznie. 

„Depozyt zastawny na nieruchomość musi wynosić przynajmniej połowę 

wartości czynszu dla tejże nieruchomości. 

„Czynsz staje się zaległy po upływie pięciu dni od zawartego w umowie najmu 

terminu płatności. 

„Za każdy dzień zwłoki w uiszczeniu czynszu wymierzana jest opłata karna 

w wysokości 5$. 

„Najemcy, dzierżawiący więcej niż jedną nieruchomość, uzyskują 10% zniżki na 

każdą dodatkową nieruchomość. 

„Wszystkie umowy najmu muszą obowiązywać przez przynajmniej sześć 

miesięcy. 

„Nowy najemca nie może wprowadzić się do nieruchomości, zanim nie 

rozpocznie się ustalony w umowie okres najmu. 

Każda z tych reguł ma w bazie danych lub aplikacji odpowiadający jej element. 
Ich artykulacja w 

zdaniach języka naturalnego jest zrozumiała dla osób 

związanych z danym przedsięwzięciem. Natomiast ich reprezentacja jako zbiór 
elementów bazy danych lub aplikacji jest zrozumiała dla programistów baz danych 
lub aplikacji. Zdolny „architekt” systemów klient/server będzie w stanie zrozumieć 
reguły wypowiedziane na oba sposoby. 

W rozdziale tym omawiamy serwerową stronę implementowania reguł logiki 
aplikacji w aplikacjach bazodanowych. Są i tacy, którzy implementacje reguł 
logiki aplikacji omawiają jako koncepcję teoretyczną, niezależną od ograniczeń 

background image

610 

Część IV 

bazy danych i obiektów programu, niezbędnych do ich zaimplementowania. Ja zaś, 
choć zgadzam się w pełni, że zanim przystąpi się do implementowania reguł logiki 
aplikacji, trzeba je w pełni zrozumieć, to oddzielanie ich od ich praktycznego 
zastosowania uważam za nieporozumienie. Zwłaszcza dlatego, że w końcu i tak 
zostaną sprowadzone do realnych obiektów w bazach danych lub programach. 

Całkowite oddzielanie reguł logiki aplikacji od ograniczeń, niezbędnych do ich 
zaimplementowania, wydaje się nierozsądne także i ze względu na ścisłe 
pokrewieństwo między nimi. Fundamentalnym celem każdej organizacji winno 
być zapewnienie integralności, lub inaczej spójności, jej danych. Na pewno żadna 
firma nie pragnie bazy danych usianej osieroconymi wierszami, niepoprawnymi 
wartościami kolumn lub innymi anomaliami w danych. I na odwrót, elementarna 
integralność i „spolegliwość” danych jest fundamentem, na którym organizacja 
może się oprzeć z pełnym zaufaniem. Tak więc oba te tematy - reguły logiki 
aplikacji i integralność danych - są nierozłącznie ze sobą powiązane. 

Istnieją zasadniczo trzy szkoły myślenia w sprawach dotyczących właściwego 
miejsca reguł logiki aplikacji: umiejscowienie na serwerze, umiejscowienie 
w oprogramowaniu klienta i umiejscowienie w oprogramowaniu pośredniczącym 
(middleware). Oczywiście to, że aplikacja klient/serwer o nietrywialnym stopniu 
złożoności wszystkie te podejścia pomiesza ze sobą, można uznać za dowiedziony 
pewnik. Jest to tak pewne, jak z góry pewny jest podział tejże aplikacji na część 
kliencką i część serwerową.  

Niesłychane bogactwo wcieleń, jakie przybierać mogą reguły logiki aplikacji, 
stanowi jedno z największych wyzwań dla zdroworozsądkowego programowania 
systemów klient/serwer. Czasy prostego sprawdzanie poprawności danych 
w systemie dBASE typu 

@...SAY...GET

 minęły już bezpowrotnie. 

W rozdziale tym omówimy słabe i mocne strony każdego z tych podejść, 
a następnie szczegółowo zgłębimy bazujące na serwerze reguły logiki aplikacji. 
Nie miejmy złudzeń - przy budowaniu skomplikowanych aplikacji klient/serwer 
będziemy nieuchronnie mieszać ze sobą implementacje reguł logiki aplikacji 

programowaniu stacji roboczej klienta, serwera, i 

być może nawet 

implementacje tych reguł w oprogramowaniu pośredniczącym. Miejmy jednak 
nadzieję,  że oddzielne przebadanie każdej z 

tych warstw przygotuje nas 

w wystarczającym stopniu do naszego nowego zadania. 

Ściślejsza definicja reguł logiki aplikacji 

Przed omówieniem reguł logiki aplikacji realizowanych po stronie serwera 
zdefiniujemy bardziej szczegółowo, czym w istocie są reguły logiki aplikacji. 
Przeanalizujemy w tym celu rozmaite postacie, jakie reguły logiki aplikacji mogą 
przybierać, i opowiemy o funkcji, jaką każda z nich pełni. 

background image

 Rozdział 20 Reguły logiki aplikacji na serwerze bazy danych 

611

 

Skuteczne zaimplementowanie reguł logiki aplikacji zapewnia, że dane rezydujące 
w bazie danych są zgodne z regułami i praktyką postępowania w danej organizacji. 
Jednym ze sposobów osiągnięcia tego celu jest takie określenie każdej kolumny 
w każdej tabeli bazy danych, by chroniła ona przed wprowadzeniem wartości 
naruszających reguły organizacji. Z 

perspektywy bazy danych oznacza to 

zastosowanie wobec danych pewnych więzów lub ograniczeń  (constraint), 
zapewniających,  że dane zawierać  będą tylko poprawne wartości. To właśnie 
przychodzi nam zwykle na myśl, gdy słyszymy termin reguły logiki aplikacji.  

UWAGA: 

W obrębie tego rozdziału terminów logiki aplikacji i ograniczenia lub więzy 
używamy zamiennie. Ograniczenia są podstawową formą, jaką reguły logiki 
aplikacji przyjmują w bazach danych i aplikacjach. Tak naprawdę to określenie 
ograniczenia nigdy mi się nie podobało - niekiedy ograniczenia wcale nie 
ograniczają. Czasami definiują wartości domyślne dla kolumn, czasami znów 
ustanawiają relacje między tabelami. W tym rozdziale reguły logiki aplikacji 
stosowane będą często w sposób generalny, jako odnoszące się do tych elementów 
baz danych i aplikacji, które je implementują. 

Jednak samo chronienie bazy danych przed niepoprawnymi wartościami jeszcze 
nie wystarczy. Reguły logiki aplikacji, w odniesieniu do baz danych, spełniają 
w rzeczywistości trzy niezależne zadania: nie dopuszczają niepożądanych danych 
do bazy, definiują zależności między kolumnami i tabelami, oraz opisują sposób, 
w jaki dane powstają w bazie. Każde z tych zadań omówię teraz oddzielnie. 

Ograniczenia nie dopuszczają niepoprawnych danych do bazy danych. Definiują 
także wartości domyślne dla kolumn, jeśli rzeczywiste wartości nie zostały 
dostarczone. Przykładem takiego ograniczenia jest: „wszystkie faktury muszą 
zawierać aktualną informację o kliencie”. Z punktu widzenia bazy danych 
limitowałoby to - lub ograniczało - wartości, jakie mogą być przechowywane 
w tabeli INVOICE. Innym przykładem ograniczenia mogłoby być: „wartości 
w kolumnie 

PaymentType

 muszą pochodzić z następującej listy: 

'C'

'H'

'R'

”. Ograniczenie, które definiuje wartość domyślną dla kolumny, może być 

wyrażone jako: „domyślnym sposobem płatności jest gotówka”.  

Definicje reguł logiki aplikacji mogą również określać zależności między tabelami 
(na przykład „dla każdej faktury musi być przynajmniej jedna zamówiona 
pozycja”) i wewnątrz-tabelowe zależności między kolumnami (takie jak „kolumna 

Commission

 w 

tabeli SALES równa się kolumnie 

AmountOfSale

 

pomnożonej przez .07”). Osobiście wolę unikać wewnątrz - tabelowych zależności 
między kolumnami, obliczenia takie jak te wykonując zwykle na bieżąco, lecz są 
pewne sytuacje, w których jest to niemożliwe. W tym przykładzie kolumna 

Commission

 jest zależna od kolumny 

AmountOfSale

, zatem można by nie 

background image

612 

Część IV 

bez racji utrzymywać, iż takie uzależnienia uniemożliwiają dokonanie pełnej 
normalizacji tabel.  

Przy pomocy reguł logiki aplikacji można opisywać pochodzenie elementów 
danych. Opis pochodzenia elementu wskazuje na jego źródło: gdzie dany element 
bazy danych powstał, w jaki sposób został wyprowadzony, obliczony czy 
wygenerowany? Czy jest on agregacją kolumny X w tabeli Y? Prostym 
przykładem mogłoby tu być: „saldo „winien” księgi głównej jest uaktualniane 
poprzez dodawanie do niego sum nowych transakcji „do wypłaty””. Definiuje to 
pochodzenie lub źródło salda „winien” księgi głównej. 

Jak już wspomniałem, lepiej jest unikać wyprowadzania jednego elementu danych 
z innego. Nie twierdzę tym samym, że nie należy tego nigdy robić, lecz że trzeba 
starannie rozważyć wszystkie możliwe konsekwencje. Wyprowadzanie jednego 
elementu danych z innego tworzy zależność między nimi oboma. Może to być 
nieuniknione, lecz może i doprowadzić do poważnych kłopotów. Jeśli dana 
źródłowa ulegnie zmianie, to także i dana zależna musi zostać zmieniona. Zwykle 
chronimy się przed tą niedogodnością implementując mechanizmy „księgowania” 
(posting) danych. Dane, które zostały zaksięgowane, uaktualniają swe elementy 
zależne (tak jak w przypadku salda „winien” księgi głównej) i jednocześnie 
przestają być redagowalne. Po uaktualnieniu elementów zależnych  żadne inne 
modyfikacje nie są już dozwolone.  

Teraz, gdy już nieco lepiej rozumiemy, czym są reguły logiki aplikacji, 
zastanówmy się, jak najlepiej je zaimplementować. Jak już wspomniałem, istnieją 
trzy szkoły w sprawie najodpowiedniejszego miejsca dla reguł logiki aplikacji. 
Określenie zaś  właściwego miejsca dla reguł logiki aplikacji wpływa silnie na 
sposób, w 

jaki zostaną zaimplementowane. Jeśli zaimplementujemy je na 

serwerze, to oczywiście zrobimy to z pomocą ograniczeń i podobnych im środków. 
Jeśli implementację reguł logiki aplikacji umiejscowimy w oprogramowaniu 
klienta, to użyjemy do tego kodu programu. Jeśli zaś reguły logiki aplikacji 
wbudujemy w 

oprogramowanie pośredniczące, to trzeba będzie skorzystać 

z narzędzi dostarczanych przez dany produkt. 

Implementacje reguł logiki aplikacji na serwerze 

Choć podejrzewam, że przemawia przeze mnie niepoprawny administrator baz 
danych (DBA), to niezachwianie obstaję przy bazujących na serwerach 
implementacjach reguł logiki aplikacji. Innymi słowy, w sprawach wdrażania reguł 
logiki aplikacji zajmuję stanowisko „grubego serwera”. A oto podstawy mojej 
filozofii: 

background image

 Rozdział 20 Reguły logiki aplikacji na serwerze bazy danych 

613

 

Gdy to tylko możliwe, reguły logiki aplikacji należy umieszczać na serwerze 
i w miarę konieczności uzupełniać w 

oprogramowaniu pośredniczącym 

(middleware) i w aplikacjach klienckich, w tej właśnie kolejności. 

Oczywisty wniosek z tej zasady jest bardzo podobny: 

Reguła logiki aplikacji zrealizowana po stronie klienta, która może być 
przeniesiona do oprogramowania pośredniczącego lub serwera bazy danych, 
powinna tam zostać „niezwłocznie” przeniesiona. Podobnie też każda reguła 
logiki aplikacji osadzona w oprogramowaniu pośredniczącym, która może być 
przeniesiona do serwera, powinna się tam znaleźć. 

Sądzę, że przesłanki dla takiej filozofii staną się bardziej oczywiste, gdy omówimy 
wszelkie „za” i „przeciw” dla wszystkie trzech wymienionych modeli. 

Silne strony implementacji serwerowej 

Jedną z korzyści z umieszczenia reguł logiki aplikacji na serwerze bazy danych 
jest to, iż wówczas przed niepowołanym dostępem i przypadkowym uszkodzeniem 
chronione są bezpośrednio same dane. Ponieważ tego rodzaju mechanizmy 
kontrolne są wewnętrznie powiązane z 

danymi, to bazujące na serwerze 

ograniczenia gwarantują,  że dane przechowywane w 

bazie danych będą 

zabezpieczone przed nieuprawnionym skasowaniem i zawsze zawierać  będą 
poprawne wartości. 

Inna korzyść z implementowania reguł logiki aplikacji na serwerze polega na tym, 
że wszystkie aplikacje klienckie, komunikujące się z bazą danych, uzyskują 
automatyczny dostęp do reguł. Jednym z wielkich problemów, jakie stwarza 
podejście polegające na lokowaniu reguł logiki aplikacji w oprogramowaniu 
klienta jest to, że narzędzia programistyczne do tworzenia klientów są często 
zależne od platformy i systemu operacyjnego. Przeciwnie z implementacjami 
bazującymi na serwerze - wszyscy najważniejsi producenci systemów zarządzania 
bazami danych (DBMS) typu klient/serwer dostarczają sposobów łączenia się 
z klientami bazującymi na różnych systemach operacyjnych i różnych platformach 
sprzętowych. Jakie by nie było środowisko systemu operacyjnego klienta, ma on 
zarówno dostęp do informacji o regułach logiki aplikacji na serwerze bazy danych, 
jak i musi się im podporządkować..  

Inną zaletą implementowania reguł logiki aplikacji na serwerze jest prędkość. 
Ponieważ na ogół instytucje traktują serwer bazy danych jako inwestycję 
w infrastrukturę, to stosunkowo łatwo przychodzi im znalezienie pieniędzy na 
kupno oprogramowania i sprzętu niezbędnego do tego, by serwer działał jak 
należy. Jeśli umieszczenie reguł logiki aplikacji na serwerze pogorszyłoby 
wyraźnie jego efektywność, to korporacja będzie z reguły bardziej skłonna zakupić 
dodatkowe zasoby konieczne do skompensowania spadku niż umieścić na każdym 

background image

614 

Część IV 

biurku maszyny o dużej mocy, nawet jeśli koszt pierwszego rozwiązania 
przekracza koszt drugiego

Innym czynnikiem do uwzględnienia jest to, że serwery baz danych są z samej 
swej konstrukcji skalowalne. Jeśli zatem nasze potrzeby przekraczają maksymalne 
możliwości danej platformy sprzętowej, to serwer i jego bazę danych możemy 
przenieść na silniejszą platformę sprzętową bez konieczności dokupowania DBMS 
innego producenta lub przeprojektowywania naszej bazy danych. Ten sam rodzaj 
skalowalności powinien występować w 

oprogramowaniu pośredniczącym 

i w rozwiązaniach bazujących na klientach, jeśli mają one stanowić porównywalną 
alternatywę. Na razie jednak tak nie jest - gdy na przykład mamy oprogramowanie 
klientów pracujące w systemie Windows, to nie oderwiemy się już od platformy 
Intela. Wprawdzie Windows NT jest również dostępny na niewielkiej liczbie 
innych platform, lecz nie jest on tak przenośny jak Sybase SQL Server, dostępny 
dla prawie każdej liczącej się platformy sprzętowej i systemu operacyjnego. 

Słabe strony implementacji serwerowej 

Jedna ze słabości rozwiązań bazujących na serwerze wynika stąd,  że wydajność 
serwera bazy danych jest odwrotnie proporcjonalna do wielkości jego obciążenia. 
W miarę jak do obiektów bazy danych dodawane są ograniczenia, dostęp do nich 
(a szczególnie modyfikacje) musi stawać się coraz wolniejszy. Zjawisko to może 
nabrać takiej ostrości, że serwer stanie się w praktyce bezużyteczny. 

Odpowiedzią nie jest jednak pospieszne przerzucenie się na reguły logiki aplikacji 
bazujące na klientach lub oprogramowaniu pośredniczącym. Tkwi ona raczej 
w takim  podejściu, jakie zwykle przyjmujemy, gdy nagły wzrost ilości danych 
spowalnia serwer w 

stopniu nie do przyjęcia - czyli w 

zainwestowaniu 

w dodatkowe  zasoby  sprzętowe i 

programowe niezbędne do przywrócenia 

serwerowi odpowiedniej mocy. Przecież w przypadku nagłego wzrostu woluminu 
danych rezygnacja z serwera na rzecz rozwiązań bazujących na klientach nie jest 
na ogół brana pod uwagę. To samo winno dotyczyć implementacji reguł logiki 
aplikacji - ich implementacje na serwerach należy traktować jako integralną część 
bazy danych i 

podstawowy składnik serwera. Przy takim nastawieniu 

przeforsowanie inwestycji niezbędnych do obsługi bazujących na serwerze 
implementacji reguł logiki aplikacji stanie się o wiele łatwiejsze. 

Inną  słabą stroną, często wytykaną przez oponentów umieszczania reguł logiki 
aplikacji na serwerach, jest skłonność tych implementacji do bazodanowej lub 
serwerowej „egocentryczności”. Oznacza to, że przenoszenie reguł logiki aplikacji 
pomiędzy bazami danych lub z serwera na serwer jest trudne lub wręcz 
niemożliwe. Tabela w jednej bazie danych nie mogłaby przypuszczalnie odwołać 
się do tabeli w innej bazie danych w celu sprawdzenia poprawności wprowadzanej 
do kolumny pozycji, ani też tabela na jednym serwerze nie mogłaby uzyskać 

background image

 Rozdział 20 Reguły logiki aplikacji na serwerze bazy danych 

615

 

wartości domyślnej z tabeli na innym serwerze. Ponieważ instytucje wykazują 
skłonność do organizowania serwerów zgodnie ze strukturą swych działów, to 
niewątpliwie stanowi to pewien problem. 

Odpowiedzią na te zastrzeżenia jest (jednak!) skłonienie producentów DBMS do 
poprawienia współpracy ich produktów z różnymi bazami danych i serwerami. Na 
przykład Sybase już teraz obsługuje heterogeniczne zapytania do baz danych 
(cross-database queries), tak jak zresztą robił to od lat. Co więcej, technologia 
taka jak serwer replikacyjny w Sybase rozwiązuje problem wieloplatformowości, 
pozwalając na automatyczne replikowanie kluczowych tabel z jednego serwera na 
drugi. Natomiast technologia bram (gateway) serwerowych umożliwia zapytania 
heterogeniczne. Pozwala ona na wykonywanie zapytań do tabel umieszczonych 
w systemach DBMS różnych producentów tak, jakby wszystkie one były na 
jednym serwerze. Odpowiedzią na zależność od bazy danych i od serwera nie jest 
pospieszne przejście na jeszcze jedną niedojrzałą technologie, lecz wywieranie 
nacisku na istniejących producentów po to, by swe narzędzia do obsługi 
wielobazowości i 

wieloplatformowości ulepszyli przynajmniej do stopnia 

elementarnej użyteczności. 

Innym problemem związanym z bazującymi na serwerach implementacjami reguł 
logiki aplikacji jest występujący często brak integracji między oprogramowaniem 
klienta a serwerem. Jednym ze skutków tej sytuacji bywa niekiedy niewłaściwe 
obsługiwanie przez klienta komunikatów serwera związanych z regułami logiki 
aplikacji, lub nawet całkowite ich ignorowanie. 

Także i w tym przypadku odejście od implementacji serwerowych nie jest żadnym 
rozwiązaniem. Wprost przeciwnie, rozwiązaniem jest właśnie wywarcie presji na 
producentów narzędzi do tworzenia oprogramowania klienckiego (takich jak 
Borland), by skłonić ich do dokonania pełnej integracji ze wspieranymi 
systemami. Czyli - jeśli Delphi zapewnia obsługę określonego DBMS typu 
klient/serwer - to obsługa ta powinna być pełna i musi obejmować wszystkie 
związane z klientami mechanizmy, jakich platforma ta dostarcza, z wykrywaniem 
naruszenia reguł logiki aplikacji włącznie. 

Silne strony implementacji klienckiej 

Jedną z silniejszych stron implementowania reguł logiki aplikacji na kliencie są 
możliwości indywidualnego dostosowywania i spory zakres kontroli, dostępnej 
w dziedzinie sygnalizowania i reagowania na reguły logiki aplikacji. Zupełnie 
proste jest sterowanie przechodzeniem przez kolejne pola. Na przykład 
uniemożliwienie użytkownikowi opuszczenia formularza, zanim wszystkie wpisy 
nie będą poprawne, jest tu zwykle zagadnieniem banalnym. 

background image

616 

Część IV 

Inną zaletą implementowania reguł po stronie klienta jest elastyczność  języków 
programowania aplikacji, nieporównywalna z SQL. Na przykład Object Pascal jest 
językiem bez porównania bogatszym niż SQL; nawet BASIC jest lepszy.  

Ostatnią zaletą implementowania reguł logiki aplikacji na klientach jest możliwość 
umieszczania ich w komponentach, których można potem ponownie używać we 
wszystkich aplikacjach opracowanych z 

użyciem tego samego narzędzia. 

Dodawanie reguł logiki aplikacji do oprogramowania staje się wówczas równie 
proste, jak „rzucenie” komponentu na formularz. W rozdziale 21, „Reguły logiki 
aplikacji w aplikacjach Delphi”, opisano jak się to robi. 

Słabe strony implementacji klienckiej 

Podstawową niedogodnością związaną z umieszczeniem reguł logiki aplikacji 
wyłącznie w oprogramowaniu klienta jest konieczność „obsadzania” w roli 
klientów coraz to potężniejszych maszyn. W końcu komputery te zaczynają 
wymagać zasobów tej miary, że ledwie parę lat temu wystarczyłyby one dla 
dobrego serwera. W rezultacie na biurku ląduje najnowszy i najlepszy sprzęt, na 
jaki nas stać, ponieważ klient nieustannie skarży się na niedostateczną moc 
obliczeniową. Aplikacje klienckie, które obfitują w reguły logiki aplikacji, 
pochłaniają więcej pamięci i działają wolniej niż te, które mają ich mniej. Odnosi 
się to zwłaszcza do aplikacji, które dla obsłużenia swych bazujących na kliencie 
implementacji muszą zapuszczać bazujące na serwerze zapytania. Jeśli dla 
przykładu aplikacja kliencka musi zapytać swój serwer zapleczowy o typ danych 
w pewnej kolumnie po to, by do jej danych mogła zastosować odpowiednie 
ograniczenia, to niewątpliwie musi wykonać zbyt wiele pracy. Byłoby o wiele 
lepiej, gdyby zadanie to pozwolono wykonać serwerowi, który przecież 
z oczywistych powodów wie z góry, jak je wykonać. 

Gdy budujemy aplikacje, które niepotrzebnie wypytują serwer o informacje 
dotyczące ograniczeń, pojawia się problem „gadatliwej pielęgniarki”. Pielęgniarka 
usiłuje wykonać zabieg chirurgiczny, lecz ponieważ jako pielęgniarka nie ma 
wystarczających kwalifikacji, musi nieustannie zawracać  głowę swej szefowej, 
czyli chirurgowi. Ponieważ pani chirurg spędza swój cały czas pomagając 
pielęgniarce, nie ma czasu na praktykowanie chirurgii. A ponieważ pielęgniarka, 
choćby nie wiadomo jak dokładnie stosowała się do wskazówek chirurga, nie zrobi 
niczego innego, czego nie zrobiłby chirurg, to cała ta praktyka chirurgiczna traci 
wszelki sens. Jest to modelowy przypadek elementów, nie służących 
zamierzonemu celowi - nie robiących tego, co robią najlepiej. Mamy tu do 
czynienia z sytuacją, gdy w aplikacji klienta implementujemy reguły logiki 
aplikacji, których właściwym miejscem są serwery baz danych. 

Wraz z nieustannym rozbudowywaniem sprzętu klienta pojawiają się  kłopoty 
związane ze stale zmieniającymi się konfiguracjami sprzętowymi i programowymi. 

background image

 Rozdział 20 Reguły logiki aplikacji na serwerze bazy danych 

617

 

trakcie historycznego rozwoju komputerów owo nieustające dostrajanie 

i poprawianie  sprzętu zostało „wyrzucone” na serwery, lecz nie stało się tak 
w świecie „grubych klientów”. W ostatecznym efekcie otrzymamy więc serwer na 
każdym biurku, wymagający do obsługi dodatkowego personelu i wiedzy.  

Podejście to narusza również jeden z 

podstawowych dogmatów filozofii 

klient/serwer - dogmatu zmniejszonego zapotrzebowania na zasoby klienta. 
Naturalną konsekwencją  użycia DBMS typu klient/serwer jest - wedle 
powszechnego mniemania - to, że klient może być mniej wydajny, ponieważ cała 
rzeczywista praca związana z zarządzaniem bazą danych odbywa się na serwerze. 
Jeśli zatem niezbędne jest powiększenie zasobów, to będzie to miało miejsce 
przede wszystkim na serwerze, a nie na kliencie. Temu sposobowi myślenia 
zaprzecza zaś wprost model „grubego klienta”. 

Innym problemem związanym z wbudowywaniem reguł logiki aplikacji w klienta 
jest to, że implementacje takie rzadko kiedy są ze swej natury niezależne od 
narzędzia, o niezależności od producenta nie wspominając. Oznacza to, że trzeba 
będzie ponownie „wynajdywać koła”, jeśli na przykład musimy stworzyć jedną 
aplikację, która uaktualniać  będzie pewną tabelę w Delphi w ciągu jednego 
tygodnia, i drugą, która uaktualniać ją będzie w Developerze/2000 Oracla w ciągu 
następnego tygodnia. Ponieważ Developer/2000 nie będzie miał dostępu do reguł 
logiki aplikacji, które wbudowaliśmy w aplikację Delphi, to będziemy musieli 
zaimplementować je ponownie korzystając z narzędzi Developera. Sytuacja 
wygląda jeszcze gorzej, gdy uwzględnić należy możliwość pracy narzędziami 
wywodzącymi się z 

różnych platform. Prawdopodobnie będziemy w 

stanie 

hermetyzować reguły logiki aplikacji danego programu w zestawie komponentów 
Delphi i następnie zestawu tego użyć zarówno w aplikacjach Delphi, jak i Borland 
C++ Builder, i w ten sposób narzucić  te  same  reguły logiki aplikacji w różnych 
narzędziach. Lecz co stanie się, gdy te same reguły zechcemy wprowadzić do 
programu znakowego C działającego w systemie Unix? 

Wbudowanie reguł logiki aplikacji w oprogramowanie klienta zamiast do serwera 
zamyka także możliwość oglądania z jednego punktu „obserwacyjnego” całości 
reguł logiki aplikacji w bazie danych lub w banku danych. Ponieważ wszystkie te 
reguły zamknięte są w kodzie programu lub w obiektach, nie można w prosty 
sposób zobaczyć, jakie ograniczenia narzucono na jakie dane - czyli zupełnie 
inaczej niż w podejściu opartym na serwerze. W końcu dochodzimy do tego, że 
narzędzia CASE używamy jedynie w celu stwierdzenia, gdzie zaimplementowane 
są nasze reguły logiki aplikacji.  

Ostatnim argumentem, jaki można wysunąć na rzecz tezy o nieadekwatności 
rozwiązań bazujących na klientach jest to, że nawet jeśli dana aplikacja lub 
narzędzie izoluje bazę danych od niepoprawnych danych, to sama baza danych 
pozostaje nadal nie chroniona. Rodzi to nadmierne uzależnienie od konkretnych 
narzędzi do tworzenia oprogramowania klienckiego, które wcale nie tak łatwo 

background image

618 

Część IV 

osłabić. W efekcie cały dalszy rozwój oprogramowania klienckiego musi odbywać 
się z pomocą tego samego narzędzia - w razie użycia innego dotychczasowe reguły 
logiki aplikacji trzeba by albo w nim powielić, albo całkowicie zarzucić. Choć 
producenci narzędzi nie mieliby z pewnością  żadnego problemu z realizacją tej 
pierwszej możliwości, to na przeszkodzie stoją względy strategii rynkowej. 
Dlatego o wiele lepiej jest trzymać reguły logiki aplikacji na serwerze, gdzie mogą 
być wdrażane bez względu na rodzaj narzędzia użytego w aplikacji klienckiej, oraz 
przywoływane i współużytkowane przez wszystkie aplikacje, zgodnie z ich 
przeznaczeniem. 

Silne strony oprogramowania pośredniczącego 

Termin  middleware, czyli oprogramowanie pośredniczące, odnosi się do 
oprogramowania znajdującego się między klientem a serwerem. W szczególności 
middleware izoluje klientów od serwerów i serwery od klientów, zmuszając je do 
komunikowania się ze sobą poprzez warstwę pośredniczącą. Na middleware może 
składać się wszystko, co tylko da się umieścić między aplikacją klienta a serwerem 
bazy danych. Może to być API realizujące przyłączanie do bazy danych, takie jak 
BDE, lub może to być serwer aplikacji, taki jak serwer OLEnterprise, dołączony 
do Delphi 3 Client/Server. Middleware może przyjmować kilka postaci. W sensie 
czysto koncepcyjnym, podejście związane z middleware mogłoby być najlepszą 
z dostępnych możliwości. W idealnym świecie reguły logiki aplikacji byłyby 
zdefiniowane w obiektach systemu operacyjnego, które z kolei odwoływałyby się 
do obiektów serwera bazy danych. Niektóre systemy operacyjne - na przykład 
NeXTSTEP Steva Jobsa - posunęły się znacznie w tym kierunku. 

Podejście wykorzystujące oprogramowanie pośredniczące pozwala uniknąć 
doświadczanych aktualnie trudności z implementowaniem reguł logiki aplikacji na 
różnych serwerach i różnych bazach danych, ponieważ reguły te nie rezydują ani 
w danej bazie danych, ani na danym serwerze. 

Podejście to pozwala także uchronić się przed problemem „grubego” klienta 
i „grubego” serwera. W zasadzie ani serwer, ani klient nie będzie wtedy obarczony 
obsługą reguł logiki aplikacji. Nie trzeba będzie inwestować w potężne biurkowe 
PCety, zaś zasoby po stronie serwera zostaną zwolnione z 

obowiązku 

przestrzegania reguł logiki aplikacji. 

Ograniczenia i 

brokerzy danych w 

Delphi dostarczają metody budowania 

serwerów aplikacji, która jest zarazem efektywna i prosta w użyciu. Pozwala to 
konstruować wielowarstwowe aplikacje klient/serwer równie łatwo, jak budowało 
się w przeszłości aplikacje dwuwarstwowe. Więcej informacji na ten temat 
znajdziemy w rozdziale 22, „Poza granicami modelu dwuwarstwowego”.  

background image

 Rozdział 20 Reguły logiki aplikacji na serwerze bazy danych 

619

 

Słabe strony oprogramowania pośredniczącego 

Największy problem z modelem opartym na oprogramowaniu pośredniczącym 
polega na tym, że wymaga on zaprogramowania jeszcze jednej warstwy, 
niezależnie od nieuniknionego trudu programowania serwera i klienta. Poza tym - 
jako że nasze reguły logiki aplikacji nie będą już umieszczone w jednym miejscu - 
nie będziemy mogli oglądać ich w jednej całościowej perspektywie. Innymi słowy, 
ponieważ reguły te nie będą już znajdować się wyłącznie na serwerze lub 
wyłącznie na kliencie (gdyż  są rozproszone pomiędzy warstwami klienta, 
oprogramowania pośredniczącego i 

serwera), będą trudniejsze w 

obsłudze 

i administracji. Mamy zatem dwa problemy - podwójną pracę programistyczną, 
gdyż wiele z reguł zaimplementowanych w oprogramowaniu pośredniczącym 
trzeba będzie także zaimplementować na serwerze, i utrudnione zarządzanie 
regułami biznesowymi naszej aplikacji, gdyż w omawianej architekturze są one 
rozrzucone w kilku warstwach.  

Implementowanie reguł logiki aplikacji bazujących na 
serwerze 

Teraz, gdy już przedstawiłem swoje poglądy na temat właściwej strategii reguł 
logiki aplikacji, zastanówmy się, jak najlepiej je zaimplementować. Znalezienie 
najodpowiedniejszego miejsca dla reguł logiki aplikacji w 

dużej mierze 

determinuje sposób, w 

jaki zostaną zaimplementowane. Jeśli wybierzemy 

implementację na serwerze, to niewątpliwie będziemy musieli stworzyć obiekty 
bazy danych, realizujące naszą implementację. Poniższy podrozdział omawia tego 
rodzaju obiekty i ich rolę w implementacji reguł logiki aplikacji. 

Wprowadzenie 

Pierwszym krokiem, jaki należy wykonać opracowując schemat reguł logiki 
aplikacji, jest stworzenie modelu reguł przetwarzania, jakie nasza aplikacja ma 
obsługiwać. Ów etap modelowania będzie bez wątpienia wymagał rozmów 
i współpracy z użytkownikami. Prześledzenie wraz z użytkownikami wszystkich 
ujmowanych w aplikacji reguł przetwarzania pozwoli zawczasu określić niezbędne 
zależności między obiektami i wymagane ograniczenia dla bazy danych i aplikacji. 

Dwa ogólne typy reguł logiki aplikacji, jakich będziemy poszukiwać, to reguły 
zapewniające integralność domenową i 

reguły zapewniające integralność 

relacyjną.  Integralność domenowa dotyczy rodzaju danych, które dana kolumna 
może zawierać. Na przykład kolumna dat musi mieścić poprawne daty, a kolumna 
typu „forma zapłaty” musi być ograniczona do gotówki, czeku lub karty 

background image

620 

Część IV 

kredytowej. Reguły logiki aplikacji związane z integralnością domenową mogą 
być zaimplementowane z pomocą ograniczeń dla kolumn bazy danych. 

Ograniczenia związane z integralnością relacyjną zapewniają przestrzeganie 
zależności między tabelami. Na przykład, jeśli wiersz w tabeli FAKTURA 
odwołuje się do wiersza w tabeli KLIENT, to ograniczenie integralnościowo-
relacyjne (lub referencyjne) zapewnia, że wiersz w tabeli KLIENT nie zostanie 
skasowany tak długo, jak długo istnieć będzie jakiś odnoszący się do niego wiersz 
w tabeli FAKTURA. 

Na możliwie najwcześniejszym etapie prac należy wyczerpująco opracować 
wszystkie reguły i wszystkie strategie, jakie można zastosować do analizowanych 
danych. Najlepszym sposobem jest użycie prostych zdań napisanych w zwykłej 
polszczyźnie. A oto niektóre przykłady reguł logiki aplikacji w języku naturalnym: 

„Każdy numer faktury w tabeli FAKTURA musi być niepowtarzalny. 

„Każdy numer klienta w tabeli FAKTURA musi mieć odpowiadający mu wiersz 

w tabeli KLIENT. 

„Akceptowanymi kartami kredytowymi są VISA, MasterCard i American 

Express. 

„Dla każdego wiersza-pozycji faktury obliczana jest suma częściowa przez 

pomnożenie ceny pozycji przez zamówioną ilość. 

„Sumę ogólną faktury otrzymuje się przez dodanie wszystkich sum częściowych 

w wierszach pozycji, oraz dodanie 7 procent podatku od sprzedaży i 5 dolarów 
na koszty wysyłki i manipulacji. 

„Rekordu nagłówka faktury nie można skasować tak długo, jak długo istnieje 

jakiś odpowiadający mu rekord szczegółowy faktury. 

„Domyślną metodą wysyłki wyrobów jest Federal Express. 

Należy przyglądnąć się wszystkim kolumnom we wszystkich tabelach. Każda 
z kolumn  może zawierać tylko poprawne dane. Należy określić i zagwarantować 
zachowanie zależności między tabelami. Trzeba zawczasu zaprojektować każdą 
agregację i 

wszystkie źródła danych. Zleceniodawca powinien sprawdzić 

poprawność i kompletność listy reguł jeszcze zanim rozpoczniemy właściwą pracę. 
Później, gdy będziemy tworzyć ograniczenia przeznaczone do umieszczenia 
w projekcie bazy danych, może po kolei „odfajkowywać” każdą regułę logiki 
aplikacji na liście. Sumienność na tym etapie zaoszczędzi nam czasu (i kłopotów) 
później. 

Wiele narzędzi CASE oferuje istotne wsparcie w implementowaniu reguł logiki 
aplikacji. W popularnych narzędziach CASE klient/serwer występuje wszystko co 
trzeba, począwszy od możliwości wpisywania zdań w 

języku naturalnym, 

opisujących reguły logiki aplikacji, aż po definiowanie szablonów procedur 

background image

 Rozdział 20 Reguły logiki aplikacji na serwerze bazy danych 

621

 

zdarzeń w celu ich zaimplementowania. Jeśli musimy określić dużą ilość reguł 
logiki aplikacji w skomplikowanym modelu bazy danych, to dobre narzędzie 
CASE może zaoszczędzić wiele godzin pracy. 

Ograniczenia PRIMARY KEY 

Ograniczenia dla kolumn i 

tabel są najczęściej używanym sposobem 

implementowania bazujących na serwerze reguł logiki aplikacji. Choć prawdą jest, 
że procedury zdarzeń  (trigger) mogą zrobić wszystko to, co robią ograniczenia, 
a nawet jeszcze więcej, to moją filozofię w debacie „ograniczenia kontra 
wyzwalacze” ująłbym następująco: 

Ograniczenia mają zawsze pierwszeństwo nad procedurami zdarzeń. Należy 
zawsze starać się, by jak największa część implementacji naszych reguł logiki 
aplikacji wykonana została z 

użyciem ograniczeń. Resztę załatwić można 

z pomocą perspektyw (view), procedur zdarzeń lub procedur pamiętanych (stored 
procedure) - i 

to w 

tej właśnie kolejności. Perspektywy powinny mieć 

pierwszeństwo przed procedurami zdarzeń, zaś procedury zdarzeń przed 
procedurami pamiętanymi. 

Ograniczenia są lepsze od wyzwalaczy, ponieważ  są od nich szybsze. Przyczyną 
jest to, że ograniczenia są narzucane przez samo jądro serwera (zwykle kod C 
skompilowany dla danej platformy). Natomiast procedury zdarzeń składają się 
z półskompilowanego SQL. Kod maszynowy jest prawie zawsze szybszy od kodu 
półskompilowanego. Z tego też powodu perspektywy są korzystniejsze od 
procedur zdarzeń. Składnia WITH CHECK OPTION w perspektywach ANSI SQL 
jest wdrażana przez sam serwer, a nie przez SQL. Mimo to procedury zdarzeń są 
bardziej zalecane od procedur pamiętanych, ponieważ realizowane są 
automatycznie. Wbudowywanie reguł logiki aplikacji w procedury pamiętane 
pozostawia zawsze to niebezpieczeństwo, że jakiś proces może pominąć procedurę 
i zmodyfikować obsługiwaną przez nią tabelę, obchodząc w 

ten sposób 

obowiązujące w teorii reguły logiki aplikacji. 

Pierwszym typem ograniczeń, jakie należy zastosować, są  klucze pierwotne
Określają one, które kolumny w tabeli jednoznacznie identyfikują każdy z wierszy. 
Klucz pierwotny jest domyślną metodą dostępu do tabeli. Przykładami kluczy 
pierwotnych są: pole InvoiceNumber w 

tabeli INVOICE lub pole 

CustomerNumber w tabeli CUSTOMER. Dodając klucz pierwotny nakazujemy 
serwerowi sprawdzanie, czy wartości wstawiane do kolumny lub kolumn klucza 
pierwotnego są unikalne w obrębie tabeli. Choć zwykle klucze pierwotne 
definiujemy przy tworzeniu tabeli, to może się niekiedy zdarzyć, że zrobimy to już 
po fakcie. Składnia SQL służąca do dodawania kluczy pierwotnych do istniejącej 
tabeli wygląda następująco: 

ALTER TABLE CUSTOMER ADD PRIMARY KEY (CustomerNumber) 

background image

622 

Część IV 

Ograniczenia FOREIGN KEY  

Ograniczenia w formie kluczy obcych są bardzo popularne przy definiowaniu 
relacji między tabelami. Wymagają one, by wartość umieszczana w kolumnie 
jednej tabeli istniała wcześniej w innej tabeli. W podobny sposób uniemożliwiają 
one usuniecie danej z drugiej tabeli, jeśli do danej tej odwołuje się pierwsza 
tabela. Ograniczeń w formie kluczy obcych używamy na przykład po to, by mieć 
gwarancję,  że wszystkie numery klientów wylistowane w polu CustomerNumber 
tabeli INVOICE istnieją w tabeli CUSTOMER. Odwołanie do obcego klucza 
tworzymy zwykle w trakcie konstruowania tabeli, lecz nie jest wcale wykluczone, 
że będziemy musieli zaczekać i zrobić to później. A oto składnia SQL służąca do 
dodawania klucza obcego post factum

ALTER TABLE ORDERS ADD FOREIGN KEY (CustomerNumber) REFERENCE  

 CUSTOMER 

Ograniczenie CHECK 

Innym typem ograniczenia jest ograniczenie kontrolne (check). Zapewnia ono, że 
wartość wstawiana do kolumny, występuje w pewnym zbiorze ustalonych 
wcześniej wartości. Przypuśćmy, że pewne przedsiębiorstwo sprzedaży detalicznej 
akceptuje tylko niektóre karty kredytowe, na przykład VISA, MasterCard 
i American  Express.  Ponieważ jest to stały zbiór wartości, jest on dobrym 
kandydatem na ograniczenie kontrolne. Możemy je zakodować jako ograniczenie 

CHECK

 używając następującej składni SQL: 

ALTER TABLE ORDERS ADD CONSTRAINT INVALID_CREDIT_CARD 
CHECK (CreditCardType in (‘V’, ‘M.’, ‘A’)) 

Ograniczenia kontrolne można również skonstruować w trakcie tworzenia tabeli. 
Oto przykład: 

CREATE TABLE NYSE_EVENTS 

EventNo 

INTEGER NOT NULL, 

Year 

INTEGER NOT NULL CHECK (YEAR >= 1799), 

Description 

VARCHAR(80) NOT NULL, 

Resolution 

VARCHAR(80) NOT NULL, 

PRIMARY KEY (EventNo) 
); 

Ograniczenia kontrolne można definiować na poziomie tabel lub, jak 
w poprzednim przykładzie, dla poszczególnych kolumn. 

background image

 Rozdział 20 Reguły logiki aplikacji na serwerze bazy danych 

623

 

Wartości domyślne 

Wartości domyślne dla pól mają istotne znaczenie, ponieważ określają wartość, 
jaką kolumna otrzyma w operacji 

INSERT

, jeśli wartość ta nie zostanie 

dostarczona jawnie. Podawanie wartości domyślnych pozwala zagwarantować, że 
dana kolumna wiersza otrzyma już w 

momencie utworzenia poprawnie 

wprowadzone dane. 

Wśród programistów występuje tendencja do określania wartość domyślnych 
kolumn z pomocą kodu programu. Można na przykład w łatwy sposób przypisać 
kolumnie taką wartość korzystając ze zdarzenia 

OnNewRecord

 w Delphi.  

Jednak jakby to nie było  łatwe, definiowanie wartości domyślnych dla kolumn 
w aplikacji jest niedobrą praktyką. Wymaga ona na przykład „przekopania” się 
przez kod programu w celu znalezienia wartości domyślnych dla kolumn tabeli. 
O wiele  lepszą metodą jest przechowywanie ich na serwerze, gdzie mogą być 
łatwo odczytywane i zmieniane. 

Choć niektórzy producenci dostarczają specyficznych dla platform sposobów 
ustalania wartości domyślnych dla kolumn, to osobiście wolę pozostać przy 
składni ANSI. Zaś składnia ANSI do ustalania wartość domyślnych dla kolumn 
jest następująca: 

ALTER TABLE ORDERS 
ADD CreditCardType char(1) 
DEFAULT ‘V’ 

Perspektywy 

Istnieją sytuacje, w których implementację konkretnej reguły logiki aplikacji 
najlepiej wykonać za pośrednictwem perspektywy SQL. Ujmując rzecz krótko, 
perspektywa jest wyrażeniem 

SELECT

  języka SQL, które można skompilować 

i „odpytywać” tak, jak gdyby była to najzwyklejsza tabela. Jest wiele różnych 
sposobów korzystania z perspektyw, zaś podstawowy sposób ich użycia przy 
implementowaniu reguł logiki aplikacji polega na wykonywaniu obliczeń na 
kolumnach tabeli. Mamy tu na przykład perspektywę do obliczania sum 
częściowych dla poszczególnych wierszy faktury: 

CREATE VIEW INVOICEDETAIL 
AS 
SELECT InvoiceNumber, LineNumber, PriceEach * UnitsOrdered  

 ExtendedTotal 

Perspektywa ta implementuje regułę logiki aplikacji brzmiącą: „dla każdej pozycji 
w wierszu faktury oblicza się sumę mnożąc cenę tej pozycji przez zamówioną 
ilość”.  

background image

624 

Część IV 

Procedury zdarzeń 

Gdy wszystko inne zawiedzie, musimy zwrócić się do procedury zdarzenia. Wiele 
platform oferuje specjalne rozszerzenia języka SQL, nadające procedurom zdarzeń 
i w ogólności procedurom różne nadzwyczajne możliwości. Na przykład Sybase 
dostarcza Transact-SQL, natomiast Oracle zawiera PL./SQL. Jeśli to tylko 
możliwe, należy zamiast procedur zdarzeń  używać więzów. Jeśli tego, czego 
potrzebujemy, nie możemy zrobić przy użyciu więzów, to wedle wszelkiego 
prawdopodobieństwa załatwi nam to procedura zdarzenia. Oto przykład procedury 
zdarzenia, która wykracza poza zwykle możliwości ograniczeń kolumnowych: 

CREATE TRIGGER ORDERSInsert FOR ORDERS BEFORE INSERT AS 
BEGIN 
 

IF (New.CreditCardType=’V’ AND New.Amount<50.00) THEN 

 EXCEPTION 

BELOW_MINIMUM_VISA; 

END 

Procedura ta zapewnia, że zamówienia zrealizowane przy pomocy karty 
kredytowej VISA wynosić  będą w sumie 50 $ lub więcej. Ze względu na 
warunkowy charakter tej reguły, byłoby trudne lub wręcz niemożliwe 
zaimplementować  ją jako proste więzy kolumny. Zatem użycie procedury 
zdarzenia w tej sytuacji jest jak najbardziej wskazane. 

Procedury pamiętane 

W pewnych kręgach „sequelowskich” daje się zauważyć dążność do nadużywania 
procedur pamiętanych przy implementowaniu reguł logiki aplikacji. Wyraża się 
przy tym pogląd, że procedur pamiętanych należy używać do wszystkich operacji 
DML (Data Manipulation Language), tworząc dla każdej tabeli oddzielne 
procedury 

INSERT

UPDATE

 i 

DELETE

. Dopiero procedura taka zapewnia, że 

przy każdej operacji przestrzegane są odpowiednie ograniczenia spójnościowe 
i reguły logiki aplikacji.  

Problem z takim podejściem polega jednak na tym, że uniemożliwia ono oglądanie 
zabezpieczeń i implementacji reguł logiki aplikacji w naszej bazie danych 
z jednego punktu „obserwacyjnego”. Redukuje także do zera użyteczność narzędzi 
takich jak Delphi, ponieważ ich zdolność do wiązania obiektów programu 

elementami bazy danych pozostaje wówczas w 

przeważającej mierze 

niewykorzystana. Wprawdzie z pamiętanych procedur DML można skorzystać za 
pośrednictwem komponentu Delphi 

TUpdateSQL

, to sposób ten w dużej mierze 

marnuje korzyść wynikającą ze stosowania narzędzi takich jak Delphi - 
umiejętność automatycznego podłączania się do danych, bez względu na ich 
strukturę. Musimy bowiem odwzorowywać struktury naszych tablic w związanych 
z nimi procedurach, czyli robić dokładnie to, czego próbowaliśmy uniknąć dzięki 
narzędziom RAD takim jak Delphi. 

background image

 Rozdział 20 Reguły logiki aplikacji na serwerze bazy danych 

625

 

Poza tym tworzenie dla każdej tabeli w bazie danych przynajmniej trzech procedur 
pamiętanych sprawia, że zarządzanie bazą staje się znacznie trudniejsze. W bazach 
danych z tysiącami tabel możemy dojść do wielu tysięcy procedur pamiętanych. 
Utrzymywanie ich jest dla DBA koszmarem i nieustannym źródłem zgryzoty. 
Przyrost wydajności, uzyskiwany z budowania procedur pamiętanych w taki 
„poszatkowany” sposób, jest przereklamowany i ma miejsce jedynie w pewnych, 
bardzo szczególnych okolicznościach, a przy tym jest zwykle minimalny lub nawet 

ogóle niedostrzegalny. Zwykle kłopoty związane z 

tworzeniem procedur 

pamiętanych w ogromnych ilościach są nieporównanie większe niż takie to 
problematyczne korzyści. 

Należy przy tym pamiętać, że pamiętane procedury, implementujące poprawność 
danych, muszą być debugowane i obsługiwane tak, jak każdy inny program. Jeśli 
w jakiejś tabeli pojawią się nieprawidłowe dane, to pierwszą rzeczą  będzie 
sprawdzenie, czy nie ma błędów w jej procedurach. W efekcie staniemy wobec 
konieczności obsługiwania, prócz właściwego kodu Delphi, także i obszernego 
zestawu skądinąd zbędnych procedur pamiętanych.  

Z tych to względów odradzałbym konstruowania niepotrzebnych procedur 
pamiętanych. Strońmy od tworzenia procedur przy byle okazji - używajmy ich 
tylko w sytuacjach, w których ani tradycyjne więzy, ani procedury zdarzeń nie 
mogą znaleźć zastosowania. 

Przykładem takiej sytuacji jest „niesławny” podprogram księgowania. Jeśli 
chcielibyśmy zakumulować wartości w 

kolumnie lub kolumnach w 

celu 

zaksięgowania ich w oddzielnej tabeli, to ponieważ chcielibyśmy dokładnie 
kontrolować moment, w którym takie zaksięgowanie nastąpi, zrobilibyśmy to 
najprawdopodobniej z pomocą procedury pamiętanej. 

Rozważmy przytoczony wcześniej przykład księgi głównej. Gdybyśmy musieli 
napisać procedurę pamiętaną, obsługującą księgowanie transakcji „do wypłaty” 
w księdze głównej, to moglibyśmy napisać coś takiego jak: 

CREATE PROCEDURE POSTAP (APACCOUNT) 
AS 
DECLARE VARIABLE APTOTAL FLOAT 
BEGIN 
SELECT SUM(AmountOfTransaction) TranAmount 
 INTO 

:APTOTAL 

 FROM 

APTRANS 

 

UPDATE GLBAL SET APMonthEndBalance=APMonthEndBalance+  

 

 :APTOTAL 

 WHERE 

AccountNumber=:APACCOUNT; 

END 

Procedura ta definiuje kolumnę 

APMonthEndBalance

 jako powstającą 

z kolumny 

AmountOfTransaction

 w tabeli APTRANS. Implementuje ona 

background image

626 

Część IV 

regułę logiki aplikacji definiującą, w jaki sposób każdego miesiąca uzyskiwany 
jest bilans strony „winien” w księdze głównej. 

Procedury pamiętane przydają się w sytuacjach podobnych do tej, ponieważ mogą 
one wykonać tyle instrukcji SELECT, ile jest niezbędnych do pełnego wykonania 
całej operacji, a także i dlatego, że to my decydujemy, kiedy będą wykonane. 
Szczególnie dobrze przystosowane są do operacji wsadowych, takich jak 
podprogramy księgowania i generowanie złożonych raportów.