plik


��IDZ DO IDZ DO PRZYK�ADOWY ROZDZIA� PRZYK�ADOWY ROZDZIA� Oracle PL/SQL. SPIS TRE CI SPIS TRE CI Wprowadzenie KATALOG KSI��EK KATALOG KSI��EK Oracle PL/SQL. Wprowadzenie KATALOG ONLINE KATALOG ONLINE Autorzy: Bill Pribyl, Steven Feuerstein T�umaczenie: Bart�omiej Garbacz ISBN: 83-7197-727-1 ZAM�W DRUKOWANY KATALOG ZAM�W DRUKOWANY KATALOG Tytu� orygina�u: Learning Oracle PL/SQL Format: B5, stron: 412 TW�J KOSZYK Przyk�ady na ftp: 118 kB TW�J KOSZYK PL-SQL  j�zyk programowania systemu Oracle, przeznaczony do tworzenia procedur DODAJ DO KOSZYKA DODAJ DO KOSZYKA magazynowanych  zapewnia ogromne mo�liwo ci pisz�cym oprogramowanie baz danych. PL/SQL rozszerza standard j�zyka relacyjnych baz danych SQL poprzez umo�liwienie korzystania z takich konstrukcji, jak: p�tle, instrukcje IF-THEN, z�o�one CENNIK I INFORMACJE CENNIK I INFORMACJE struktury danych czy szerokie mo�liwo ci kontroli operacji transakcyjnych. Wszystkie z nich s� ci le zintegrowane z serwerem bazy danych Oracle. ZAM�W INFORMACJE ZAM�W INFORMACJE O NOWO CIACH O NOWO CIACH  Oracle PL/SQL. Wprowadzenie daje Czytelnikowi mo�liwo � pe�nego zrozumienia j�zyka PL/SQL bez wzgl�du na to, czy jest pocz�tkuj�cym, czy do wiadczonym ZAM�W CENNIK programist�. W niniejszej ksi��ce przedstawiono nast�puj�ce zagadnienia: ZAM�W CENNIK " cechy j�zyka PL/SQL i korzy ci wynikaj�cych z jego u�ywania; " sk�adnia i przyk�ady zastosowania wszystkich g��wnych konstrukcji j�zyka; CZYTELNIA CZYTELNIA " tworzenie i wykorzystywanie procedur, funkcji oraz pakiet�w magazynowanych; " tworzenie aplikacji opartych na sieci Internet; FRAGMENTY KSI��EK ONLINE FRAGMENTY KSI��EK ONLINE " zabezpieczanie program�w w j�zyku PL/SQL przed atakami z zewn�trz; " korzy ci wynikaj�ce z wykorzystania narz�dzi wspomagaj�cych programowanie, pochodz�cych od innych dostawc�w; " wykorzystanie j�zyka PL/SQL do programowania zada� zwi�zanych z u�yciem poczty elektronicznej, j�zyka Java oraz sieci Internet.  Oracle PL/SQL. Wprowadzenie zawiera szczeg��owy opis konstrukcji j�zyka we wszystkich wersjach od Oracle7 do Oracle9i, podparty przyk�adami program�w dost�pnych tak�e pod adresem http://oracle.oreilly.com. Autorami jej s� eksperci j�zyka PL/SQL Bill Pribyl oraz Steven Feuerstein. Ksi��ka daje solidne podstawy ka�demu programi cie baz danych i administratorowi, kt�ry zmuszony jest do poznania j�zyka PL/SQL. Wydawnictwo Helion ul. Chopina 6 44-100 Gliwice tel. (32)230-98-63 e-mail: helion@helion.pl RozdziaB 1. Podstawy j�zyka PL/SQL ........................................................................................................ 19 Zalety j�zyka PL/SQL ............................................................................................................. 27 Wymagania dotyczce stosowania j�zyka PL/SQL ................................................................ 33 RozdziaB 2. Podstawy skBadni ..................................................................................................................... 38 Pierwszy program w PL/SQL.................................................................................................. 40 Wprowadzenie do budowy programu...................................................................................... 44 Zmienne ................................................................................................................................... 48 Podstawowe operatory............................................................................................................. 56 Wyra|enia warunkowe ............................................................................................................ 63 Instrukcje wykonywania w p�tlach ......................................................................................... 67 Formatowanie kodu: wymagania i wskaz�wki ....................................................................... 73 Podstawy bardziej zBo|onych zagadnieD ................................................................................. 75 RozdziaB 3. Informacje o programie przykBadowym .................................................................................. 81 Pierwsze zadanie programistyczne.......................................................................................... 83 Pobieranie informacji o liczbie ksi|ek za pomoc funkcji .................................................... 97 Tworzenie elastycznego kodu................................................................................................ 102 Wykorzystanie pakiet�w PL/SQL w celu organizacji kodu.................................................. 108 Przej[cie na wy|szy poziom .................................................................................................. 117 Dalsza droga .......................................................................................................................... 122 RozdziaB 4. Wprowadzenie do HTML...................................................................................................... 124 Tworzenie stron internetowych za pomoc j�zyka PL/SQL ................................................. 134 Inne zagadnienia .................................................................................................................... 167 RozdziaB 5. Wprowadzenie ....................................................................................................................... 170 Prosta metoda: pobierania danych z jednego wiersza ........................................................... 170 Pobieranie wielu wierszy za pomoc kursora........................................................................ 172 Prezentowanie wynik�w zapytania na stronie WWW .......................................................... 184 Tworzenie strony WWW sBu|cej do wyszukiwania za pomoc mechanizmu dynamicznego SQL ..................................................................... 188 Zaawansowane zagadnienia zwizane z pobieraniem danych .............................................. 205 RozdziaB 6. Organizowanie kodu.............................................................................................................. 215 Narz�dzia pomagajce w efektywnym programowaniu........................................................ 228 RozdziaB 7. Podstawy bezpieczeDstwa w systemie Oracle....................................................................... 246 Organizowanie kont w celu zwi�kszenia poziomu zabezpieczeD ......................................... 255 Analiza wymagaD systemu bibliotecznego............................................................................ 267 Zledzenie zmian w bazie danych ........................................................................................... 273 Szczeg�lne kwestie bezpieczeDstwa zwizane z programowaniem w PL/SQL ................... 281 RozdziaB 8. WysyBanie wiadomo[ci poczt elektroniczn za pomoc PL/SQL ....................................... 288 Wykorzystanie narz�dzia sBu|cego do wysyBania wiadomo[ci elektronicznych w systemie bibliotecznym ................................................................................................... 293 Odbieranie wiadomo[ci z poziomu bazy danych .................................................................. 296 Pobieranie danych ze zdalnych stron internetowych............................................................. 305 Integracja z innymi j�zykami programowania ...................................................................... 317 RozdziaB 9. Cykle istnienia oprogramowania ........................................................................................... 324 Listy obiekt�w (kolekcje) w j�zyku PL/SQL ........................................................................ 326 Pakiety obsBugi wyjtk�w...................................................................................................... 339 Kontrola transakcji................................................................................................................. 343 Kompilator PL/SQL............................................................................................................... 349 Zarzdzanie uprawnieniami czytelnik�w i bibliotekarzy...................................................... 352 Inne cechy PL/SQL................................................................................................................ 372 Programowanie a bazy danych .............................................................................................. 381 Fakty ...................................................................................................................................... 381 W niniejszym rozdziale om�wiono nastpujce zagadnienia: " Informacje o programie przykBadowym " Pierwsze zadanie programistyczne " Pobieranie informacji o liczbie ksi|ek za pomoc funkcji " Tworzenie elastycznego kodu " Wykorzystanie pakiet�w PL/SQL w celu organizacji kodu " Przej[cie na wy|szy poziom " Dalsza droga Po zapoznaniu si� z podstawami j�zyka PL/SQL Czytelnik jest przygotowany do tworzenia pro- gram�w bardziej rozbudowanych ni| zwykBe wy[wietlanie komunikatu. W niniejszym rozdziale przedstawiono spos�b rozpocz�cia tworzenia aplikacji obsBugi katalogu biblioteki. W kolejnych cz�- [ciach ksi|ki opisano spos�b jej dalszej rozbudowy. Nowymi elementami j�zyka PL/SQL, kt�re przedstawiono w niniejszym rozdziale, s procedury (procedures), funkcje (functions) oraz pakiety (packages). Czytelnik dowie si�, do czego te elementy sBu|, jak je konstruowa oraz w jaki spo- s�b u|ywa w celu osigni�cia wymaganych cel�w. PrzykBadowe zadanie programistyczne, opisane w niniejszej ksi|ce, polega na pr�bie utworzenia systemu, kt�ry sBu|yBby do katalogowania oraz wyszukiwania ksi|ek w bibliotece  jest to rodzaj elektronicznego katalogu. W przypadku tej hipotetycznej biblioteki zakBada si�, |e wszelkie dane operacyjne znajduj si� w bazie danych Oracle. Istnieje wi�cej ni| jeden spos�b gromadzenia danych  dotyczcych tytuB�w, autor�w itp.  w bazie danych. Jednym z nich jest r�czne wpisywanie danych przez bibliotekarza. W kolejnych rozdziaBach zostan opisane metody automatycznego Ba- dowania danych z odlegBych zr�deB oraz metody wyszukiwania przez u|ytkownika danych znajduj- cych si� w katalogu. Istnieje konieczno[ speBnienia dw�ch wymagaD o podstawowym znaczeniu dla dziaBania opisywa- nej aplikacji: " Nale|y umo|liwi tworzenie wpis�w do katalogu dla ka|dej nowej ksi|ki. " Nale|y udost�pni mo|liwo[ okre[lania liczby egzemplarzy danej ksi|ki, znajdujcych si� w zasobach biblioteki. W celu speBnienia pierwszego wymagania nale|y utworzy procedur� PL/SQL, sBu|c do wprowa- dzania danych do bazy danych. Program umo|liwiajcy speBnienie drugiego warunku wymaga za- stosowania funkcji PL/SQL. Przed opisaniem sposobu tworzenia tych element�w nale|y najpierw przedstawi metody projektowania struktury samej bazy danych. Podobnie jak w przypadku wi�kszo[ci projekt�w tworzonych przez programist�w PL/SQL, struktura bazy danych dotyczcych ksi|ek w bibliotece zostaBa wcze[niej zaprojektowana i utworzona na podstawie wymagaD postawionych przez przyszBego u|ytkownika. Podzbi�r logicznego projektu bazy danych, zwizany ze wspomnianymi wcze[niej wymaganiami, mo|na ograniczy do infor- macji o ka|dym egzemplarzu ksi|ki w bibliotece. Rysunek 3.1 przedstawia tak zwany diagram zwizk�w encji (entity-relationship diagram, ERD). Rysunek 3.1. Zale|no[ midzy wpisem (informacj) dotyczcym ksi|ki a jej fizycznie istniejcymi egzemplarzami Diagramy takie w zwi�zBej i uproszczonej formie prezentuj informacje o realnym [wiecie. Opisane w odpowiedni spos�b prostokty s encjami (entities) bazy danych, a linie pomi�dzy nimi ozna- czaj zwizki (relationships) pomi�dzy encjami. Relacyjne bazy danych przedstawiaj rzeczywi- sto[ w formie zbioru struktur danych (kt�re przechowuj informacje o pewnych obiektach) oraz zbio- ru metod (kt�re definiuj powizania mi�dzy obiektami). Encja book reprezentuje podstawowe informacje o ksi|ce (tytuB, autor itd.), kt�re zawiera ka|da biblioteka. Encja book_copy zawiera informacje o fizycznie istniejcych egzemplarzach danej ksi|ki. Pewne zdziwienie mo|e wywoBa fakt, |e caBo[ rozdzielono na dwie encje zamiast u|ycia jednej. Wy- korzystanie tylko jednej encji spowodowaBaby jednak problemy w p�zniejszym czasie, poniewa| wy- stpiBaby konieczno[ kopiowania informacji dotyczcych ksi|ki razem z informacjami dotyczcymi jej pojedynczych egzemplarzy, co z pewno[ci byBoby niewBa[ciwym sposobem wykorzystania zaso- b�w komputera i wysiBku ludzkiego. PeBna dyskusja na temat normalizacji (normalization) baz danych (procesu organizowania danych w postaci tabel zgodnie z ich wewn�trzn struktur) wykracza poza zakres tre[ci niniejszej ksi|ki. Warto jednak podkre[li, |e gB�wna idea polega na przechowywaniu wa|nych informacji w jednym i tylko w jednym miejscu. Ka|dy kolejny egzemplarz danej ksi|ki wy- maga utworzenia jedynie dodatkowego rekordu zawierajcego identyfikator, kt�ry w powy|szym przy- padku jest numerem identyfikacyjnym pochodzcym z samoprzylepnej naklejki z kodem kreskowym. W tym miejscu nale|y wyja[ni znaczenie linii przedstawiajcych relacj�, pokazan na rysunku 3.1. Z tre[ci tego rysunku wynikaj nast�pujce fakty dotyczce realnej sytuacji: " Ka|dy egzemplarz danej ksi|ki jest egzemplarzem tyko jednej ksi|ki. " Ka|da ksi|ka mo|e posiada jeden lub wi�ksz liczb� swoich egzemplarzy. Relacja taka jest znana jako relacja jeden-do-wielu (one-to-many relationship): jedna pozycja ksi|- kowa i wiele egzemplarzy danej ksi|ki. Fakty powy|sze wydaj si� by truizmem. Jednak przed przystpieniem do wBa[ciwego projektowa- nia bazy danych nale|y dokona analizy rozwizywanego problemu na takim wBa[nie, podstawowym poziomie. RozBo|enie informacji dotyczcych projektowanej aplikacji na szereg pozornie banalnych fakt�w i ustalenie wszystkich podstawowych zwizk�w pomi�dzy jej elementami z pewno[ci uBatwi prac� podczas tworzenia kodu programu. Faktyczna struktura bazy danych odzwierciedla model zwizk�w encji  ka|da encja odpowiada ta- beli w bazie danych. Poni|ej przedstawiono kod w j�zyku SQL, sBu|cy do utworzenia takiej tabeli: CREATE TABLE books ( isbn VARCHAR2(13) NOT NULL PRIMARY KEY, title VARCHAR2(200), summary VARCHAR2(2000), author VARCHAR2(200), date_published DATE, page_count NUMBER ); CREATE TABLE book_copies( barcode_id VARCHAR2(100) NOT NULL PRIMARY KEY, isbn VARCHAR2(13) NOT NULL, CONSTRAINT book_copies_isbn_fk FOREIGN KEY (isbn) REFERENCES books (isbn) ); Z powod�w zrozumiaBych dla specjalist�w od modelowania danych, encjom nadaje si� nazwy w for- mie rzeczownik�w w liczbie pojedynczej (book, book_copy), natomiast tabelom  w liczbie mnogiej (books, book_copies). Ponadto warto wykona graficzn reprezentacj� tabeli  na rysunku 3.2 przedstawiono mo|liw posta zdefiniowanych tabel zapeBnionych pewnymi danymi. Zapoznawszy si� z danymi zawartymi w tabelach, Czytelnik z pewno[ci zwr�ciB uwag� na pewne problemy. PrzykBadowo, dane w kolumnie author s nieprawidBowe i nie jest mo|liwe poprawne przechowanie informacji o kilku autorach jednej ksi|ki. W dalszej cz�[ci niniejszej ksi|ki zosta- nie opisany spos�b poprawienia tych wad. Pierwszym, przykBadowym zadaniem b�dzie utworzenie programu w j�zyku PL/SQL, kt�ry posBu- |y do dodawania nowych ksi|ek do bazy danych. Oczywi[cie, zamiast takiego programu mo|na po prostu wykona instrukcj� INSERT (lub dwie takie instrukcje) j�zyka SQL: Rysunek 3.2. PrzykBad danych w postaci relacyjnej, rozbitych na wiersze i kolumny INSERT INTO books (isbn, title, author) VALUES ('0-596-00180-0', 'Oracle PL/SQL. Wprowadzenie', 'Bill Pribyl, Steven Feuerstein'); W zwizku z powy|szym Czytelnik z pewno[ci zastanawia si� nad sensem tworzenia programu w j�zyku PL/SQL. Nale|y zaBo|y, |e istnieje konieczno[ zapewnienia stosowania dw�ch sposob�w dodawania ksi- |ek do katalogu: po pierwsze w spos�b interaktywny, poprzez r�czne wpisanie danych, po drugie w spos�b automatyczny, pobierajc informacje o ksi|ce z innej bazy danych. Nasuwa si� zatem py- tanie, czy w takiej sytuacji nale|y skopiowa instrukcje INSERT do dw�ch program�w. Jednak|e p�zniej mo|e pojawi si� potrzeba napisania trzeciego programu, kt�ry dodawaBby informacje o ksi|- kach, przykBadowo, odczytujc je z pByty CD-ROM. A zatem nale|aBoby uwzgl�dni kolejne ko- piowanie instrukcji INSERT. ZakBadajc jednak, |e zaistnieje potrzeba zmiany struktury tabel, trzeba by w�wczas wszystkie dotd utworzone programy oddzielnie uaktualni. Istnieje kilka powod�w, dla kt�rych instrukcje INSERT warto umie[ci w programie PL/SQL. Poni- |ej wymieniono najwa|niejsze z nich: " Umo|liwia to ograniczenie, a nawet wyeliminowanie m�czcej pracy zwizanej z aktualizacj oprogramowania po zmianie struktury bazy danych, podczas wykonywania kt�rej istnieje mo|liwo[ popeBniania bB�d�w. " Pozwala to na zwi�kszenie wydajno[ci dziaBania serwera bazy danych. " Pozwala to umie[ci rozwizanie problemu programistycznego w tylko jednym miejscu. Tworzenie poprawnych instrukcji w j�zyku SQL mo|e wymaga interpretowania oraz zapisywa- nia w formie kodu wielu skomplikowanych reguB zarzdzania. Ewentualna konieczno[ dokonania zmian we wszystkich napisanych programach oddzielnie oznacza bezzasadne marnotrawstwo cza- su i wysiBku. Og�lna zasada m�wi, |e: Instrukcje SQL nale|y umieszcza w jednym, mo|liwym do wielokrotnego wykorzystania, programie napisanym w jzyku PL/SQL, a nie kopiowa je w wielu aplikacjach. Nawet je[li Czytelnik jest jedynym programist w swoim miejscu pracy, powinien trzyma si� tej zasady. Nie ogranicza si� ona zreszt tylko do wykorzystania j�zyka SQL  wszelkie zadania programistyczne powinno si� zapisywa tylko raz, a potem w razie konieczno[ci jedynie wykonywa odpowiedni program. Przez definiowanie czynno[ci wykonywanych przez ka|d jednostk� progra- mu, kt�r mo|na wielokrotnie wywoBywa, mo|na utworzy wBasny interfejs tworzenia oprogramo- wania (application programming interface, API). Tak prosty, jak to mo|liwe, ale nie prostszy Prawdziwy bibliotekarz uznaBby niniejszy model za banalnie prosty, nawet nie biorc pod uwag nie uwzgldnionych w nim kwestii zwizanych z czytelnikami, operacjami wypo|yczenia/ oddawania i kupowania ksi|ek. W rzeczywisto[ci funkcjonowanie biblioteki jest znacznie bar- dziej skomplikowane: " Poza przechowywaniem ksi|ek biblioteki magazynuj tak|e gazety i czasopisma, nagrania muzyczne i kasety wideo. " Wiele dzieB, na przykBad starsze ksi|ki, nie posiada numeru ISBN (International Standard Book Number), co ogranicza jego zastosowanie jako jednoznacznego identyfikatora. " DzieBa mog mie r�|ne tytuBy i wielu autor�w. " Nale|y przechowywa o wiele wicej informacji: o dziaBach, wydawcach, ilustratorach, wydaniach, dzieBach wielotomowych i pochodnych. " Biblioteki zazwyczaj udostpniaj sobie nawzajem swoje katalogi drog elektronicznej wymiany. Podobnych przykBad�w jest wicej, dlatego nale|y wyja[ni powody uwzgldnienia w niniejszej ksi|ce tak prostego przykBadu. Wykonanie bazy danych, kt�rej schemat pokazano na rysunku 3.1, w zasadzie jest zbyt skom- plikowanym zadaniem dla zupeBnie pocztkujcych programist�w. Relacja jeden do wielu stanowi podstaw wikszo[ci aspekt�w projektowania baz danych (tyle |e w realnych sytuacjach chodzi o wiele takich relacji) oraz programowania w jzyku PL/SQL. W dalszej cz[ci niniejszej ksi|ki zostanie opisany spos�b rozszerzania funkcjonalno[ci projektowanej bazy danych, a tak|e spo- soby wykorzystania PL/SQL w bardziej  realnych zadaniach. Innym powodem wprowadzenia pewnych uproszczeD jest fakt, |e nauka nowego materiaBu przychodzi najBatwiej, je[li mo|na studiowa jedno zagadnienie w jednym czasie. W przeciwnym razie nauka przychodzi du|o trudniej. W niniejszym rozdziale przedstawiono informacje o sposobach lokalizowania kodu SQL (stosowanie kodu w jednym miejscu) za pomoc obwolut tabel (table wrappers), kt�re s programami odpo- wiedzialnymi za wszelkie operacje zmiany zawarto[ci ka|dej z tabel bazy danych. Zapewne wi�kszo[ programist�w, niezale|nie od stopnia zaawansowania, odczuwa niepewno[ w sytuacji, gdy ma napisa program od podstaw. Z reguBy w takiej sytuacji mo|na rozpocz prac� od przerabiania ju| istniejcych lub przykBadowych program�w. W tym przypadku zostanie przed- stawiony spos�b tworzenia programu od samego pocztku, ale prawdopodobnie Czytelnik rzadko b�dzie do tego zmuszony. Godnym polecenia zwyczajem jest rozpocz�cie tworzenia programu od narysowania schematu. Ry- sunek 3.3 przedstawia mo|liw reprezentacj� graficzn omawianego programu oraz jego danych wej- [ciowych i wyj[ciowych. Rysunek 3.3. Schemat programu sBu|cego do dodawania ksi|ek do bazy danych W przeciwieDstwie do wcze[niej prezentowanego diagramu zwizk�w i encji, powy|szy diagram nie zostaB skonstruowany zgodnie z jakimi[ zasadami projektowania. Najwa|niejsz rzecz jest przedstawienie najbardziej znaczcych element�w. Z powy|szego rysunku wynika, |e trzeba skon- struowa program zdolny do pobierania pewnych informacji, a nast�pnie do umieszczania ich w ta- belach bazy danych. Cho zapewne nie jest to oczywiste, uwzgl�dniono mo|liwo[ poszerzenia funk- cjonalno[ci aplikacji w przyszBo[ci. Og�lnie rzecz biorc, jednostka programu powinna sBu|y do wykonania jednego, konkretnego zadania i nale|y zapewni prawidBowe dziaBanie tej jednostki w swoim zakresie. Wskazane jest, aby miaBa on niewielki rozmiar  uBatwi to jej zapis i p�zniejsze modyfikacje. Trzeba jeszcze znalez odpowiedz na pytanie, jakiej konstrukcji j�zyka PL/SQL nale|aBoby u|y w celu zdefiniowania operacji dodawania ksi|ki add_book. Z uwagi na fakt, |e program nie b�- dzie zwracaB |adnej warto[ci, najbardziej rozsdnym rozwizaniem jest zastosowanie procedury. W tym podrozdziale zostanie przedstawiony spos�b napisania procedury, kt�ra ma wstawia infor- macje na temat danej ksi|ki do bazy danych. Procedura taka mo|e by nazwana obwolut. Mo|na te| powiedzie, u|ywajc terminologii pochodzcej z j�zyka greckiego, |e b�d wykorzystywane abstrakcje (abstraction), procesy enkapsulacji (encapsulation) oraz ukrywania informacji (informa- tion hiding)  definicje wymienionych poj� znajduj si� w SBowniczku. Na rysunku 3.4 przedsta- wiono wi�cej szczeg�B�w dotyczcych takiego rozwizania. Rysunek 3.4. Jedynie z poziomu programu PL/SQL bdzie mo|liwe dodawanie informacji o ksi|ce do bazy danych U|ytkownicy gotowego programu nie musz wiedzie na jego temat zbyt wiele, jednak tw�rca danej aplikacji musi z pewno[ci posiada gruntown wiedz� dotyczc struktury bazy danych. Dlatego te| pierwsz rzecz, jak nale|y wykona, jest okre[lenie tabel i ich kolumn zwizanych z procesem wykonania reguBy zarzdzania (w tym przypadku  dodania ksi|ki). Trzeba odpowiedzie sobie na pytanie, jakie informacje s potrzebne do manipulowania zawarto[ci tych tabel. W celu okre[lenia istotnych dla wykonania planowanej operacji tabel i kolumn trzeba przyjrze si� projektowi bazy danych (przedstawionemu we wcze[niejszej cz�[ci niniejszego rozdziaBu). List� tych kolumn mo|na z Batwo[ci utworzy za pomoc instrukcji DESCRIBE, dost�pnej w SQL*Plus (w for- mie skr�conej DESC): SQL> DESC ksiazki Name Null? Type -------------------------------------------- -------- ----------------------- ISBN NOT NULL VARCHAR2(13) TITLE VARCHAR2(200) SUMMARY VARCHAR2(2000) AUTHOR VARCHAR2(200) DATE_PUBLISHED DATE PAGE_COUNT NUMBER SQL> DESC egzemplarze_ksiazki Name Null? Type -------------------------------------------- -------- ----------------------- BARCODE_ID NOT NULL VARCHAR2(100) ISBN VARCHAR2(13) Po przeanalizowaniu listy kolumn mo|na przyj, |e wi�kszo[ zawartych w nich informacji powin- na by znana osobie wykonujcej katalogowanie i dlatego nie trzeba niczego syntetyzowa, spraw- dza lub oblicza. Procedura b�dzie wi�c bardzo prosta. Podstawowym problemem do rozwizania jest podj�cie decyzji, czy u|ytkownik b�dzie wstawiaB dane do obydw�ch tabel jednocze[nie, czy te| oddzielnie. Na tym etapie pracy odpowiedz na to pytanie jest jeszcze nieznana. Najprawdopodobniej w bibliotekach odbywa si� to w ten spos�b, |e informacje o ksi|kach s dodawane do bazy danych w momencie pojawienia si� pierwszego eg- zemplarza. Dlatego te| podczas dodawania danej ksi|ki po raz pierwszy wszystkie informacje wymagane dla wypeBnienia obydw�ch tabel s od razu znane: od numeru ISBN po identyfikator kodu kreskowego. Jednak istnieje tak|e konieczno[ katalogowania nowych egzemplarzy ksi|ki ju| znajdujcej si� w zbiorach biblioteki  t� potrzeb� r�wnie| nale|y uwzgl�dni podczas pla- nowania programu. Rozpoczynajc opracowywanie nowego projektu wielu programist�w zapisuje tzw. pseudokod w postaci zwykBych zdaD, kt�re opisuj z grubsza dziaBanie programu. W tym przypadku mo|na by napisa: Sprawdz, czy dane wej[ciowe s prawidBowe. Wstaw nowy rekord do tabeli "books". Wstaw nowy rekord do tabeli "book_copies". Kolejnym etapem b�dzie przedstawienie skBadni konstrukcji j�zykowych potrzebnych do utworze- nia procedury. Nast�pnie zapisany pseudokod zostanie zamieniony na konkretne instrukcje. Poni|ej znajduje si� opis r�|nych cz�[ci skBadowych procedury. Zazwyczaj procedury tworzy si� za pomoc instrukcji o nast�pujcej skBadni: CREATE [ OR REPLACE ] PROCEDURE nazwa_procedury (parametr1 TRYB TYP_DANYCH [ DEFAULT wyra|enie ], parametr2 TRYB TYP_DANYCH [ DEFAULT wyra|enie ], ...) AS [ zmienna1 TYP_DANYCH; zmienna2 TYP_DANYCH; ... ] BEGIN instrukcje_wykonawcze [ EXCEPTION WHEN nazwa_wyjtku THEN instrukcje_wykonawcze ] END; / Powy|szy wzorzec zawiera kombinacj� sB�w kluczowych j�zyka PL/SQL (pisane du|ymi literami i nie kursyw) oraz wyra|eD do zastpienia (pisane kursyw) w kodzie tworzonego programu. CREATE [ OR REPLACE ] Jest to szczeg�lna instrukcja SQL, sBu|ca do utworzenia procedury. Fraza OR REPLACE (lub zastp) jest opcjonalna i pozwala na unikni�cie konieczno[ci usuwania ju| istniejcej procedury w przypadku tworzenia jej nowej wersji. Zastosowanie wyra|enia OR REPLACE zachowuje tak|e wszelkie synonimy (synonyms) oraz granty (grants), jakie zostaBy uprzednio utworzone, a s zale|ne od dziaBania procedury. Jest to du|a zaleta. PROCEDURE nazwa_procedury W sekcji nagB�wka podaje rodzaj tworzonej jednostki programowej (w tym wypadku  procedura) oraz nadaje si� jej nazw�. parametr1 TRYB TYP_DANYCH [ DEFAULT wyra|enie ] Aby umo|liwi u|ytkownikowi podawanie parametr�w wywoBania procedury, nale|y utworzy list� definicji parametr�w oddzielonych przecinkami, a caB list� obj w nawiasy. TRYB mo|e mie warto[: IN, OUT lub IN OUT. Poni|ej znajduje si� opis wszystkich opcji. IN SBowo kluczowe oznaczajce tryb tylko do odczytu. WywoBujcy procedur� podaje warto[ parametru, a PL/SQL nie pozwala na jej zmian� wewntrz programu. OUT SBowo kluczowe oznaczajce tryb tylko do zapisu. Oznacza to, |e procedura nadaje parametrowi pewn warto[, kt�ra jest odczytywana przez program wywoBujcy. Podanie jakiejkolwiek warto[ci takiego parametru podczas wywoBania procedury jest ignorowane. IN OUT SBowo kluczowe oznaczajce tryb do odczytu lub zapisu. SBowo to jest u|ywane w sytuacji, gdy warto[ zmiennej, przekazywanej do procedury jako parametr, ma by zar�wno odczytywana, jak i zmieniana, a nast�pnie zwracana do programu wywoBujcego. TYP_DANYCH Znaczenie tego parametru przedstawiono w rozdziale 2.  dopuszczalnymi warto[ciami s na przykBad: NUMBER, INTEGER, VARCHAR2, DATE. Jedyna r�|nica polega na tym, |e w tym miejscu nale|y poda jedynie rodzaj typu, bez jego dokBadnej specyfikacji. Innymi sBowy, nale|y u|y VARCHAR2 zamiast VARCHAR2(30) i NUMBER zamiast NUMBER(10,2). DEFAULT wyra|enie Pozwala na przypisanie parametrowi warto[ci domy[lnej w przypadku, gdy wywoBanie procedury jej nie okre[la. Mo|na tak|e u|y symbolu  := (dwukropek i znak r�wno[ci) zamiast sBowa kluczowego DEFAULT. AS SBowo kluczowe AS oddziela nagB�wek od reszty jednostki programowej. Opcjonalnie mo|na u|y sBowa kluczowego IS, kt�re jest r�wnowa|ne AS. BEGIN..END SBowa BEGIN i END oddzielaj zwykBe, czyli wykonawcze instrukcje od reszty programu. EXCEPTION Oznacza pocztek kodu obsBugi wyjtku  tej cz�[ci programu, kt�ra jest wykonywana tylko w przypadku przechwycenia wyjtku w sekcji wykonawczej. Wszystkie elementy umieszczone po sBowie kluczowym EXCEPTION i przed instrukcj END s cz�[ci obsBugi wyjtku. WHEN nazwa_wyjtku THEN instrukcje_wykonawcze Mo|liwym do wystpienia sytuacjom bB�dnego dziaBania programu zazwyczaj s nadawane nazwy  albo przez system Oracle, albo przez programist�. Dzi�ki temu mo|na w kodzie programu zapisa instrukcje  wychwytujce te sytuacje i umo|liwi odpowiedni na nie reakcj�, kt�r jest wykonanie pewnego fragmentu kodu. Je[li taka nazwa jest nieznana lub w celu wychwytywania bB�d�w, kt�re nie zostaBy nazwane, mo|na posBu|y si� sBowem OTHERS, kt�re dotyczy wszystkich sytuacji wyjtkowych. W zapisie wygldaBoby to nast�pujco: WHEN OTHERS THEN.... Pewne elementy kodu procedury s opcjonalne. Najprostsza, mo|liwa do utworzenia procedura po- siada nast�pujc form�: CREATE PROCEDURE nie_rob_nic AS BEGIN NULL; END; Z powy|szego wynika, |e parametry, zmienne i kod obsBugi wyjtk�w s opcjonalne. SBowo kluczowe NULL zostaBo tutaj zastosowane jako instrukcja wykonawcza. Oznacza ona tyle, co  nie r�b nic . Korzystajc z potrzebnych element�w podanego wcze[niej wzorca mo|na zapisa pseudokod w for- mie prawdziwego kodu: CREATE OR REPLACE PROCEDURE add_book (isbn_in IN VARCHAR2, barcode_id_in IN VARCHAR2, title_in IN VARCHAR2, author_in IN VARCHAR2, page_count_in IN NUMBER, summary_in IN VARCHAR2 DEFAULT NULL, date_published_in IN DATE DEFAULT NULL) AS BEGIN /* sprawdzenie poprawno[ci danych wej[ciowych */ IF isbn_in IS NULL THEN RAISE VALUE_ERROR; END IF; /* wstawienie rekordu do tabeli "books" */ INSERT INTO books (isbn, title, summary, author, date_published, page_count) VALUES (isbn_in, title_in, summary_in, author_in, date_published_in, page_count_in); /* je[li to konieczne, wstawienie rekordu do tabeli "book_copies" */ IF barcode_id_in IS NOT NULL THEN INSERT INTO book_copies (isbn, barcode_id) VALUES (isbn_in, barcode_id_in); END IF; END add_book; / Poni|ej znajduje si� opis dziaBania utworzonej procedury. Nazwa procedury i kolejno[ parametr�w. Nazw procedury jest wyra|enie czasownikowe, kt�re opisuje dziaBanie tej procedury. Podano tu tak|e parametry wej[ciowe  na ka|d z kolumn tabel, do kt�rych maj by wprowadzane dane, przypada jeden parametr. W celu wyeksponowania naj- wa|niejszych parametr�w (isbn_in czy barcode_id_in) oraz w celu umieszczenia parame- tr�w o warto[ciach domy[lnych na koDcu, zmieniono nieco ich kolejno[ w odniesieniu do kolej- no[ci kolumn w tabelach. Nazwy parametr�w. Warto przyj pewn konwencj� nazewnictwa w programowaniu i do nazw parametr�w doda si� nazw� ich trybu (IN, OUT lub IN OUT). Poniewa| wszystkie parametry procedury add_book s parametrami w trybie IN, ich nazwy zawieraj koDc�wk� _in. Taka konwencja nadawania nazw nie jest obowizkowa, ale jest pomocna w unikaniu konflikt�w z na- zwami kolumn podczas u|ywania instrukcji SQL. Gdyby pozostaBy one identyczne, otrzymana in- strukcja miaBaby nast�pujc posta: INSERT INTO book_copies (barcode_id, isbn) VALUES (barcode_id, isbn); W takim przypadku odr�|nianie nazwy kolumn od nazw zmiennych podczas odczytywania kodu mogBoby okaza si� problematyczne nawet dla do[wiadczonego programisty. Jednak|e sama in- strukcja zostaBaby wykonana prawidBowo, gdy| PL/SQL zinterpretowaBby wszystko nast�pujco: INSERT INTO book_copies (barcode_id, isbn) /* nazwy kolumn */ VALUES (barcode_id, isbn); /* zmienne PL/SQL */ Jednak|e instrukcja: UPDATE ksiazki SET summary = summary /* BBd! */ WHERE isbn = isbn; /* Nie wolno tak robi! */ nie zostanie wykonana prawidBowo. PL/SQL zinterpretuje ka|de wystpienie summary oraz isbn jako nazwy kolumn. Weryfikacja danych wej[ciowych. Zapis pierwszej linii zaprezentowanego wcze[niej pseudoko- du m�wiB:  Sprawdz, czy dane wej[ciowe s prawidBowe . Konieczne jest jednak podj�cie jeszcze kilku ustaleD. PrzykBadowo, mo|na zaBo|y, |e u|ytkownicy systemu b�d domaga si� minimalnych wymagaD ze strony procedury w momencie jej wywoBywania. Mo|e to oznacza, |e jedynym ab- solutnie wymaganym parametrem tworzonej procedury jest ISBN. Std te| sekcja weryfikacji da- nych wej[ciowych zostaBa zapisana jako: IF isbn_in IS NULL THEN RAISE VALUE_ERROR; END IF; Bez dokBadniejszej znajomo[ci powy|szych identyfikator�w nie jest mo|liwe przeprowadzenie bar- dziej wymy[lnej weryfikacji poprawno[ci danych wej[ciowych. Przedstawiony wy|ej fragment kodu oznacza, |e brak ISBN powoduje zatrzymanie wykonywania programu. W dalszej cz�[ci kodu jest tak|e wykonywane sprawdzenie kodu kreskowego. Program zostaB skon- struowany w ten spos�b, aby unikn wykonania niepoprawnej instrukcji INSERT, co spowodo- waBoby bBd. W rozdziale 2. wyja[niono, |e w razie wystpienia bB�du PL/SQL zatrzymuje wykonywanie progra- mu za pomoc mechanizmu zwanego przechwytywaniem wyjtku (raising an exception). Jak wy- nika z rysunku 3.5, instrukcja: RAISE VALUE_ERROR zatrzymuje wykonywanie instrukcji sekcji wykonawczej i przekazuje sterowanie do kodu obsBugi wyjtku. Je[li taki kod nie istnieje, wyjtek zwraca pewien bBd do programu wywoBujcego, a ten reaguje w okre[lony przez programist� spos�b. Rysunek 3.5. Prosty przykBad obsBugi wyjtku Wyjtek VALUE_EXCEPTION nale|y do grupy wyjtk�w wewn�trznych, kt�re w pewnych sytu- acjach s przechwytywane przez system Oracle. Program wywoBujcy procedur� add_book po- winien umo|liwia obsBug� wszelkich mo|liwych do przewidzenia wyjtk�w i na podstawie infor- macji dotyczcych napotkanego bB�du zdecydowa o dalszym funkcjonowaniu programu. W tym przypadku po|danym dziaBaniem byBoby przerwanie procesu dodawania do bazy danych niekom- pletnych informacji. Najlepiej byBoby, gdyby program wywoBujcy zwracaB u|ytkownikowi infor- macj� o bB�dzie. By mo|e Czytelnik zastanawia si� na celowo[ci podejmowania takich dziaBaD zamiast, przykBa- dowo, umo|liwienia samej procedurze add_book wy[wietlania komunikatu o napotkanym bB�- dzie. Celowo[ u|ycia mechanizmu wyjtk�w staje si� jasna po u[wiadomieniu sobie, |e przeka- zanie obsBugi sytuacji wyjtkowych do procedury ograniczyBoby w znacznym stopniu mo|liwo[ci jej ponownego wykorzystania. Je[li procedura add_book obsBuguje wyjtek i wy[wietla komunikat o bB�dzie, niemo|liwe jest wykorzystanie jej przez program, dla kt�rego dziaBania takie komuni- katy s niewskazane. PrzykBadowo, mo|na zaBo|y istnienie programu, kt�ry odczytuje informacje o ksi|kach z pliku i jednorazowo wprowadza do bazy danych informacje dotyczce tysi�cy ksi|ek. Program ten ma wywoBywa procedur� add_book dla ka|dej kolejnej pozycji i w razie wyst- pienia bB�du zapami�ta informacj� o jego przyczynie, nie przerywajc jednak swojego dziaBania, a| do zakoDczenia wprowadzania danych dotyczcych ostatniej ksi|ki. Dopiero w�wczas mo|na by przedstawi u|ytkownikowi podsumowanie informacji o napotkanych problemach. Wykorzysta- nie procedury add_book w taki spos�b jest mo|liwe jedynie poprzez propagacj� wyjtk�w na ze- wntrz  do programu wywoBujcego. Uog�lniajc, je[li istnieje prawdopodobieDstwo napotkania przez program bB�du, kt�rego nie da si� naprawi w prosty spos�b, nale|y zapewni mo|liwo[ przechwycenia wyjtku. W dalszej cz�[ci niniejszej ksi|ki opisano wyjtki, kt�re nale|y bra pod uwag�. Je|eli weryfikacja poprawno[ci danych wej[ciowych przebiega pomy[lnie, program kontynuuje swoje dziaBanie wykonujc instrukcje INSERT j�zyka SQL. Nie ma potrzeby zwracania jakichkolwiek danych do programu wywoBujcego. Jednak gdyby zaszBa taka konieczno[, mo|na uwzgl�dni jedn z dw�ch mo|liwo[ci: zastosowanie funkcji zamiast procedury lub wykorzystanie parametr�w w trybie OUT. Wi�cej informacji Czytelnik znajdzie w dalszej cz�[ci niniejszego rozdziaBu. NajBatwiejszym sposobem wywoBania procedury z poziomu kodu PL/SQL jest napisanie jej nazwy wraz z potrzebnymi argumentami, umieszczonymi w nawiasach i oddzielonymi przecinkami: BEGIN nazwa_procedury (argument1, argument2, ...); END; PrzykBadowo, aby doda do katalogu now ksi|k�, nale|y napisa: BEGIN add_book('1-56592-335-9', '100000001', 'Programowanie w Oracle PL/SQL', 'Feuerstein, Steven, Bill Pribyl', 987, 'Kompendium informacji o jzyku PL/SQL, ' || 'wraz z przykBadami i poradami na temat programowania.', TO_DATE('01-WRZ-1997','DD-MON-YYYY')); END; / Takie wywoBanie procedury spowoduje wstawienie po jednym rekordzie do tabel books oraz book_ copies. W powy|szym przykBadzie argumentami s tak zwane wyra|enia literalne, a PL/SQL przekazuje te warto[ci do programu jako parametry wej[ciowe1, zgodnie z ich kolejno[ci. Ozna- cza to, |e zazwyczaj warto[ci trzeba podawa w takiej samej kolejno[ci, w jakiej wyst�puj parame- try w programie wywoBywanym. Informacje te przedstawiono w poni|szej tabeli: 1 Wyra|enie przekazywane przez program wywoBujcy nosi nazw� argumentu lub parametru aktualnego, podczas gdy zmienne zdefiniowane w nagB�wku programu wywoBujcego s nazywane parametrami formalnymi lub po prostu parametrami. W tym kontek[cie  formalny oznacza  formujcy posta zmiennej. Pozycja Nazwa parametru Typ danych Warto[ u|yta w przykBadowym wywoBaniu parametru isbn_in '1-56592-335-9' 1 VARCHAR2 barcode_id_in '100000001' 2 VARCHAR2 title_in 'Programowanie w Oracle PL/SQL' 3 VARCHAR2 author_in 'Feuerstein, Steven, Bill Pribyl' 4 VARCHAR2 page_count_in 987 5 NUMBER summary_in 'Kompendium informacji o jzyku 6 VARCHAR2 PL/SQL wraz z przykBadami i poradami na temat programowania.' date_published_in TO_DATE('01-WRZ-1997','DD-MON-YYYY') 7 DATE Warto zwr�ci uwag�, |e podane warto[ci s zgodne z typami danych, jakich wymaga procedura. Oznacza to, |e ka|demu parametrowi typu VARCHAR2 odpowiada cig znakowy, parametrowi typu NUMBER odpowiada seria cyfr. Czytelnik zapewne zauwa|yB, |e parametrowi typu DATE odpo- wiada warto[ o do[ dziwnym wygldzie. Parametr date_published_in wymaga podania warto[ci typu DATE systemu Oracle. W rze- czywisto[ci jest to seria bit�w o skomplikowanym formacie wewn�trznym  z pewno[ci nie jest to zwykle u|ywana kombinacja roku, miesica i dnia. Cz�sto stosowan metod otrzymania takiej warto[ci jest wykorzystanie wewn�trznej funkcji systemu Oracle o nazwie TO_DATE. Podczas wywoBywania tej funkcji nale|y poda dat�, zapisan w formie cigu znakowego (w tym przypadku  '01-WRZ-1997'), oraz dodatkowy element, zwany mask formatu (format mask)  'DD- -MON-YYYY'. Funkcja TO_DATE pr�buje dopasowa do siebie poszczeg�lne elementy wyspecy- fikowanego cigu znak�w z odpowiednimi elementami maski formatujcej. W przypadku pomy[l- nego wykonania funkcja TO_DATE zwraca warto[ binarn, kt�r system Oracle rozpoznaje jako warto[ typu DATE. W przeciwnym przypadku nast�puje przechwycenie wyjtku. Wr�my do omawianego przykBadu: funkcja TO_DATE przekazuje wspomnian warto[ binarn jako argument do procedury add_book. Dla tej procedury spos�b utworzenia warto[ci typu DATE jest bez znaczenia  bezpo[rednie podawanie warto[ci literaB�w jest r�wnie dobrym roz- wizaniem, co uwzgl�dnienie wyniku dziaBania funkcji, takiej jak na przykBad TO_DATE. Zastosowanie funkcji TO_DATE nie zawsze jest konieczne, poniewa| system Oracle automatycznie podejmuje pr�b� konwersji cigu znakowego na dat�. W sytuacji takiej trzeba opiera si� na domy[lnej masce formatu systemu Oracle, kt�ra mo|e zosta zmieniona przez administratora bazy danych. Zwi�ksza to prawdopodobieDstwo wystpienia pewnych problem�w, jak na przykBad interpretacja warto[ci roku (jaki rok jest oznaczony warto[ci '00'?). Og�lnie mo|na powiedzie, |e w celu konwersji na format daty systemu Oracle nale|y skorzysta z funkcji TO_DATE. Powy|szy fragment kodu zawiera argumenty podane w formie literaB�w (literals), to znaczy z za- stosowaniem konkretnych warto[ci. Jest to dobry spos�b w przypadku przeprowadzania test�w, jednak|e podczas programowania w j�zyku PL/SQL zazwyczaj u|ywa si� zmiennych w wywoBa- niach. Warto[ci zmiennych s zazwyczaj ustalane nie poprzez bezpo[redni zapis w kodzie programu, ale na przykBad przez u|ytkownika korzystajcego z klawiatury i ekranu, wy[wietlajcego odpowied- nie informacje. Warto si� zastanowi nad sposobem wywoBywania procedury w przypadku posiadania niepeBnej informacji dotyczcej dodawanej ksi|ki  na przykBad w przypadku braku daty wydania lub opisu. PrzykBadowo, w takim przypadku mo|na poda warto[ci NULL dla tych parametr�w i sprawdzi, czy nie spowoduje to problem�w z wykonywaniem programu:2 add_book('1-56592-335-9', '100000001', 'Programowanie w Oracle PL/SQL', 'Feuerstein, Steven, Bill Pribyl', 987, NULL, NULL); Jest to jedna z mo|liwo[ci. Mo|na tak|e w og�le nie podawa warto[ci argument�w i oprze si� na warto[ciach domy[lnych. W tym przypadku b�dzie to wywoBanie poprawne, gdy| w sekcji nagB�w- kowej procedury dla dw�ch ostatnich parametr�w zdefiniowano warto[ci domy[lne: ...summary_in IN VARCHAR2 DEFAULT NULL, date_published_in IN DATE DEFAULT NULL); Warto[ci NULL w tym kontek[cie s w peBni poprawnymi warto[ciami. Korzystajc z warto[ci domy[lnych, mo|na przedstawione powy|ej wywoBanie upro[ci i pomin ostatnie dwa argumenty: add_book('1-56592-335-9', '100000001', 'Programowanie w Oracle PL/SQL', 'Feuerstein, Steven, Bill Pribyl', 987); W tym przypadku mechanizm odpowiedzialny za wykonanie kodu PL/SQL w miejsce brakujcych argument�w podstawi warto[ci domy[lne i wykonanie procedury odb�dzie si� identycznie, jak we wcze[niejszym przypadku. Mo|liwo[ pomijania argument�w dla parametr�w posiadajcych warto[ domy[ln jest niezwykle przydatn cech j�zyka PL/SQL, poniewa| umo|liwia prawidBowe dziaBanie jednostki programowej nawet bez podania tych argument�w. Ponadto mechanizm ten mo|e w ogromnym stopniu zredukowa negatywny wpByw ewentualnych, przyszBych modyfikacji. PrzykBadowo, je[li zaistnieje potrzeba dodania do programu pewnych parametr�w, to dzi�ki zdefiniowaniu ich warto[ci domy[lnych nie b�dzie trzeba przeglda caBego kodu, aby zmieni ka|de wyst�pujce w nim wywoBanie. 2 Ze wzgl�du na oszcz�dno[ miejsca w niniejszej ksi|ce nie zawsze jest przedstawiany peBny kod programu. W tym przypadku nale|aBoby doda instrukcj� EXECUTE lub obj wywoBanie sBowami kluczowymi BEGIN i END oraz doda koDcowe  / w celu uruchomienia tej procedury z poziomu SQL*Plus. Warto te| wiedzie, |e wywoBujc procedur� mo|na jednocze[nie pomija parametry posiadajce warto[ci domy[lne oraz podawa warto[ci NULL: add_book('1-56592-335-9', '100000001', 'Programowanie w Oracle PL/SQL', NULL, 987); Czytelnik by mo|e ma pewne problemy z zapami�taniem, kt�ra warto[ odpowiada kt�remu ar- gumentowi, ale jest to rzecz normalna w przypadku notacji pozycyjnej (positional notation), co ozna- cza konieczno[ podawania argument�w w takiej samej kolejno[ci, w jakiej zapisano dane parametry w kodzie programu. Rozwizaniem tych problem�w mo|e by zastosowanie innego, bardzo u|ytecznego mechanizmu  notacji imiennej (named notation). Spos�b dziaBania notacji imiennej najlepiej mo|na wyja[ni na przykBadzie. W przypadku poni|szego wywoBania procedury add_book wykorzystano wBa[nie ten mechanizm: add_book(isbn_in => '1-56592-335-9', title_in => 'Programowanie w Oracle PL/SQL', summary_in => 'Kompendium informacji o jzyku PL/SQL, ' || 'wraz z przykBadami i poradami na temat programowania.', author_in => 'Feuerstein, Steven, Bill Pribyl', date_published_in => NULL, page_count_in => 987, barcode_id_in => '100000001'); Z powy|szego wynika, |e dla ka|dego argumentu podaje si� nazw� parametru zdefiniowanego w pro- cedurze add_book, symbol => oraz warto[ danego parametru. Zalet tej metody jest to, |e po- szczeg�lne argumenty mo|na podawa w dowolnej kolejno[ci  nie trzeba pami�ta kolejno[ci, w jakiej zdefiniowano parametry w procedurze. Wyb�r metody caBkowicie zale|y od programisty  dla kompilatora jest to bez znaczenia. Argu- mentem przemawiajcym za stosowaniem notacji imiennej mo|e by fakt, |e w ten spos�b kod staje si� du|o bardziej przejrzysty. Znaczenie wyra|enia page_count => 987 nie pozostawia wt- pliwo[ci, a na pewno nie jest tak w przypadku podania samej warto[ci 987. Mo|na tak|e, oczywi- [cie, pomija parametry opcjonalne (domy[lne)  w tym przypadku mo|e to by, przykBadowo, date_published_in: add_book(isbn_in => '1-56592-335-9', title_in => 'Programowanie w Oracle PL/SQL', summary_in => 'Kompendium informacji o jzyku PL/SQL, ' || 'wraz z przykBadami i poradami na temat programowania.', author_in => 'Feuerstein, Steven, Bill Pribyl', page_count_in => 987, barcode__is_in => '100000001'); Poza konieczno[ci pisania wi�kszej ilo[ci kodu istnieje tak|e pewna niedogodno[, wynikajca ze stosowania tej notacji. W razie potrzeby zmiany nazwy parametru konieczne jest uaktualnienie nie tylko samej procedury, ale tak|e ka|dego jej wywoBania w notacjiimiennej. Z drugiej jednak stro- ny zmiana nazwy parametru jest raczej rzadko wykonywan operacj. Istnieje tak|e mo|liwo[ wykorzystania obydw�ch notacji w jednym wywoBaniu. Nale|y pami�ta jedynie o paru zasadach. Nale|y zacz od notacji pozycyjnej, a po przej[ciu do notacji imiennej trzeba przy niej pozosta do koDca. Oto przykBad: add_book('1-56592-335-9', '100000001', 'Programowanie w Oracle PL/SQL', summary_in => NULL, author_in => 'Feuerstein, Steven, Bill Pribyl', page_count_in => 987); U|ywanie notacji imiennej W razie konieczno[ci dokonania wyboru nale|y stosowa notacj wymieniajc wszdzie tam, gdzie znaczenie poszczeg�lnych argument�w nie jest oczywiste. PrzykBadowo: uaktualnij_moj_profil(ulub_ksiazka_isbn => '1-56592-335-9'); Notacji pozycyjnej nale|y u|ywa w przypadku czsto u|ywanych program�w u|ytkowych, kt�re posiadaj jeden lub dwa parametry, a znaczenie tych parametr�w jest oczywiste: DBMS_OUTPUT.PUT_LINE('Witaj Muddah.'); Zastosowanie obydw�ch notacji mo|e okaza si przydatne w sytuacji, gdy na przykBad pierwszy argument jest oczywisty, za[ kolejne nie: moje_put_line('Witaj Fadduh.', linie_do_pominiecia => 2); W tym podrozdziale przedstawiono przykBad konstruowania i wykorzystywania procedury magazy- nowanej j�zyka PL/SQL, kt�ra wykonuje pojedyncze zadanie. Zadanie to polega na dodaniu do bazy danych informacji o ksi|ce identyfikowanej za pomoc odpowiedniego kodu kreskowego. Kolej- ne zadanie polega na okre[leniu liczby egzemplarzy danej ksi|ki. Potrzeba pobierania informacji o takiej pojedynczej warto[ci stanowi idealn sposobno[ wykorzystania funkcji j�zyka PL/SQL, kt�ra ze swej definicji zwraca jak[ warto[ (lub koDczy dziaBanie nie obsBu|onym wyjtkiem). Przed podj�ciem pr�by zapisania kodu funkcji trzeba najpierw zapozna si� z og�ln skBadni two- rzenia funkcji. Funkcje stanowi drugi typ program�w magazynowanych. Poni|ej przedstawiono wzorzec definiowania funkcji. Elementy, kt�re oznaczono za pomoc czcion- ki pogrubionej, mog by jeszcze Czytelnikowi nieznane. CREATE [ OR REPLACE ] FUNCTION nazwa_funkcji (parametr1 TRYB TYP_DANYCH [ DEFAULT wyra|enie ], parametr2 TRYB TYP_DANYCH [ DEFAULT wyra|enie ], ...) RETURN TYP_DANYCH AS [ zmienna1 TYP_DANYCH; zmienna2 TYP_DANYCH; ... ] BEGIN instrukcje_wykonawcze; RETURN wyra|enie; [ EXCEPTION WHEN nazwa_wyjtku THEN instrukcje_wykonawcze ] END; / R�|nice pomi�dzy wzorcem dotyczcym funkcji i wzorcem procedury s minimalne. Poza zamian sBowa kluczowego PROCEDURE na FUNCTION w instrukcji CREATE, kod r�|ni si� tylko w dw�ch miejscach. Pierwszym z nich jest nagB�wek, gdzie podaje si� zwracany typ danych, a drugim jest cz�[ wykonawcza, gdzie nast�puje bezpo[rednie przekazanie zwracanej warto[ci do programu wy- woBujcego. RETURN TYP_DANYCH W nagB�wku wyra|enie RETURN stanowi cz�[ deklaracji funkcji. Jest to informacja o typie danych warto[ci, kt�re maj by zwracane w wyniku wywoBania funkcji. RETURN wyra|enie Wewntrz sekcji wykonawczej wyra|enie RETURN jest instrukcj i oznacza, |e dziaBania zostaBy zakoDczone i |e nale|y zwr�ci (return) warto[, kt�r definiuje wyra|enie. Instrukcja RETURN mo|e znalez si� tak|e w sekcji EXCEPTION. Obydwie wymienione instrukcje s wymagane. W nast�pnym podrozdziale przedstawiono kod go- towej funkcji. Funkcja book_copy_qty zwraca liczb� ksi|ek, kt�rych numer ISBN odpowiada podanemu. W poni|szym, przykBadowym kodzie funkcji do pobrania danych z bazy danych wykorzystano kursor (cursor). Szczeg�Bowe om�wienie tej struktury znajduje si� dopiero w rozdziale 5. Uog�lnia- jc, kursor jest okre[lonym miejscem w pami�ci, do kt�rego program mo|e przenie[ pewne dane po- brane z bazy danych. W sekcji deklaracji nast�puje powizanie pewnej instrukcji SELECT z kur- sorem. Powizanie to zachodzi za pomoc instrukcji CURSOR. Warto zwr�ci uwag�, |e parametr wej[ciowy isbn_in wyst�puje po prawej stronie wyra|enia WHERE. W celu pobrania danych nale- |y kursor otworzy (open), pobra (fetch) z niego dane, a w koDcu go zamkn (close). CREATE OR REPLACE FUNCTION book_copy_qty(isbn_in IN VARCHAR2) RETURN NUMBER AS number_o_copies NUMBER := 0; CURSOR bc_cur IS SELECT COUNT(*) FROM book_copies WHERE isbn = isbn_in; BEGIN IF isbn_in IS NOT NULL THEN OPEN bc_cur; FETCH bc_cur INTO number_o_copies; CLOSE bc_cur; END IF; RETURN number_o_copies; END; / Konstrukcja funkcji niewiele odbiega od procedury. R�|ni si� one jednak swoim zachowaniem  szczeg�By dotyczce dziaBania funkcji przedstawiono na rysunku 3.6. Rysunek 3.6. Wykorzystanie funkcji jzyka PL/SQL w celu zwr�cenia pewnej warto[ci do programu wywoBujcego; dla danej warto[ci ISBN funkcja zwraca liczb egzemplarzy znajdujcych si w bazie danych Zasadnicza r�|nica pomi�dzy wywoBaniem funkcji i procedury wynika z tego, |e funkcje zwracaj pewn warto[. Najprostszym sposobem wykorzystania warto[ci wynikowej, zwracanej przez funkcj�, jest jej przy- pisanie do pewnej zmiennej, kt�rej typ odpowiada typowi zwracanej warto[ci. Zwykle wyglda to w nast�pujcy spos�b: DECLARE zmienna_lokalna TYP_DANYCH; BEGIN zmienna_lokalna := nazwa_funkcji (argument1, argument2, ...); END; / Jest to zatem typowa instrukcja przypisania, gdzie wywoBanie funkcji znajduje si� po prawej stronie operatora przypisania, a zmienna lokalna po lewej. Mo|na wi�c napisa: DECLARE ile INTEGER; BEGIN ile := book_copy_qty('1.56592-335-9'); END; / Z informacji przedstawionych w rozdziale 1. wynika, |e w celu wy[wietlenia wynik�w na ekranie mo|na przekaza je do funkcji DBMS_OUTPUT.PUT_LINE: SET SERVEROUTPUT ON BEGIN DBMS_OUTPUT.PUT_LINE('Liczba kopii 1-56592-335-9: ' || book_copy_qty('1-56592-335-9')); END; / Funkcja book_copy_qty zwraca warto[ typu VARCHAR2, co umo|liwia konkatenacj� z innym cigiem znak�w i u|ycie funkcji PUT_LINE. Takie zagnie|d|anie funkcji wewntrz innych in- strukcji jest cz�sto stosowan technik. Poni|ej wymieniono kilka wartych zapami�tania zasad dotyczcych wykorzystania funkcji: 1. Nie mo|na tworzy niezale|nych (standalone) funkcji o takich samych nazwach, jakie nosz niezale|ne procedury. Jednak|e przyj�cie konwencji nazywania procedur wyra|eniem czasownikowym, a funkcji  wyra|eniem rzeczownikowym mo|e uchroni przed potencjalnymi problemami. 2. Nieuwzgl�dnienie w nagB�wku wyra|enia RETURN spowoduje, |e funkcja nie zostanie skompilowana. Jest to dziaBanie pozytywne, gdy| bB�dy czasu kompilacji uwa|a si� za metod� wczesnego ostrzegania przed ewentualnymi problemami. Je[li jednak sBowo kluczowe RETURN zostanie pomini�te w sekcji wykonawczej, system Oracle poinformuje o tym dopiero po uruchomieniu funkcji. Zostanie wtedy wygenerowany komunikat o bB�dzie ORA-06503: PL/SQL: Function returned without value. Dlatego zawsze warto przeprowadza dogB�bne testy napisanych program�w. Procedury a funkcje Uog�lniajc, funkcja sBu|y do przeprowadzenia pewnych operacji, kt�rych celem jest otrzyma- nie pewnej warto[ci. Oczywi[cie, jest mo|liwe wykorzystanie procedury zamiast funkcji i za- stosowanie pojedynczego parametru OUT, jednak takie postpowanie nie jest zalecane. Warto te| pamita, |e nie nale|y pisa program�w, kt�re zwracaj warto[ informujc o stanie zakoDczenia. Postpowanie takie jest uzasadnione w jzyku takim jak C, lecz w przypadku PL/SQL informowanie o bBdach powinno si odbywa poprzez przechwytywanie wyjtk�w. Je[li program magazynowany nie przechwyci wyjtku, zakBada si, |e podczas wykonania tego programu nie napotkano |adnych problem�w. Czasami okazuje si, |e istnieje potrzeba zwr�cenia wicej ni| jednej warto[ci  w takim przy- padku nale|y utworzy procedur. W celu zwr�cenia wielu warto[ci trzeba wykorzysta kilka parametr�w w trybie OUT lub IN OUT, kt�rych warto[ mo|e by odczytana przez program wywoBujcy po zakoDczeniu dziaBania procedury. Zdefiniowanie kilku parametr�w w trybie OUT mo|e wprowadzi nieco zamieszania, jednak istnieje metoda zapisywania program�w, kt�- re musz zwraca wiksz ilo[ danych w bardziej czytelny spos�b. Mo|na bowiem r�|ne ele- menty poBczy w jedn caBo[ przez zastosowanie jednego ze zBo|onych typ�w danych, jak na przykBad rekord, kolekcja lub tak zwany typ obiektowy. Zagadnienia te opisano w rozdziale 5. 3. Program wywoBujcy po wywoBaniu funkcji musi w jaki[ spos�b wykorzysta zwr�con warto[, na przykBad przypisa j pewnej zmiennej. PL/SQL, w przeciwieDstwie do j�zyka C, nie dopuszcza wywoBania funkcji i zignorowania zwracanej warto[ci. 4. Po wykonaniu instrukcji RETURN w sekcji wykonawczej do programu wywoBujcego zostaje przekazana nie tylko warto[, ale tak|e sterowanie wykonaniem programu. Innymi sBowy, kod zapisany po instrukcji RETURN nie jest wykonywany. Warto r�wnie| zwraca uwag� na stosowan terminologi�. Czasami, gdy kto[ m�wi o  procedurach magazynowanych , naprawd� ma na my[li programy magazynowane, czyli albo procedury, albo funkcje. Z drugiej jednak strony, mo|e chodzi wBa[nie o procedury, nie za[ funkcje. Je[li og�lny kontekst rozmowy nie pozwala na rozpoznanie, o kt�r mo|liwo[ chodzi, z pewno[ci pro[ba o wyja[nienie nie b�dzie objawem dyletanctwa. Powy|ej przedstawiono nast�pujcy spos�b wywoBania funkcji: DECLARE ile INTEGER; BEGIN ile := book_copy_qty('1-56592-335-9'); END; / WydawaBoby si�, |e powy|szy kod mo|na zapisa w bardziej zwi�zBy spos�b poprzez wywoBanie funkcji podczas inicjalizacji zmiennej: DECLARE ile INTEGER := book_copy_qty('xyz'); BEGIN Z pozoru wszystko jest w porzdku. Jednak je[li funkcja przechwyci wyjtek, to okazuje si�, |e |aden kod obsBugi wyjtku w tej sekcji nie zdoBa przechwyci wyjtku, kt�ry ewentualnie mo|e pojawi si� po takim wywoBaniu funkcji book_copy_qty. A zatem: DECLARE ile INTEGER := book_copy_qty('xyz'); BEGIN ...cokolwiek... EXCEPTION WHEN OTHERS THEN /* NIESPODZIANKA! Wyjtki przechwycone w sekcji deklaracji || NIE MOG by obsBu|one w tym miejscu! */ ... END; / WytBumaczenie powodu takiego zachowania wykracza poza zakres niniejszej ksi|ki. Dlatego nale|y po prostu zapami�ta, |e nie nale|y dokonywa pr�b inicjalizowania zmiennych za pomoc funkcji. Z pewno[ci Czytelnik chciaBby kontynuowa rozwijanie tworzonej, przykBadowej aplikacji. Nie mo|na jednak zapomina o konsekwentnym upewnianiu si�, |e zapisany od nie zawiera bB�d�w. Z tego te| wzgl�du poni|ej zamieszczono pewnego rodzaju dygresj�. Z pewno[ci ka|dy zetknB si� ju| z wyra|eniem garbage in, garbage out (GIGO). Jest to wyra|e- nie do[ cz�sto u|ywane lub sByszane przez telefon podczas rozmowy z obsBug techniczn. Oznacza ono mniej wi�cej tyle, co  wprowadzasz bB�dne dane  uzyskujesz bB�dne wyniki . Unikni�cie problemu GIGO jest spraw do[ problematyczn. Istnieje tendencja do nieuzasadnione- go optymizmu w kwestii wykorzystywania utworzonych aplikacji. Ch�tniej przyjmuje si� zaBo|enie tidy in, tidy out (wprowadzasz poprawne dane  uzyskujesz poprawne wyniki)3. Nikt nie lubi z g�ry planowa dziaBaD zapobiegawczych wzgl�dem zastosowania niepoprawnych danych wej[ciowych. W celu unikni�cia nieprzewidzianych zaBamaD programu trzeba przeprowadzi serie test�w. Prze- prowadzenie dobrych test�w oznacza generowanie przer�|nych kombinacji danych testowych, kt�re potencjalnie powinny  zawiesi program. Potem nale|y sprawdzi oczekiwany wynik, uru- chomi program, por�wna z danymi wyj[ciowymi, poprawi program i wreszcie& ponownie przeprowadzi testy. Z pewno[ci warto upro[ci ten caBy proces. Monotonne wykonywanie fragmentu kodu z r�|nymi danymi wej[ciowymi jest dobr okazj do na- pisania pewnych program�w u|ytkowych. Poni|ej przedstawiono spos�b zautomatyzowania tego m�czcego procesu za pomoc takich program�w. DziaBanie pierwszego, sprawdzajcego programu polega na por�wnywaniu dw�ch warto[ci i wy[wie- tlaniu komunikatu o pomy[lnym lub niepomy[lnym przebiegu tego testu. U podstaw testowania le|y wBa[nie por�wnywanie warto[ci  warto[ci faktycznej ze spodziewan warto[ci wyj[ciow. Dlatego te| wspomniany program jest bardzo u|yteczny. ZawieraB on tak|e opis poszczeg�lnych iteracji, tak aby umo|liwi otrzymanie informacji o tym, dla jakich warto[ci wykonanie programu b�dzie niepomy[lne. Poni|ej znajduje si� kod tej procedury  test r�wno[ci (testrownosci): CREATE OR REPLACE PROCEDURE reporteq (description IN VARCHAR2, expected_value IN VARCHAR2, actual_value IN VARCHAR2) AS BEGIN DBMS_OUTPUT.PUT(description || ': '); IF expected_value = actual_value OR (expected_value IS NULL AND actual_value IS NULL) THEN DBMS_OUTPUT.PUT_LINE('PASSED'); 3 NieprzetBumaczalna gra sB�w: garbage to po angielsku [mieci, bzdury; tidy  czysty, schludny  przyp. tBum. ELSE DBMS_OUTPUT.PUT_LINE('FAILED. Expected ' || expected_value || '; got ' || actual_value); END IF; END; / W powy|szej procedurze por�wnywaniu podlegaj cigi znak�w (VARCHAR2), ale mo|na oczywi- [cie napisa analogiczne procedury obsBugujce liczby, daty czy te| warto[ci logiczne. Kolejnym krokiem b�dzie napisanie programu wywoBujcego procedur� add_book na wiele spo- sob�w  tak|e w razie zastosowania nieprawidBowych danych wej[ciowych. Poni|szy program ze wzgl�du na jego obszerno[ (89 linii kodu) podzielono na fragmenty. Dodatkowo ponumerowano poszczeg�lne linie w celu uBatwienia odwoBywania si� do nich. 1 DECLARE 2 l_isbn VARCHAR2(13) := '1-56592-335-9'; 3 l_title VARCHAR2(200) := 'Oracle PL/SQL Programming'; 4 l_summary VARCHAR2(2000) := 'Reference for PL/SQL developers, ' || 5 'including examples and best practice recommendations.'; 6 l_author varchar2(200) := 'Feuerstein, Steven, and Bill Pribyl'; 7 l_date_published DATE := TO_DATE('01-WRZ-1997', 'DD-MON-YYYY'); 8 l_page_count NUMBER := 987; 9 l_barcode_id VARCHAR2(100) := '100000001'; 10 11 CURSOR bookCountCur IS 12 SELECT COUNT(*) FROM books; 13 14 CURSOR copiesCountCur IS 15 SELECT COUNT(*) FROM book_copies; 16 17 CURSOR bookMatchCur IS 18 SELECT COUNT(*) FROM books 19 WHERE isbn = l_isbn AND title = l_title AND summary = l_summary 20 AND author = l_author AND date_published = l_date_published 21 AND page_count = l_page_count; 22 23 CURSOR copiesMatchCur IS 24 SELECT COUNT(*) FROM book_copies 25 WHERE isbn = l_isbn AND barcode_id = l_barcode_id; 26 27 how_many NUMBER; 28 l_sqlcode NUMBER; Poni|ej znajduje si� kilka wyja[nieD dotyczcych przedstawionego fragmentu kodu. Linie 2.  9. S to deklaracje zmiennych lokalnych, kt�re reprezentuj warto[ci u|ywane w r�|nych testach. Przechowywanie tych warto[ci w zmiennych uBatwia programowanie z uwagi na mo|li- wo[ ich wielokrotnego u|ycia. Przedrostek l_ oznacza, |e s to zmienne lokalne. Linie 11.  12. Jest to deklaracja pierwszego z kursor�w programu. Kursor umo|liwia pobieranie warto[ci z bazy danych za pomoc instrukcji j�zyka SQL SELECT. Ta konkretna instrukcja oblicza caBkowit liczb� rekord�w w tabeli ksiazki. Linie 14.  15. Jest to r�wnie| deklaracja kursora programu  umo|liwia on obliczanie caBkowi- tej liczby egzemplarzy ksi|ki. Linie 17.  21. Ten kursor sBu|y do obliczania liczby ksi|ek, dla kt�rych warto[ci kolumn odpo- wiadaj warto[ciom zmiennych lokalnych. Linia 27. Zmienna lokalna ile przechowuje tymczasowo rezultat dziaBania powy|szych zapytaD. Linia 28. Zmienna l_sqlcode przechowuje tymczasowo warto[ wyj[ciow wewn�trznej funk- cji PL/SQL  SQLCODE. Jej dziaBanie zostanie om�wione nieco dalej. Poni|ej przedstawiono sekcj� wykonawcz omawianego programu. Rozpoczyna ona swoje dziaBa- nie od usuni�cia zawarto[ci obydw�ch tabel w bazie danych. W ten spos�b uzyskuje si� pewno[, |e wszelkie operacje zliczania b�d dotyczy jedynie bie|cych danych testowych, a nie innych, kt�re mogBy pozosta po wcze[niejszych wykonaniach. Oczywi[cie, caBa ta procedura powinna doty- czy pewnej testowej bazy danych, a nie bazy podstawowej. 29 BEGIN 30 DELETE book_copies; 31 DELETE books; 32 33 add_book(isbn_in => l_isbn, barcode_id_in => l_barcode_id, 34 title_in => l_title, summary_in => l_summary, author_in => l_author, 35 date_published_in => l_date_published, page_count_in => l_page_count); 36 37 OPEN bookMatchCur; 38 FETCH bookMatchCur INTO how_many; 39 reporteqbool('add procedure, book fetch matches insert', 40 expected_value => TRUE, actual_value => bookMatchCur%FOUND); 41 CLOSE bookMatchCur; 42 Linie 33.  41. W tym miejscu nast�puje pierwsze wywoBanie procedury add_book. Wykorzy- stywane s wszystkie zdefiniowane wcze[niej parametry i oczekiwane jest poprawne zakoDczenie procedury. WywoBanie to rozpoczyna proces sprawdzajcy, czy procedura dodawania ksi|ki dziaBa poprawnie. Nast�puje to przez otwarcie kursora, pobranie z niego danych i sprawdzenie, czy, zgodnie z oczekiwaniami, rekord zostaB utworzony. W liniach 39.  40. znajduje si� wywoBa- nie procedury reporteqbool  jest to odmiana procedury reporteq, kt�ra wykorzystuje warto[ci logiczne (Boolean) zamiast cig�w znak�w. Je[li pobranie danych do kursora koDczy si� powodzeniem, warto[ci bookMatchCur%FOUND jest TRUE (wi�cej informacji na temat wyko- rzystania tej techniki znajduje si� w rozdziale 5.). Jak wynika z tre[ci linii 41., dobrym zwyczajem jest zamykanie kursora po jego u|yciu. 43 BEGIN 44 add_book(isbn_in => NULL, barcode_id_in => 'foo', title_in => 'foo', 45 summary_in => 'foo', author_in => 'foo', 46 date_published_in => SYSDATE, page_count_in => 0); 47 l_sqlcode := SQLCODE; 48 EXCEPTION 49 WHEN OTHERS THEN 50 l_sqlcode := SQLCODE; 51 END; 52 53 reporteq('add procedure, detection of NULL input', 54 expected_value => '-6502', actual_value => TO_CHAR(l_sqlcode)); 55 Linie 43.  54. Ten fragment kodu sBu|y do przeprowadzenia kolejnego testu  tym razem nast�- puje pr�ba okre[lenia warto[ci NULL dla parametru isbn w celu sprawdzenia prawidBowego dziaBania detekcji bB�dnych danych wej[ciowych. Je[li procedura add_book dziaBa poprawnie, po- winna przechwyci wyjtek NO_DATA_FOUND. Programista powinien zosta poinformowany o tym fakcie, a zatem tekst zostaB umieszczony w bloku zagnie|d|onym. W ten spos�b mo|na obsBu|y wyjtek niejako w kolejnej instrukcji zamiast przeskakiwa do koDcowej cz�[ci bloku gB�wnego (sekcji obsBugi wyjtk�w). W celu zachowania zgodno[ci z innymi przeprowadzanymi testami, tu r�wnie| trzeba przeprowa- dzi por�wnanie otrzymanej warto[ci z pewn warto[ci oczekiwan. PL/SQL zawiera specjaln funkcj� wewn�trzn SQLCODE, kt�ra wywoBana z poziomu kodu obsBugi wyjtku zawsze zwraca okre[lon warto[ r�|n od zera. Z uwagi na fakt, |e warto[ ta ma zosta wykorzystana poza ko- dem obsBugi wyjtku, w linii 50. nast�puje przypisanie tej warto[ci zmiennej l_sqlcode, kt�ra nast�pnie jest wykorzystywana w liniach 53. i 54. podczas wywoBania procedury reporteq. Z linii 54. wynika, |e warto[ oczekiwana wynosi  6502. Jest to warto[, kt�r PL/SQL przypi- suje SQLCODE w sytuacji, gdy pojawia si� wyjtek NO_DATA_FOUND. 56 OPEN bookCountCur; 57 FETCH bookCountCur INTO how_many; 58 reporteq('add procedure, book_record count', expected_value => '1', 59 actual_value => how_many); 60 CLOSE bookCountCur; 61 62 OPEN copiesCountCur; 63 FETCH copiesCountCur INTO how_many; 64 reporteq('add procedure, book_copy record count', expected_value => '1', 65 actual_value => how_many); 66 CLOSE copiesCountCur; 67 68 OPEN copiesMatchCur; 69 FETCH copiesMatchCur INTO how_many; 70 reporteqbool('add procedure, book copy fetch matches insert', 71 expected_value => TRUE, actual_value => copiesMatchCur%FOUND); 72 CLOSE copiesMatchCur; 73 Linie 56.  72. Kolejne linie kodu sBu| do sprawdzenia, czy w tabeli znajduje si� oczekiwana liczba rekord�w. 74 BEGIN 75 add_book(isbn_in => l_isbn, barcode_id_in => l_barcode_id, 76 title_in => l_title, summary_in => l_summary, author_in => l_author, 77 date_published_in => l_date_published, 78 page_count_in => l_page_count); 79 l_sqlcode := SQLCODE; 80 EXCEPTION 81 WHEN OTHERS THEN 82 l_sqlcode := SQLCODE; 83 END; 84 reporteq('add procedure, detection of duplicate isbn', 85 expected_value => '-1', actual_value => l_sqlcode); 86 END; 87 / Linie 74.  85. Kolejny test, uwzgl�dniony w omawianym programie, polega na sprawdzeniu, czy pr�ba wprowadzenia drugi raz tej samej warto[ci isbn spowoduje przechwycenie wyjtku. Sys- tem Oracle powinien w takiej sytuacji ustawi warto[ SQLCODE na  1, co oznacza wBa[nie pr�b� wstawienia rekordu o takim samym kluczu gB�wnym, co rekord ju| istniejcy (w rzeczywisto[ci jest to test poprawno[ci projektu bazy danych). Jest to w zasadzie ostatni punkt kontrolny testu poprawno[ci procedury add_book. Je|eli przed uruchomieniem programu wykonano komend� SERVEROUTPUT ON (dokBadniejszy opis znajduje si� w rozdziale 2.), wywoBanie omawianego programu z poziomu SQL*Plus powoduje wy[wietle- nie nast�pujcych informacji: add procedure, book fetch matches insert: PASSED add procedure, detection of null input: PASSED add procedure, book record count: PASSED add procedure, book_copy record count: PASSED add procedure, book_copy fetch matches insert: PASSED add procedure, detection of duplicate isbn: PASSED By mo|e Czytelnik zauwa|yB, |e powy|szy kod sBu|y jako test jednostki programowej (unit test)4. Mo|e on tak|e posBu|y jako zapisany przykBad wywoBywania programu, co mo|e okaza si� przy- datne w razie zaistnienia wtpliwo[ci dotyczcych sposobu przeprowadzenia podobnej procedury. Poni|szy program sBu|y do testowania pracy funkcji book_copy_qty. Zasadniczo spos�b jego dziaBania jest taki sam, jak w przypadku poprzedniego programu. 1 DECLARE 2 l_isbn VARCHAR2(13) := '1-56592-335-9'; 3 l_isbn2 VARCHAR2(13) := '2-56592-335-9'; 4 l_title VARCHAR2(200) := 'Programowanie w Oracle PL/SQL'; 5 l_summary VARCHAR2(2000) := 'Kompendium informacji o jzyku PL/SQL ' || 6 'wraz z przykBadami i poradami na temat programowania.'; 7 l_author varchar2(200) := 'Feuerstein, Steven, Bill Pribyl'; 8 l_date_published DATE := TO_DATE('01-WRZ-1997', 'DD-MON-YYYY'); 9 l_page_count NUMBER := 987; 10 l_barcode_id VARCHAR2(100) := '100000001'; 11 l_barcode_id2 VARCHAR2(100) := '100000002'; 12 l_barcode_id3 VARCHAR2(100) := '100000003'; 13 14 how_many NUMBER; 15 BEGIN 16 DELETE book_copies; 17 DELETE books; 4 Wyra|enie  jednostka programowa (unit) odnosi si� tu do pojedynczej jednostki programowej w przeciwieDstwie do innych rodzaj�w test�w, kt�re pozwalaj upewni si�, co do prawidBowej wsp�Bpracy poszczeg�lnych jednostek w ramach caBej aplikacji. 18 19 reporteq('book_copy_qty function, zero count', '0', 20 TO_CHAR(book_copy_qty(l_isbn))); 21 22 /* ZakBadamy, |e procedura add_book dziaBa prawidBowo */ 23 add_book(isbn_in => l_isbn, barcode_id_in => l_barcode_id, 24 title_in => l_title, summary_in => l_summary, author_in => l_author, 25 date_published_in => l_date_published, page_count_in => l_page_count); 26 27 reporteq('book_copy_qty function, unit count', '1', 28 TO_CHAR(book_copy_qty(l_isbn))); 29 30 add_book_copy(isbn_in => l_isbn, barcode_id_in => l_barcode_id2); 31 add_book_copy(isbn_in => l_isbn, barcode_id_in => l_barcode_id3); 32 33 reporteq('book_copy_qty function, multi count', '3', 34 TO_CHAR(book_copy_qty(l_isbn))); 35 36 reporteq('book_copy_qty function, null ISBN', '0', 37 TO_CHAR(book_copy_qty(NULL))); 38 END; 39 / Linie 30.  31. Ten fragment kodu zawiera wywoBania procedury, kt�ra jeszcze nie zostaBa Czy- telnikowi przedstawiona. Procedura ta sBu|y do wstawienia rekordu do tabeli book_copies. Je|eli uruchomienie jednostki testowej powoduje wy[wietlenie wynik�w pokazanych poni|ej (przy zaBo|eniu, |e przed uruchomieniem programu wykonano polecenie SERVEROUTPUT ON), ozna- cza to prawidBowe dziaBanie funkcji book_copy_qty: book_copy_qty function, zero count: PASSED book_copy_qty function, unit count: PASSED book_copy_qty function, multi count: PASSED book_copy_qty function, null ISBN: PASSED By mo|e Czytelnik si� zastanawia nad zasadno[ci tworzenia takiej ilo[ci dodatkowego kodu. By mo|e po prostu wystarczyBoby przegldanie programu w celu wyszukania ewentualnych bB�d�w. Takie sprawdzanie kodu jest sposobem post�powania przeci�tnego programisty. Istot� problemu najlepiej oddaje sprawdzenie warto[ci NULL, wykonywane w liniach 40.  41. omawianego pro- gramu sprawdzajcego. Co prawda, ostateczny test wersji procedury add_book przebiegB po- my[lnie, jednak pocztkowo Autorzy wcale nie brali pod uwag� konieczno[ci sprawdzania warto- [ci NULL. Dopiero w trakcie pisania jednostki testowej okazaBo si�, |e nale|y uwzgl�dni co najmniej trzy przypadki wprowadzania danych wej[ciowych: okre[lenie danych poprawnych, niepoprawnych oraz uwzgl�dnienie tej problematycznej warto[ci NULL. UstaleD tych dokonano jedynie dzi�ki anali- zie mo|liwych danych wej[ciowych, kt�re nale|y uwzgl�dnia podczas planowania test�w. Wcze- [niejsze poprawne dziaBanie programu okazaBo si� kwesti przypadku. Testowanie i spos�b jego zaplanowania umo|liwia analiz� tworzonego kodu z zupeBnie odmiennego punktu widzenia, co po- zwala na uzyskanie nowych, wa|nych informacji. Czas przeznaczony na testowanie aplikacji jest niekiedy ograniczany z powod�w finansowych lub w rezultacie decyzji kierownictwa firmy. Cz�[ciej jednak testowanie aplikacji jest pomijane przez programist�w, kt�rzy postrzegaj t� czynno[ jako nudn lub nawet niepotrzebn. Bezwzgl�dnie nale|y jednak wyrobi sobie nawyk testowania pisanych przez siebie aplikacji. Dotychczas Czytelnik zapoznaB si� z kodem umo|liwiajcym przeprowadzanie kilku operacji zwi- zanych z obsBug katalogu. Przedstawiono tak|e kod kilku narz�dzi sBu|cych do testowania. Poni|ej opisano pewne uproszczenia, jakie dotychczas dopuszczano wobec omawianego problemu. Przedstawiono tak|e kilka sposob�w pokonania tych ograniczeD. Kod, kt�ry zaprezentowano we wcze[niejszych podrozdziaBach, nie rozwizuje jeszcze pewnych wa|nych zagadnieD, takich jak: " Mo|liwo[, |e rekord wstawiany do tabeli books ju| istnieje. Trzeba sprawdzi, czy jest to traktowane tak samo, jak wprowadzenie informacji o nowym egzemplarzu. " Spos�b modyfikowania danych w katalogu. " Sytuacja, w kt�rej dany rekord katalogu biblioteki zostanie przypadkowo usuni�ty lub utracony. Trzeba przeanalizowa mo|liwo[ci wykorzystania PL/SQL do przekazania tej informacji do systemu bazy danych. " Sytuacja, w kt�rej zaistnieje potrzeba wykonania wielu r�|nych zapytaD, np. wyszukiwanie ksi|ek na podstawie kilku r�|nych kryteri�w. Oczywi[cie, w dalszej cz�[ci niniejszej ksi|ki zostan przedstawione sposoby rozwizania wielu z powy|szych problem�w. Zaprezentowane b�d odpowiednie fragmenty kodu i spos�b ich doda- wania. Z powy|szego wynika, |e wygodnym rozwizaniem byBoby posiadanie mechanizmu pozwa- lajcego na organizowanie kodu w taki spos�b, aby umo|liwi jego Batwiejsze rozwijanie i utrzy- mywanie. Mechanizmem takim s pakiety (packages). Pakiet j�zyka PL/SQL jest pewnym nazwanym zbiorem, kt�ry mo|e zwiera dowoln liczb� pro- cedur i funkcji. Pakiety mog tak|e przechowywa inne obiekty, na przykBad wyjtki, zmienne czy deklaracje typ�w danych. W trakcie lektury dalszej cz�[ci niniejszej ksi|ki Czytelnik przekona si� o ogromnych korzy[ciach, kt�re pByn z tych dodatkowych mo|liwo[ci. W tym rozdziale jednak zostanie przedstawiony tylko spos�b wykorzystania teoo mechanizmu do wstawienia ju| utworzo- nego programu do pakietu. W przypadku innych j�zyk�w programowania  na przykBad Java lub Ada  tak|e istniej konstrukcje zwane pakietami. Jednak pakiety w j�zyku PL/SQL charakteryzuj specyficzne definicje i zachowania. Warto o tym pami�ta w przypadku zapoznawania si� z tymi strukturami w innych j�zykach. Z powod�w, kt�re stan si� niedBugo oczywiste, pakiety skBadaj si� zazwyczaj z dw�ch cz�[ci: specyfikacji (specification)  w skr�cie spec  oraz ciaBa (body). Specyfikacja pakietu zawiera jedynie informacje o jego mo|liwo[ciach (przeznaczeniu), ale nie ma tu |adnych wiadomo[ci o sposobie jego wykonania. Specyfikacja zawiera jedynie nagB�wki jednostek programowych, a nie kod wykonywalny. Jest to rodzaj sekcji deklaracyjnej, wyst�pujcej w jed- nostkach programowych. Uproszczony wzorzec skBadni definicji pakietu przedstawiono poni|ej: CREATE OR REPLACE PACKAGE nazwa_pakietu AS nagB�wek_programu1; nagB�wek_programu2; nagB�wek_programu3; END nazwa_pakietu; / nazwa_pakietu jest opisow nazw, jak u|ytkownik nadaje danemu pakietowi (nazwa ta podle- ga zasadom nadawania nazw obowizujcym w j�zyku PL/SQL). Poni|ej przedstawiono spos�b utworzenia pakietu, sBu|cego do zarzdzania ksi|kami w bazie danych. Pierwszym problemem jest nadanie odpowiedniej nazwy. Cz�[ programist�w uwa|a, |e taki rodzaj pakietu peBni rol� zarzdcy (manager) i dlatego zastosowan przez nich nazw byBoby book_mgr lub book_man. Inni raczej podkre[laj rodzaj obiektu i u|yliby nazwy book_pkt. Autorzy preferuj jednak nazwy kr�tkie i proste  a zatem wybrali prost nazw� book5. Poni|ej przedstawiono przykBadow specyfikacj� pakietu: CREATE OR REPLACE PACKAGE book AS PROCEDURE add(isbn_in IN VARCHAR2, title_in IN VARCHAR2, author_in IN VARCHAR2, page_count_in IN NUMBER, summary_in IN VARCHAR2 DEFAULT NULL, date_published_in IN DATE DEFAULT NULL, barcode_id_in IN VARCHAR2 DEFAULT NULL); PROCEDURE add_copy(isbn_in IN VARCHAR2, barcode_id_in IN VARCHAR2); FUNCTION book_copy_qty(isbn_in IN VARCHAR2) RETURN NUMBER; PROCEDURE change(isbn_in IN VARCHAR2, new_title IN VARCHAR2, new_author IN VARCHAR2, new_page_count IN NUMBER, new_summary IN VARCHAR2 DEFAULT NULL, new_date_published IN DATE DEFAULT NULL); 5 WywoBywanie program�w umieszczonych w pakietach odbywa si� w nast�pujcy spos�b: nazwa_pakietu. nazwa_programu  std mo|liwe okazuje si� u|ywanie zwi�zBych, lecz zrozumiaBych wywoBaD w rodzaju book.add(...). PROCEDURE remove_copy(barcode_id_in IN VARCHAR2); PROCEDURE weed(isbn_in IN VARCHAR2); END book; / W wi�kszo[ci przypadk�w (tak|e w powy|szym) nie ma potrzeby umieszczania w specyfikacji pa- kietu procedur i funkcji w okre[lonym porzdku. Warto zauwa|y, |e instrukcja definicji specyfikacji pakietu rozpoczyna si� od wyra|enia CREATE OR REPLACE, za[ poszczeg�lne programy w nagB�wku maj posta: FUNCTION nazwa ... lub: PROCEDURE nazwa ... Jest to spowodowane faktem, |e w przypadku j�zyka PL/SQL caBy kod pojedynczego pakietu jest tworzony, uaktualniamy lub usuwany jednocze[nie, tak wi�c sensowne jest tylko zastosowanie jed- nej instrukcji CREATE. Z powy|szego wynika, |e w planach rozwoju aplikacji uwzgl�dniono dodanie kilku brakujcych funk- cji (jednak|e metody niezb�dne do pobierania danych z bazy danych nie zostan na razie utworzone). Specyfikacja pakietu peBni rol� interfejsu programowania aplikacji (application programming interface, API) w odniesieniu do pakietu. Nazwa ta jest by mo|e nieco nie[cisBa, lecz oddaje istot� idei stosowania pakietu. Ka|dy API sBu|y bowiem jako forma komunikacji mi�dzy u|ytkownikami (np. mi�dzy piszcymi program i wykorzystujcymi go). Sens takiego post�powania polega na ukry- ciu niejednokrotnie bardzo skomplikowanych rozwizaD programistycznych za ich prost prezentacj. CiaBo pakietu zawiera elementy strukturalne jednostek programowych, czyli instrukcje wykonawcze odpowiadajce nagB�wkom podanym w specyfikacji pakietu. Uproszczony wzorzec skBadniowy ciaBa pakietu znajduje si� poni|ej: CREATE OR REPLACE PACKAGE BODY nazwa_pakietu AS programy_prywatne; /* opcjonalnie */ ciaBo_programu1; ciaBo_programu2; ciaBo_programu3; END nazwa_pakietu; / Innymi sBowy, ciaBo pakietu jest t lokalizacj, gdzie si� umieszcza implementacje program�w wy- mienionych w specyfikacji. Niemal zawsze ciaBo pakietu tworzy si� po zdefiniowaniu jego specyfikacji. Kompilator sprawdza, z kt�r specyfikacj jest zwizane dane ciaBo poprzez sprawdzenie jego nazwy, kt�ra musi by iden- tyczna z wymienion w specyfikacji. Ponadto ciaBo pakietu musi zawiera definicje wszystkich program�w, jakie zostaBy wymienione w specyfikacji  w przeciwnym wypadku kompilacja si� nie powiedzie. Jednak|e warto zauwa|y, |e zasada ta nie dziaBa odwrotnie  ciaBo pakietu mo|e zawiera pewne dodatkowe programy, kt�rych nie wymieniono w specyfikacji pakietu. Na przed- stawionym powy|ej wzorcu opisano je jako programy_prywatne. Kod ciaBa pakietu book zawiera jedn procedur� prywatn (private): CREATE OR REPLACE PACKAGE BODY book AS /* "prywatna" procedura u|ywana tylko w ciele tego pakietu */ PROCEDURE assert_notnull (tested_variable IN VARCHAR2) IS BEGIN IF tested_variable IS NULL THEN RAISE VALUE_ERROR; END IF; END assert_notnull; FUNCTION book_copy_qty(isbn_in IN VARCHAR2) RETURN NUMBER AS number_o_copies NUMBER := 0; CURSOR bc_cur IS SELECT COUNT(*) FROM book_copies WHERE isbn = isbn_in; BEGIN IF isbn_in IS NOT NULL THEN OPEN bc_cur; FETCH bc_cur INTO number_o_copies; CLOSE bc_cur; END IF; RETURN number_o_copies; END; PROCEDURE add(isbn_in IN VARCHAR2, title_in IN VARCHAR2, author_in IN VARCHAR2, page_count_in IN NUMBER, summary_in IN VARCHAR2, date_published_in IN DATE, barcode_id_in IN VARCHAR2) IS BEGIN assert_notnull(isbn_in); INSERT INTO books (isbn, title, summary, author, date_published, page_count) VALUES (isbn_in, title_in, summary_in, author_in, date_published_in, page_count_in); IF barcode_id_in IS NOT NULL THEN add_copy(isbn_in, barcode_id_in); END IF; END add; PROCEDURE add_copy(isbn_in IN VARCHAR2, barcode_id_in IN VARCHAR2) IS BEGIN assert_notnull(isbn_in); assert_notnull(barcode_id_in); INSERT INTO book_copies (isbn, barcode_id) VALUES (isbn_in, barcode_id_in); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN NULL; END; PROCEDURE change(isbn_in IN VARCHAR2, new_title IN VARCHAR2, new_author IN VARCHAR2, new_page_count IN NUMBER, new_summary IN VARCHAR2 DEFAULT NULL, new_date_published IN DATE DEFAULT NULL) IS BEGIN assert_notnull(isbn_in); UPDATE books SET title = new_title, author = new_author, page_count = new_page_count, summary = new_summary, date_published = new_date_published WHERE isbn = isbn_in; IF SQL%ROWCOUNT = 0 THEN RAISE NO_DATA_FOUND; END IF; END change; PROCEDURE remove_copy(barcode_id_in IN VARCHAR2) IS BEGIN assert_notnull(barcode_id_in); DELETE book_copies WHERE barcode_id = barcode_id_in; END remove_copy; PROCEDURE weed(isbn_in IN VARCHAR2) IS BEGIN assert_notnull(isbn_in); DELETE book_copies WHERE isbn = isbn_in; DELETE books WHERE isbn = isbn_in; IF SQL%ROWCOUNT = 0 THEN RAISE NO_DATA_FOUND; END IF; END weed; END book; / W powy|szym, do[ dBugim przykBadzie znajduje si� kilka dotd nie om�wionych konstrukcji, przy- kBadowo, konstrukcja SQL%ROWCOUNT. Zostan one jednak om�wione w dalszych rozdziaBach. Wi�kszo[ programist�w umieszcza programy w ciele pakietu w takiej samej kolejno[ci, jak w przy- padku specyfikacji (programy prywatne uwzgl�dnia si� na pocztku, gdy| ze wzgl�du na wymagania kompilatora ich definicja musi si� znajdowa przed ewentualnym wywoBaniem). W razie niezdefi- niowania kt�rej[ z jednostek programowych, wymienionych w specyfikacji, kompilator nie prze- prowadzi kompilacji, dop�ki bBd ten nie zostanie naprawiony. programy_prywatne s  prywatne w sensie dost�pno[ci jedynie z poziomu pakietu. Jego u|yt- kownicy nie mog bezpo[rednio wywoBywa |adnego z program�w prywatnych. Pozwala to na konstruowanie narz�dzi o specjalnym przeznaczeniu, kt�re b�d dost�pne tylko dla innych pro- gram�w, zdefiniowanych w ramach pakietu. W podanym wy|ej przykBadzie dodano tylko jedn, prost procedur� assert_notnull, kt�ra pozwala na niepowtarzanie kilku linii kodu w ka|dej definiowanej procedurze. U|ywanie takich lokalnych program�w cz�sto jest bardzo wygodne. Najcz�[ciej speBniaj one nast�pujce zadania: " sBu| jako dodatkowe metody, wykorzystywane przez inne programy zawarte w pakiecie; " pozwalaj na unikni�cie powtarzania tego samego kodu; " s dobr metod przechowywania lub zmieniania warto[ci pewnej zmiennej wewn�trznej. Z kolei programy, kt�re s wymienione w specyfikacji pakietu, mog by wywoBywane w dowol- ny spos�b i nazywa si� je programami publicznymi (public). Rysunek 3.7 przedstawia graficzn reprezentacj� por�wnania program�w publicznych z prywatnymi. Rysunek 3.7. Pakiety udostpniaj interfejs publiczny ukrywajcy wewntrzn implementacj Wielu programist�w nie dostrzega wa|no[ci zagadnieD zwizanych z wykorzystaniem program�w publicznych i prywatnych, mimo |e jest to jedna z technik pozwalajcych na tworzenie trwaBego, zrozumiaBego i Batwego do ponownego wykorzystania kodu. Informatycy, kt�rzy wszystkiemu na- daj pewne formalne nazwy, powiedzieliby, |e oznacza to tworzenie  abstrakcji (abstraction) ksi|ki poprzez ukrywanie informacji (information hiding)  patrz: sBowniczek. Poni|ej wymieniono najistotniejsze korzy[ci wynikajce z wykorzystywania pakiet�w: Organizacja Wi�kszo[ ludzi docenia dobre zorganizowanie dziaBania. Grupowanie powizanych ze sob jednostek programowych w pakiety pozwala na tworzenie kodu zorganizowanego w wygodne do stosowania struktury. U|ywajc terminologii fachowej mo|na powiedzie, |e pakiety pozwalaj na u|ycie mechanizm�w abstrakcji, enkapsulacji oraz ukrywania informacji. ZrozumiaBo[ Pakiety w ogromnym stopniu uBatwiaj zarzdzanie du| liczb jednostek programowych. Pewne badania z dziedziny psychologii dowiodBy, |e czBowiek w jednym czasie mo|e zajmowa si� jedynie okoBo siedmioma zagadnieniami. Oczywi[cie, nie zawsze mo|na ograniczy liczb� komponent�w pakietu do takiej liczby, ale ich grupowanie z pewno[ci uBatwia prac�. Mo|liwo[ci projektowe Rozwizanie skomplikowanego problemu odbywa si� zazwyczaj na drodze rozbicia go na mniejsze skBadowe. Dwa najpopularniejsze, zupeBnie od siebie r�|ne, sposoby rozwizywania tego problemu (czyli dekompozycji) to podej[cie funkcjonalne (functional) oraz obiektowe (object-based). Zastosowanie pakiet�w wspomaga obydwie te techniki projektowe. Wydajno[ Podczas pierwszego w danej sesji uruchomienia programu zapisanego w pakiecie system Oracle wczytuje do pami�ci caB zawarto[ pakietu, a nie tylko program wBa[nie wywoBany. Pozwala to na znaczce zwi�kszenie wydajno[ci wywoBania innych program�w pakietu, gdy| nie b�dzie konieczne korzystanie z danych zapisanych na wolniejszym dysku twardym. Z powy|szego jednocze[nie wynika, |e w pakiecie warto przechowywa tylko te komponenty, kt�re s ze sob zwizane. Wygoda pracy sesyjnej Czasem jest przydatna mo|liwo[ przechowywania w pami�ci pewnych tymczasowych lub staBych warto[ci w trakcie trwania sesji (przyj�to, |e sesj nazywa si� okres zalogowania u|ytkownika w systemie bazy danych). Dzi�ki wykorzystaniu pakiet�w warto[ci takie mo|na przechowywa w globalnych lub lokalnych zmiennych. Trzeba jednak pami�ta, |e cecha ta staje du|o mniej przydatna w przypadku aplikacji dziaBajcych w sieci Internet. Aplikacje te zazwyczaj nie s zale|ne od sesji  wi�cej informacji dotyczcych tego tematu znajduje si� w rozdziale 4. Bez zastosowania pakiet�w warto[ci takie musiaByby by przechowywane w samej bazie danych, co miaBoby niekorzystny wpByw na wydajno[ systemu. Problematyczne te| staBoby si� odwoBywanie si� do pewnej warto[ci po wycofaniu transakcji. Szczeg�lne cechy PL/SQL Jedn z najciekawszych mo|liwo[ci uzyskiwanych dzi�ki wykorzystaniu pakiet�w jest mo|liwo[ tworzenia wielu jednostek programowych o takiej samej nazwie. Pozwala to na wywoBywanie jednego programu, kt�ry mo|e obsBugiwa dane wej[ciowe o r�|nych typach. Zastosowanie tej techniki, zwanej przeci|aniem (overloading) i niedost�pnej dla program�w napisanych bez u|ycia pakiet�w, pozwala na uczynienie programu pozornie bardziej og�lnym. PrzykBadowo, funkcja TO_CHAR systemu Oracle jest przeci|ana w celu umo|liwienia przyjmowania parametr�w o r�|nym typie danych, na przykBad NUMBER lub DATE. Opis techniki przeci|ania oraz przykBadowy program znajduj si� w koDcowej cz�[ci niniejszego rozdziaBu, w podrozdziale  Uproszczenie poprzez przeci|enie . Mniejsze problemy z rekompilacj W du|ych systemach skBadajcych si� z dziesitk�w lub setek program�w du|ym problemem jest zazwyczaj rekompilowanie cz�[ci skBadowych programu po dokonaniu pewnych zmian. Dzi�ki pakietom mo|na unikn wielu trudno[ci dzi�ki temu, |e mo|na rekompilowa zawarto[ ciaBa pakietu bez konieczno[ci rekompilacji program�w, kt�re wykorzystuj zmodyfikowany program. W przypadku zmiany specyfikacji pakietu trzeba ju| jednak ponownie skompilowa ka|dy program uwzgl�dniony w pakiecie, ale cz�sto system Oracle robi to automatycznie. Usuwanie program�w magazynowanych Warto zwr�ci uwag, |e kod procedury add_book wprowadzony do pakietu nie r�|ni si od procedury oryginalnej poza zmienion nazw dodaj, gdy| bdzie ona stosowana tylko w kontek[cie pakietu book. Oryginalna procedura add_book wci| istnieje, ale mo|na j usun  po cz[ci dlatego, |e dziki wykorzystaniu pakietu procedura ta ju| nie jest potrzebna. Poni|ej zatem pokazano spos�b usuwania procedury. Odpowiedni instrukcj SQL, kt�ra w nieodwracalny spos�b usuwa procedur z bazy danych, jest instrukcja DROP PROCEDURE: DROP PROCEDURE add_book; Jest to instrukcja SQL, a nie PL/SQL. Std poni|szy spos�b wykonania: BEGIN DROP PROCEDURE add_book; /* nie zadziaBa w TYM miejscu */ END; spowoduje bBd kompilacji i wy[wietlenie komunikatu: drop procedure add_book; * BAD w linii 2: ORA-06550: linia 2, kolumna 1: PLS-00103: Napotkano symbol "DROP" gdy oczekiwano jednego z nastpujcych: ...ciach... Z powy|szego wynika, |e PL/SQL rzeczywi[cie nie jest peBnym nadzbiorem jzyka SQL. Po usuniciu procedury nie jest mo|liwe jej odzyskanie bez pomocy administratora bazy da- nych, kt�ry musi przeprowadzi pewne dziaBania zwizane z odzyskiwaniem danych. Je[li jednak istnieje plik zawierajcy kod zr�dBowy, mo|na po prostu utworzy ponownie dan procedur. W rzeczywisto[ci nie powinno si usuwa obiekt�w bazy danych bez upewnienia si, |e nie s ju| potrzebne  w przeciwnym wypadku wcze[niej czy p�zniej spowoduje to problemy. Dobrym zwyczajem jest przechowywanie specyfikacji oraz ciaBa pakietu w dw�ch oddzielnych plikach. W ten spos�b Batwo mo|na podda rekompilacji samo ciaBo po dokonaniu pewnych zmian. Niepotrzebne wykonanie instrukcji zawartych w specyfikacji pakietu sprawiBoby, |e nieaktualne staByby si� powizania innych program�w z pakietem, a zatem tak|e wymagana ich rekompilacja. Jak si� okazuje, istnieje wiele powod�w, dla kt�rych warto u|ywa pakiet�w. A zatem warto powr�- ci do zagadnieD zwizanych z programami testujcymi i umie[ci je w pakiecie. Poni|ej przedstawiono spos�b utworzenia kolejnego pakietu. Zorganizowanie procedur testowych w jednym pakiecie sBu|y ma gB�wnie w celu utrzymania porzdku w kodzie. Na tym etapie zostan pomini�te kwestie zwizane z wydajno[ci i kilkoma innymi zagadnieniami, kt�re om�wiono wcze- [niej. Pakiet testujcy zapewnia wygodny spos�b obsBugi, a jego struktura umo|liwia [wietn wsp�B- prac� ze struktur pakietu book, kt�rego budow� przedstawiono we wcze[niejszej cz�[ci niniejszego rozdziaBu. Poni|ej zamieszczono specyfikacj� omawianego pakietu: CREATE OR REPLACE PACKAGE test_book AS PROCEDURE run (verbose IN BOOLEAN DEFAULT TRUE); PROCEDURE add; PROCEDURE add_copy; PROCEDURE book_copy_qty; PROCEDURE change; PROCEDURE remove_copy; PROCEDURE weed; END test_book; / Ka|da jednostka programowa gB�wnego pakietu book posiada odpowiednik w pakiecie test_book, cho nie uwzgl�dniono |adnych parametr�w. Mo|na wywoBywa je pojedynczo lub wywoBa og�ln procedur� run, kt�ra uruchamia wszystkie pozostaBe. Posiada ona jeden opcjonalny parametr lo- giczny wskazujcy, czy maj by prezentowane szczeg�Bowe informacje dotyczce test�w. Opr�cz tego ka|da procedura zawiera kod sBu|cy do testowania. Je[li wszystko przebiega prawidBowo, przeprowadzenie testu z poziomu SQL*Plus wyglda na- st�pujco: SQL> SET SERVEROUTPUT ON SIZE 1000000 SQL> execute test_book.run Testing book package... ...add procedure, detection of NULL input: PASSED ...add procedure, book_record count: PASSED ...add procedure, book_copy record count: PASSED ...add procedure, book fetch matches insert: PASSED ...add procedure, book copy fetch matches insert: PASSED ...add procedure, detection of duplicate isbn: PASSED ...add_copy procedure, nominal case, first book: PASSED ...add_copy procedure, nominal case, second book: PASSED ...add_copy procedure, ignore duplicates: PASSED ...add_copy procedure, bad isbn detection: PASSED ...add_copy procedure, NULL isbn detection: PASSED ...add_copy procedure, NULL barcode_id detection: PASSED ...book_copy_qty function, zero count: PASSED ...book_copy_qty function, non-zero count: PASSED ...change procedure, single field test: PASSED ...change procedure, NULL barcode_id detection: PASSED ...remove_copy procedure, book count normal: PASSED ...remove_copy procedure, book copy count normal: PASSED ...remove_copy procedure, superfluous invocation: PASSED ...weed procedure, book count normal: PASSED ...weed procedure, book copy count normal: PASSED ...weed procedure, superfluous invocation: PASSED book package: PASSED Mo|na tak|e wyBczy tryb szczeg�Bowych komunikat�w, podajc warto[ FALSE przy wywoBa- niu procedury run. Odpowiednie polecenie przedstawiono poni|ej: SQL> SET SERVEROUTPUT ON SIZE 1000000 SQL> execute test_book.run(verbose => FALSE) book package: PASSED Omawiany pakiet jest zbyt obszerny, aby zamie[ci go w tym miejscu. Posiada on kilka udogodnieD w por�wnaniu do wersji pierwotnej. PeBna wersja omawianego pakietu znajduje si� pod adresem ftp://ftp.helion.pl/przyklady/orplsq.zip Odwiedzajc witryn� wydawnictwa O Reilly, Czytelnik mo|e tak|e zapozna si� z utPLSQL (http://oracle.oreilly.com/utplsql), darmow aplikacj sBu|c do te- stowania. By mo|e Czytelnik uwa|a, |e w tre[ci niniejszego rozdziaBu poBo|ono zbyt du|y nacisk na kwesti� testowania oprogramowania. Warto jednak u[wiadomi sobie, |e programowanie jest dziaBaniem ukierunkowanym na szczeg�By  u|ytkownicy aplikacji s bardzo wymagajcy i jakiekolwiek lekcewa|enie potencjalnych problem�w jest bardzo ryzykown postaw (istnieje tak zwany  styl programowania ekstremalnego 6 gloryfikujcy tak postaw�). A zatem program testowy nale|y two- rzy bardzo wcze[nie. Niekt�rzy uwa|aj, |e program testowy powinien by tworzony jeszcze przed napisaniem gB�wnej aplikacji. Zbyt dBugie zwlekanie z napisaniem programu testowego mo|e w efek- cie spowodowa, |e nigdy nie powstanie, a nawet je[li powstanie, ewentualna zwBoka mo|e unie- mo|liwi osigni�cie pewnych korzy[ci wynikajcych z testowania. My[lc o spodziewanych wy- nikach na wczesnym etapie tworzenia aplikacji Batwiej jest znalez bB�dy i naprawi je szybko i bez ponoszenia zb�dnych koszt�w. Pisanie dobrych program�w testowych nie jest zadaniem trywialnym. Dlatego wielu programist�w, piszcych aplikacje pod presj czasu, stwierdza, |e mo|e pomin ten etap. Warto jednak zapa- mi�ta nast�pujc dewiz�: Je[li nie ma czasu, aby wykona zadanie prawidBowo za pierwszym razem, to skd wzi czas, aby wykona je od nowa? Autorzy uwa|aj, |e aby zosta naprawd� dobrym programist, nale|y tworzy programy testowe. Taki spos�b post�powania umo|liwi sp�dzanie wi�kszej ilo[ci czasu na pisaniu nowych program�w, a mniej na usuwaniu bB�d�w w programach starych. Po zdobyciu pewnego do[wiadczenia w wykorzystywaniu procedur, funkcji i pakiet�w Czytelnik z pewno[ci zechce podnie[ poziom swojej pracy programistycznej. Poni|ej znajduje si� kilka po- rad i sugestii dotyczcych tego zagadnienia. 6 Wi�cej informacji na ten temat mo|na znalez w ksi|ce po[wi�conej tej tematyce, kt�rej autorem jest Kent Beck lub zajrze na witryn� http://www.extremeprogramming.org/. Przyj�cie odpowiedniego sposobu nazywania plik�w, kt�re zawieraj kod zr�dBowy tworzonych program�w, jest z pewno[ci bardzo wa|nym zagadnieniem. PrzykBadowo, w przypadku plik�w zawierajcych kod PL/SQL warto, aby rozszerzenie nazwy pliku odzwierciedlaBo jego zawarto[. W rozdziale 6. znajduje si� bardziej szczeg�Bowe om�wienie tego zagadnienia. Poni|ej podano jedy- nie kilka gB�wnych wytycznych: Wzorzec nazwy pliku Zawarto[ nazwa.pro (Pojedyncza) procedura magazynowana nazwa.fun (Pojedyncza) funkcja magazynowana nazwa.sql Blok anonimowy lub skrypt zawierajcy wiele blok�w, instrukcji SQL i (lub) poleceD SQL*Plus nazwa.pks Specyfikacja pakietu nazwa.pkb CiaBo pakietu W razie zastosowania powy|szych konwencji niekt�re z plik�w, kt�re wymieniono w niniejszym rozdziale, nosiByby nast�pujce nazwy: add_book.pro Procedura magazynowana add_book book_copy_qty.fun Funkcja magazynowana book_copy_qty test_add_book.sql Program testujcy dla add_book book.pks Specyfikacja pakietu book book.pkb CiaBo pakietu book Specyfikacja i ciaBo pakietu powinny by umieszczone w oddzielnych plikach. Czytelnik nie powinien sdzi, |e wydajno[ pracy programisty jest wprost proporcjonalna do liczby linii napisanego kodu. Dawno temu byB to pogld licznych teoretyk�w programowania. Jednak maBe jest pi�kne  programista powinien stara si� osiga du|y efekt kosztem maBego wysiBku. Oto pew- na historyjka: Pewien Prawdziwy Programista zdoBaB zmie[ci program dopasowywania do wzorca (pattern matching) w kilkuset kilobajtach nieu|ywanej pamici sondy Voyager, kt�rej zadaniem byBo odszukanie i sfotografowanie nowego ksi|yca Jowisza7. Bez wzgl�du na to, czy powy|sza anegdota jest prawdziwa czy nie, ka|dy programista powinien stara si� pisa kod zwi�zBy (ale nie niezrozumiaBy). Jednym ze sposob�w na osigni�cie tego celu jest projektowanie kodu mo|liwego do ponownego wykorzystania. Poni|szy przykBad umo|liwi zrozumienie problemu. 7 Fragment pochodzi z artykuBu  Real Programmers Don t Use PASCAL , Datamation, July 1983, s. 263  265. Poni|ej przedstawiono dziaBanie procedury reporteq. Wypisz opis testu. Por�wnaj warto[ oczekiwan z warto[ci otrzyman. Je[li obydwie warto[ci s r�wne, wypisz komunikat PASSED, je[li nie  FAILED. Poni|szy kod ju| byB omawiany w niniejszym rozdziale, ale zostaB powt�rzony dla zachowania przej- rzysto[ci wykBadu. CREATE OR REPLACE PROCEDURE reporteq (description IN VARCHAR2, expected_value IN VARCHAR2, actual_value IN VARCHAR2) AS BEGIN DBMS_OUTPUT.PUT(description || ': '); IF expected_value = actual_value OR (expected_value IS NULL AND actual_value IS NULL) THEN DBMS_OUTPUT.PUT_LINE('PASSED'); ELSE DBMS_OUTPUT.PUT_LINE('FAILED. Expected ' || expected_value || '; got ' || actual_value); END IF; END; / Program ten por�wnuje dwie zmienne typu VARCHAR2. Nast�pna funkcja, reporteqbool, po- siada identyczny pseudokod, ale jest przeznaczona do por�wnywania warto[ci logicznych typu BOOLEAN. Mo|na by dokona tylko drobnych modyfikacji w oryginale, jak pokazano w poni|szym fragmencie kodu: CREATE OR REPLACE PROCEDURE reporteqbool (description IN VARCHAR2, expected_value IN BOOLEAN, actual_value IN BOOLEAN) AS BEGIN DBMS_OUTPUT.PUT(description || ': '); IF (expected_value AND actual_value) OR (expected_value IS NULL AND actual_value IS NULL) THEN DBMS_OUTPUT.PUT_LINE('PASSED'); ELSE DBMS_OUTPUT.PUT_LINE('FAILED.'); END IF; END; / Nawet programista, kt�ry nie jest odpowiedzialny za oprogramowanie sondy Voyager, mo|e za- uwa|y, |e powy|szy kod charakteryzuje si� pewn nadmiarowo[ci. W razie konieczno[ci mody- fikacji dziaBania cz�[ci testujcej lub raportujcej (na przykBad w celu zapisania wszystkich opis�w i wynik�w testu w tabeli bazy danych) okazaBoby si�, |e trzeba wykona dwa razy wi�cej pracy. Problematyczne te| mo|e okaza si� okre[lenie dw�ch r�|nych miejsc, w kt�rych nale|y dokona zmian. Cz�sto takie zmiany s dokonywane przez kogo[ innego, ni| tw�rca oryginalnej wersji. Oso- ba taka mo|e nie by [wiadoma istnienia konieczno[ci zmodyfikowania kodu w dw�ch miejscach. W rezultacie powstanie niezgodno[, kt�rej wykrycie b�dzie kwesti przypadku. W j�zyku PL/SQL istnieje mo|liwo[ unikni�cia takiego problemu przez zmodyfikowanie drugiej procedury w taki spos�b, aby wywoBywaBa pierwsz. Aby to umo|liwi, nale|y przekonwertowa warto[ci logiczne BOOLEAN na VARCHAR2. Niestety, funkcja TO_CHAR nie obsBuguje zmiennych typu BOOLEAN. Mo|na jednak napisa wBasn funkcj� dokonujc tej konwersji. Zgodnie z obo- wizujcymi w systemie Oracle zasadami nadawania nazw funkcjom konwersji, jej nazw b�dzie booleantochar: CREATE OR REPLACE FUNCTION booleantochar(is_true IN BOOLEAN) RETURN VARCHAR2 AS BEGIN IF is_true THEN RETURN 'TRUE'; ELSIF NOT is_true THEN RETURN 'FALSE'; ELSE RETURN TO_CHAR(NULL); END IF; END booleantochar; / Teraz mo|na ju| zmodyfikowa procedur� reporteqbool w nast�pujcy spos�b: CREATE OR REPLACE PROCEDURE reporteqbool (description IN VARCHAR2, expected_value IN BOOLEAN, actual_value IN BOOLEAN) AS BEGIN reporteq(description, booleantochar(expected_value), booleantochar(actual_value)); END reporteqbool; / Najwa|niejsza kwesti, na kt�r nale|y zwr�ci uwag�, jest to, |e caBy kod zwizany z testowa- niem znajduje si� w procedurze reporteq. A zatem w razie konieczno[ci zmiany sposobu jej dziaBania wystarczy tylko zmieni kod jednego programu. Nawet je[li osoba zajmujca si� kon- serwacj danego kodu nie b�dzie wiedziaBa, kt�ry program nale|y zmieni, omawiany spos�b two- rzenia kodu umo|liwi jej szybkie zorientowanie si� w sytuacji. Nie jest to jednak ostatnia metoda uBatwiania sobie pracy. Mo|na upro[ci j jeszcze bardziej za pomoc techniki zwanej przeci|aniem (overloading). Czytelnik zapewne przypomina sobie, |e we wcze[niejszej cz�[ci niniejszego rozdziaBu opisano w skr�cie technik� przeci|ania. Opisano utworzenie procedury reporteq, kt�ra obsBuguje cigi znakowe oraz procedury reporteqbool, wykonujcej por�wnania na warto[ciach logicznych typu BOOLEAN. Prawdopodobnie potrzebna byBaby tak|e wersja obsBugujca daty  funkcja reporteqdate, i tak dalej. Zadania wykonywane przez te wszystkie programy byByby bardzo podobne. Warto zatem byBoby utworzy jeden program (lub przynajmniej zastosowa tylko jedn nazw� programu), kt�ry peBniBby funkcje wszystkich wy|ej wymienionych. PozwoliBoby to na prze- niesienie wielu obowizk�w u|ytkownika na program u|ytkowy. Im mniej nazw program�w trze- ba zapami�ta, tym lepiej. Technika przeci|ania sBu|y wBa[nie do osigni�cia tych cel�w. Uog�lniajc, przeci|enie proce- dury oznacza zdefiniowanie wi�cej ni| jednej procedury o tej samej nazwie. W ramach pakietu ma si� w�wczas dost�p do faktycznie czterech r�|nych procedur. Poni|ej znajduje si� przykBad wy- korzystania tej techniki w pakiecie zawierajcym zbi�r program�w testowych. Poni|ej przedsta- wiono kod przykBadowej specyfikacji pakietu: CREATE OR REPLACE PACKAGE tut AS PROCEDURE reporteq (description IN VARCHAR2, expected_value IN VARCHAR2, actual_value IN VARCHAR2); PROCEDURE reporteq (description IN VARCHAR2, expected_value IN NUMBER, actual_value IN NUMBER); PROCEDURE reporteq (description IN VARCHAR2, expected_value IN BOOLEAN, actual_value IN BOOLEAN); PROCEDURE reporteq (description IN VARCHAR2, expected_value IN DATE, actual_value IN DATE); PROCEDURE inna_procedura; END; / Poszczeg�lne procedury reporteq maj t sam nazw� i r�|ni si� tylko typami danych parame- tr�w. To jest cz�[  ukryta . Nale|y jeszcze zaimplementowa wszystkie cztery procedury w jed- nym ciele pakietu. Mo|na uwzgl�dni ich wzajemne wywoBywanie si�, co opisano we wcze[niej- szej cz�[ci niniejszego rozdziaBu. Autorzy pozostawili utworzenie ciaBa pakietu jako wiczenie dla Czytelnika. Ogromn zalet techniki przeci|ania jest to, |e u|ywajc takiej procedury lub funkcji PL/SQL, samodzielnie rozpoznaje ona, kt�r z nich nale|y wywoBa: DECLARE rozmiar_buta NUMBER; rezultat_szukania VARCHAR(64); BEGIN ... tut.reporteq('procedura flubber, wykrycie maksymalnego rozmiaru buta', expected_result => 15, actual_result => rozmiar_buta); tut.reporteq('procedura flubber, wyszukiwanie morsa', expected_result => 'Jestem morsem', actual_result => rezultat_szukania); END; Oznacza to, |e ka|de wywoBanie procedury reporteq zostaje dopasowane do odpowiedniej sytuacji. Istnieje kilka sytuacji, w kt�rych metoda przeci|ania nie umo|liwia prawidBowego dziaBania syste- mu. BBd jednak zostanie zwr�cony dopiero w czasie pr�by uruchomienia programu. Poni|ej wy- mieniono podstawowe zasady, kt�rych przestrzeganie pozwoli na prawidBowe dziaBanie mechani- zmu przeci|ania: 1. Przeci|ane programy musz posiada tak sam nazw� oraz znajdowa si� w tym samym pakiecie8. 8 Mo|na tak|e przeci|a programy doBczone w sekcji deklaracji. 2. Przeci|ane programy musz r�|ni si� albo liczb parametr�w, albo rodzajem typu danych parametr�w (uwzgl�dniajc pozycyjne por�wnanie). PrzykBadowo, w przypadku mechanizmu przeci|ania system bazy danych, kt�ry wykonuje program, nie mo|e stwierdzi r�|nicy pomi�dzy typami NUMBER a INTEGER, ale b�dzie to mo|liwe w przypadku typ�w NUMBER i VARCHAR2, gdy| nale| one do r�|nych rodzaj�w typ�w danych. 3. Procedura mo|e by przeci|ona funkcj, nawet je[li powy|sze dwa warunki nie s speBnione. 4. Przeci|ane funkcje musz si� r�|ni czym[ wi�cej, ni| tylko typem danych warto[ci zwracanej. W przypadku niespeBnienia kt�rego[ z wymienionych warunk�w zazwyczaj pojawia si� bBd wy- konania: PLS-00307: too many declarations of  <�nazwa podprogramu> match this call. W niniejszym rozdziale przedstawiono r�|ne porady dotyczce programowania obronnego. Ten styl pracy uwzgl�dnia mo|liwo[ wyst�powania najgorszych sytuacji. PrawidBowo napisany program powinien radzi sobie z bB�dnymi danymi wej[ciowymi nie dajc jednocze[nie bB�dnych danych wyj[ciowych. Istnieje co najmniej kilka mo|liwo[ci unikni�cia  syndromu bB�d�w na wyj[ciu . Niekt�re z nich zostaBy om�wione w trakcie omawiania sposobu tworzenia pakietu, kt�ry obsBuguje i chroni dane o ksi|kach przechowywane w bazie danych. Podsumowujc: " Nale|y zawsze pami�ta o tym, |e zmienne lub parametry PL/SQL mog mie warto[ NULL, co jest szczeg�lnie wa|ne w przypadku konstruowania instrukcji IF-THEN. " Nale|y wykorzystywa  obwoluty tabel i rozwija w sobie dyscyplin� potrzebn do u|ywania tej techniki. " Podczas deklarowania parametr�w program�w magazynowanych nale|y nadawa warto[ci domy[lne wsz�dzie tam, gdzie jest to uzasadnione. " Og�lnie rzecz biorc, nale|y korzysta raczej z notacji wymieniajcej ni| pozycyjnej, szczeg�lnie w sytuacji, gdy daje to dodatkowe informacje, kt�re nale|y uwzgl�dni. " Nale|y unika powtarzania tego samego kodu, w przeciwnym razie przyszBe jego modyfikacje b�d bardziej nara|one na powstawanie bB�d�w. " Nale|y organizowa kod w postaci pakiet�w, zamiast u|ywania wielu pojedynczych procedur i funkcji. " Nale|y obsBugiwa wyjtki tam, gdzie jest to uzasadnione oraz przechwytywa je w sytuacji, gdy istnieje mo|liwo[ zaistnienia problem�w, kt�rych tworzony program nie b�dzie rozwizywaB samodzielnie. " Nale|y korzysta z mechanizmu przeci|ania w celu zmniejszenia zBo|ono[ci aplikacji, upraszczajc tym samym przyszBy jej rozw�j. " Nale|y tworzy pewne programy testujce dla ka|dej z tworzonych jednostek programowych. W kolejnym rozdziale zostanie opisane rozszerzenie tworzonej aplikacji  na zewntrz , w kierun- ku u|ytkownika koDcowego poprzez utworzenie interfejsu u|ytkownika, sBu|cego do obsBugi nie- kt�rych z cech.

Wyszukiwarka

Podobne podstrony:
Oracle?tabaseg Programowanie w jezyku PL SQL or10ps
17 Procedury składowane w języku PL SQL (Oracle)
informatyka programowanie serwera oracle 11g sql i
Oracle?tabaseg Programowanie w jezyku PL SQL or11ps
Oracle8 Programowanie w jezyku PL SQL or8pls
SQL10G pl sql
kurs oracle podstawy sql
Linux Tablice informatyczne
informatyka windows 7 pl pierwsza pomoc adam jozefiok ebook
zasady sc i zasady etyki ksc tablica informacyjna

więcej podobnych podstron