Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00376 008933 10486900 na godz. na dobę w sumie
Oracle PL/SQL. Wprowadzenie - książka
Oracle PL/SQL. Wprowadzenie - książka
Autor: , Liczba stron: 440
Wydawca: Helion Język publikacji: polski
ISBN: 83-7197-727-1 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> bazy danych >> oracle - programowanie
Porównaj ceny (książka, ebook, audiobook).
PL/SQL -- język programowania systemu Oracle, przeznaczony do tworzenia procedur 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 struktury danych czy szerokie możliwości kontroli operacji transakcyjnych. Wszystkie z nich są ściśle zintegrowane z serwerem bazy danych Oracle.

'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 programistą. W niniejszej książce przedstawiono następujące zagadnienia:

'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 rozpoczyna pracę w języku PL/SQL.

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

IDZ DO IDZ DO PRZYK£ADOWY ROZDZIA£ PRZYK£ADOWY ROZDZIA£ SPIS TREĎCI SPIS TREĎCI KATALOG KSI¥¯EK KATALOG KSI¥¯EK KATALOG ONLINE KATALOG ONLINE ZAMÓW DRUKOWANY KATALOG ZAMÓW DRUKOWANY KATALOG TWÓJ KOSZYK TWÓJ KOSZYK DODAJ DO KOSZYKA DODAJ DO KOSZYKA CENNIK I INFORMACJE CENNIK I INFORMACJE ZAMÓW INFORMACJE ZAMÓW INFORMACJE O NOWOĎCIACH O NOWOĎCIACH ZAMÓW CENNIK ZAMÓW CENNIK CZYTELNIA CZYTELNIA FRAGMENTY KSI¥¯EK ONLINE FRAGMENTY KSI¥¯EK ONLINE Wydawnictwo Helion ul. Chopina 6 44-100 Gliwice tel. (32)230-98-63 e-mail: helion@helion.pl Oracle PL/SQL. Wprowadzenie Oracle PL/SQL. Wprowadzenie Autorzy: Bill Pribyl, Steven Feuerstein T³umaczenie: Bart³omiej Garbacz ISBN: 83-7197-727-1 Tytu³ orygina³u: Learning Oracle PL/SQL Format: B5, stron: 412 Przyk³ady na ftp: 118 kB PL-SQL — jêzyk programowania systemu Oracle, przeznaczony do tworzenia procedur 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 struktury danych czy szerokie mo¿liwoġci kontroli operacji transakcyjnych. Wszystkie z nich s¹ ġciġle zintegrowane z serwerem bazy danych Oracle. „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 programist¹. W niniejszej ksi¹¿ce przedstawiono nastêpuj¹ce zagadnienia: • 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; • tworzenie i wykorzystywanie procedur, funkcji oraz pakietów magazynowanych; • tworzenie aplikacji opartych na sieci Internet; • zabezpieczanie programów w jêzyku PL/SQL przed atakami z zewn¹trz; • korzyġci wynikaj¹ce z wykorzystania narzêdzi wspomagaj¹cych programowanie, • wykorzystanie jêzyka PL/SQL do programowania zadañ zwi¹zanych z u¿yciem poczty elektronicznej, jêzyka Java oraz sieci Internet. pochodz¹cych od innych dostawców; „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. 5RKUVTGħEK 9UVúR  Rozdział 1. 2.53.ōRKGTYU\GKPHQTOCELG  Podstawy języka PL/SQL ...................................................j...................................................j.. 19 Zalety języka PL/SQL ...................................................j...................................................j....... 27 Wymagania dotyczące stosowania języka PL/SQL ...................................................j............. 33 Rozdział 2. 2QFUVCY[  Podstawy składni ...................................................j...................................................j............... 38 Pierwszy program w PL/SQL...................................................j............................................... 40 Wprowadzenie do budowy programu...................................................j................................... 44 Zmienne ...................................................j...................................................j............................. 48 Podstawowe operatory...................................................j...................................................j....... 56 Wyrażenia warunkowe ...................................................j...................................................j......63 Instrukcje wykonywania w pętlach ...................................................j...................................... 67 Formatowanie kodu: wymagania i wskazówki ...................................................j.................... 73 Podstawy bardziej złożonych zagadnień ...................................................j.............................. 75 Rozdział 3. 2TQITCOQYCPKG   Informacje o programie przykładowym ...................................................j............................... 81 Pierwsze zadanie programistyczne...................................................j....................................... 83 Pobieranie informacji o liczbie książek za pomocą funkcji ...................................................j. 97 Tworzenie elastycznego kodu...................................................j............................................. 102 Wykorzystanie pakietów PL/SQL w celu organizacji kodu.................................................. 108 Przejście na wyższy poziom ...................................................j............................................... 117 Dalsza droga ...................................................j...................................................j.................... 122  5RKUVTGħEK Rozdział 4. +PVGTPGV  Wprowadzenie do HTML...................................................j...................................................j 124 Tworzenie stron internetowych za pomocą języka PL/SQL ................................................. 134 Inne zagadnienia ...................................................j...................................................j.............. 167 Rozdział 5. 2QDKGTCPKGFCP[EJ Wprowadzenie ...................................................j...................................................j................. 170 Prosta metoda: pobierania danych z jednego wiersza ...................................................j........ 170 Pobieranie wielu wierszy za pomocą kursora...................................................j..................... 172 Prezentowanie wyników zapytania na stronie WWW ...................................................j....... 184 Tworzenie strony WWW służącej do wyszukiwania za pomocą mechanizmu dynamicznego SQL ...................................................j.................. 188 Zaawansowane zagadnienia związane z pobieraniem danych .............................................. 205 Rozdział 6. 7VT\[O[YCPKGRQT\æFMW  Organizowanie kodu...................................................j...................................................j........ 215 Narzędzia pomagające w efektywnym programowaniu...................................................j..... 228 Rozdział 7. $G\RKGE\GēUVYQ  Podstawy bezpieczeństwa w systemie Oracle ...................................................j.................... 246 Organizowanie kont w celu zwiększenia poziomu zabezpieczeń ......................................... 255 Analiza wymagań systemu bibliotecznego...................................................j......................... 267 Śledzenie zmian w bazie danych ...................................................j........................................ 273 Szczególne kwestie bezpieczeństwa związane z programowaniem w PL/SQL ................... 281 Rozdział 8. -QOWPKMCELC\GħYKCVGO\GYPúVT\P[O Wysyłanie wiadomości pocztą elektroniczną za pomocą PL/SQL ....................................... 288 Wykorzystanie narzędzia służącego do wysyłania wiadomoścji elektronicznych w systemie bibliotecznym ...................................................j................................................ 293 Odbieranie wiadomości z poziomu bazy danych ...................................................j............... 296 Pobieranie danych ze zdalnych stron internetowych...................................................j.......... 305 Integracja z innymi językami programowania ...................................................j................... 317 Rozdział 9. 6TWFPKGLU\G\CICFPKGPKCKKPPGMYGUVKG Cykle istnienia oprogramowania ...................................................j........................................ 324 Listy obiektów (kolekcje) w języku PL/SQL ...................................................j..................... 326 Pakiety obsługi wyjątków...................................................j...................................................j 339 5RKUVTGħEK  Kontrola transakcji...................................................j...................................................j........... 343 Kompilator PL/SQL...................................................j...................................................j......... 349 Zarządzanie uprawnieniami czytelników i bibliotekarzy...................................................j... 352 Inne cechy PL/SQL...................................................j...................................................j.......... 372 2QUđQYKG Programowanie a bazy danych ...................................................j........................................... 381 Fakty ...................................................j...................................................j................................ 381 5đQYPKE\GM 5MQTQYKF\ 2TQITCOQYCPKG W niniejszym rozdziale omówiono następujące zagadnimenia: • Informacje o programie przykładowym • Pierwsze zadanie programistyczne • Pobieranie informacji o liczbie książek za pomocą feunkcji • 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ż zwykłe wyświetlanie komunikatu. W niniejszym rozdziale przedstawiono sposób rozpoczęcia tworzenia aplikacji obsługi 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 służą, jak je konstruować oraz w jaki spo- sób używać w celu osiągnięcia wymaganych celów. +PHQTOCELGQRTQITCOKGRT\[MđCFQY[O Przykładowe zadanie programistyczne, opisane w niniejszej książce, polega na próbie utworzenia systemu, który służyłby do katalogowania oraz wyszukiwania książek w bibliotece — jest to rodzaj elektronicznego katalogu. W przypadku tej hipotetycznej biblioteki zakłada się, że wszelkie dane operacyjne znajdują się w bazie danych Oracle. Istnieje więcej niż jeden sposób gromadzenia danych — dotyczących tytułów, autorów itp. — w bazie danych. Jednym z nich jest ręczne wpisywanie danych przez bibliotekarza. W kolejnych rozdziałach zostaną opisane metody automatycznego ła- dowania danych z odległych źródeł oraz metody wyszukiwania przez użytkownika danych znajdują- cych się w katalogu.  4Q\F\KCđ2TQITCOQYCPKG Istnieje konieczność spełnienia dwóch wymagań o podstawowym znaczeniu dla działania opisywa- nej aplikacji: • Należy umożliwić tworzenie wpisów do katalogu dla kaeżdej nowej książki. • Należy udostępnić możliwość określania liczby egzemplarezy danej książki, znajdujących się w zasobach biblioteki. W celu spełnienia pierwszego wymagania należy utworzyć procedurę PL/SQL, służącą do wprowa- dzania danych do bazy danych. Program umożliwiający spełnienie drugiego warunku wymaga za- stosowania funkcji PL/SQL. Przed opisaniem sposobu tworzenia tych elementów należy najpierw przedstawić metody projektowania struktury samej baezy danych. /QFGNFCP[EJ Podobnie jak w przypadku większości projektów tworzonych przez programistów PL/SQL, struktura bazy danych dotyczących książek w bibliotece została wcześniej zaprojektowana i utworzona na podstawie wymagań postawionych przez przyszłego użytkownika. Podzbiór logicznego projektu bazy danych, związany 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 związków encji (entity-relationship diagram, ERD). Rysunek 3.1. Zależność między wpisem (informacją) d.otyczącym książki a jej fizycznie istniejącymi egzemp.larzami Diagramy takie w zwięzłej i uproszczonej formie prezentują informacje o realnym świecie. Opisane w odpowiedni sposób prostokąty są encjami (entities) bazy danych, a linie pomiędzy nimi ozna- czają związki (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ą powiązania między obiektami). Encja book reprezentuje podstawowe informacje o książce (tytuł, autor itd.), które zawierea każda biblioteka. Encja book_copy zawiera informacje o fizycznie istniejących egzemplarzach daenej książki. Pewne zdziwienie może wywołać fakt, że całość rozdzielono na dwie encje zamiast użycia jednej. Wy- korzystanie tylko jednej encji spowodowałaby jednak problemy w późniejszym czasie, ponieważ wy- stąpiłaby konieczność kopiowania informacji dotyczących książki razem z informacjami dotyczącymi jej pojedynczych egzemplarzy, co z pewnością byłoby niewłaściwym sposobem wykorzystania zaso- bów komputera i wysiłku ludzkiego. Pełna 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 głó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 zawierającego identyfikator, który w powyższym przy- padku jest numerem identyfikacyjnym pochodzącym z seamoprzylepnej naklejki z kodem kreskowym. 2KGTYU\G\CFCPKGRTQITCOKUV[E\PG  W tym miejscu należy wyjaśnić znaczenie linii przedstawiających relację, pokazaną na rysunku 3.1. Z treści tego rysunku wynikają następujące fakty dotyeczące realnej sytuacji: • Każdy egzemplarz danej książki jest egzemplarzem tyeko jednej książki. • Każda książka może posiadać jeden lub większą liczbę sewoich 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 przystąpieniem do właściwego projektowa- nia bazy danych należy dokonać analizy rozwiązywanegeo problemu na takim właśnie, podstawowym poziomie. Rozłożenie informacji dotyczących projektowanej aplikacji na szereg pozornie banalnych faktów i ustalenie wszystkich podstawowych związków pomiędzy jej elementami z pewnością ułatwi pracę podczas tworzenia kodu programu. 2TQLGMVQYCPKGHK\[E\PGLUVTWMVWT[DC\[FCP[EJ Faktyczna struktura bazy danych odzwierciedla model związków encji — każda encja odpowiada ta- beli w bazie danych. Poniżej przedstawiono kod w języku SQL, służą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) REFEREoNCES books (isbn) ); Z powodów zrozumiałych 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ć zdefiniowanyceh tabel zapełnionych pewnymi danymi. Zapoznawszy się z danymi zawartymi w tabelach, Czytelnik z pewnością zwrócił uwagę na pewne problemy. Przykładowo, dane w kolumnie author są nieprawidłowe 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. 2KGTYU\G\CFCPKGRTQITCOKUV[E\PG Pierwszym, przykładowym zadaniem będzie utworzenie programu w języku PL/SQL, który posłu- ż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:  4Q\F\KCđ2TQITCOQYCPKG Rysunek 3.2. Przykład danych w postaci relacyjnej, rozbi.tych na wiersze i kolumny INSERT INTO books (isbn, title, author) VALUES ( 0-596-00180-0 , Oracle PL/SQL. Wprowadzenie , Bill Pribyl, Steven Feuerstein ); W związku z powyższym Czytelnik z pewnością zastanawia się nad sensem tworzenia programu w języku PL/SQL. 7\CUCFPKGPKGRTQLGMVW Należy założ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, pobierając 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óźniej może pojawić się potrzeba napisania trzeciego programu, który dodawałby informacje o książ- kach, przykładowo, odczytując je z płyty CD-ROM. A zatem należałoby uwzględnić kolejne ko- piowanie instrukcji INSERT. Zakładając jednak, że zaistnieje potrzeba zmiany struktury tabel, trzeba by wówczas wszystkie dotąd utworzone programey 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ęcezącej pracy związanej z aktualizacją oprogramowania po zmianie struktury bazy danych, podeczas wykonywania której istnieje możliwość popełniania błędów. 2KGTYU\G\CFCPKGRTQITCOKUV[E\PG  • Pozwala to na zwiększenie wydajności działania serweera bazy danych. • Pozwala to umieścić rozwiązanie problemu programistyecznego w tylko jednym miejscu. Tworzenie poprawnych instrukcji w języku SQL może wymagać interpretowania oraz zapisywa- nia w formie kodu wielu skomplikowanych reguł zarządzania. Ewentualna konieczność dokonania zmian we wszystkich napisanych programach oddzielnie oznacza bezzasadne marnotrawstwo cza- su i wysiłku. Ogólna zasada mówi, że: Instrukcje SQL należy umieszczać w jednym, możliwym do fwielokrotnego wykorzystania, programie napisanym w języku PL/SQL, a nie kopiować je w fwielu 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 wywoływać, można utworzyć własny interfejs tworzenia oprogramo- wania (application programming interface, API). Tak prosty, jak to możliwe, ale nie prostszy Prawdziwy bibliotekarz uznałby niniejszy model za banalnie prosty, nawet nie biorąc pod uwagę nie uwzględnionych w nim kwestii związanych zb 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 dzieł, na przykład starsze książki, nie posiada numeru ISBN (International Standard Book Number), co ogranicza jego zastosowanie jako jednoznacznego identyfikatora. • Dzieła mogą mieć różne tytuły i wielu autorów. • Należy przechowywać o wiele więcej informacji: o działach, wydawcach, ilustratorach, wydaniach, dziełach wielotomowych i pochodnych. • Biblioteki zazwyczaj udostępniają sobie nawzajem swoje katalogi drogą elektronicznej wymiany. Podobnych przykładów jest więcej, dlatego należy wyjaśnić powody uwzględnienia w niniejszej książce tak prostego przykładu. Wykonanie bazy danych, której schemat pokazano na rysunku 3.1, w zasadzie jest zbyt skom- plikowanym zadaniem dla zupełnie początkujących programistów. Relacja jeden do wielu stanowi podstawę większości aspektów projektowania baz danych (tyle że w realnych sytuacjach chodzi o wiele takich relacji) oraz programowania w języku 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 uproszczeń jest fakt, że nauka nowego materiału przychodzi najłatwiej, jeśli można studiować jedno zagadnienie w jednym czasie. W przeciwnym razie nauka przychodzi dużo trudniej.  4Q\F\KCđ2TQITCOQYCPKG 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ście każdej z tabel bazy danych. +FGPV[HKMCELCFCP[EJYGLħEKQY[EJRTQEGUWRT\GVYCT\ECPKC QTC\FCP[EJY[LħEKQY[EJ Zapewne większość programistów, niezależnie od stopnia zaawansowania, odczuwa niepewność w sytuacji, gdy ma napisać program od podstaw. Z reguły w takiej sytuacji można rozpocząć pracę od przerabiania już istniejących lub przykładowych programów. W tym przypadku zostanie przed- stawiony sposób tworzenia programu od samego początku, 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 służącego do dodawania ks.iążek do bazy danych W przeciwieństwie do wcześniej prezentowanego diagramu związków i encji, powyższy diagram nie został skonstruowany zgodnie z jakimiś zasadami projektowania. Najważniejszą rzeczą jest przedstawienie najbardziej znaczących 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 przyszłości. Ogólnie rzecz biorąc, jednostka programu powinna służfyć do wykonania jednego, konkretnego zadania i należy zapewnić prawidłowe działanie tej jedfnostki w swoim zakresie. Wskazane jest, aby miała on niewielki rozmiar — ułatwi to jej zapis i późniejsze modyfikacje. Trzeba jeszcze znaleźć odpowiedź na pytanie, jakiej konstrukcji języka PL/SQL należałoby użyć w celu zdefiniowania operacji dodawania książki add_book. Z uwagi na fakt, że program nie bę- dzie zwracał żadnej wartości, najbardziej rozsądnym rozwiązaniem jest zastosowanie procedury. 2KGTYU\G\CFCPKGRTQITCOKUV[E\PG  CUVQUQYCPKGRTQEGFWT[OCIC\[PQYCPGLYEGNWFQFCPKCEMUKæľMK 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żywając terminologii pochodzącej 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 Słowniczku. Na rysunku 3.4 przedsta- wiono więcej szczegółów dotyczących takiego rozwiązania. Rysunek 3.4. Jedynie z poziomu programu PL/SQL będzie możl.iwe 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ę dotyczącą struktury bazy danych. Dlatego też pierwszą rzeczą, jaką należy wykonać, jest określenie tabel i ich kolumn związanych z procesem wykonania reguły zarządzania (w tym przypadku – dodania książki). Trzeba odpowiedzieć sobie na pytanie, jakie informacje są potrzebne do manipuloweania zawartością tych tabel. #PCNK\CRTQLGMVW 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 rozdziału). Listę tych kolumn można z łatwością utworzyć za pomocą instrukcji DESCRIBE, dostępnej w SQL*Plus (w for- mie skróconej DESC): SQL DESC ksiazki Name Null? Toype -------------------------------------------- -------- ----------------------- ISBN NOT NoULL VARCHAR2(13) TITLE o VARCHAR2(200) SUMMARY o VARCHAR2(2000) AUTHOR o VARCHAR2(200) DATE_PUBLISHED o DATE PAGE_COUNT o NUMBER SQL DESC egzemplarze_ksiazki Name Null? Toype -------------------------------------------- -------- ----------------------- BARCODE_ID NOT NULoL VARCHAR2(100) ISBN o VARCHAR2(13) Po przeanalizowaniu listy kolumn można przyjąć, że większość zawartych w nich informacji powin- na być znana osobie wykonującej katalogowanie i dlatego nie trzeba niczego syntetyzować, spraw- dzać lub obliczać. Procedura będzie więc bardzo prosta.  4Q\F\KCđ2TQITCOQYCPKG Podstawowym problemem do rozwiązania jest podjęcie decyzji, czy użytkownik będzie wstawiał dane do obydwóch tabel jednocześnie, czy też oddzielnie. Na tym etapie pracy odpowiedź 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 wypełnienia 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ż znajdującej się w zbiorach biblioteki — tę potrzebę również należy uwzględnić podczas pla- nowania programu. Rozpoczynając opracowywanie nowego projektu wielu programistów zapisuje tzw. pseudokod w postaci zwykłych zdań, które opisują z grubsza działanie programu. W tym przypadku można by napisać: Sprawdź, czy dane wejściowe są prawidłowe. Wstaw nowy rekord do tabeli books . Wstaw nowy rekord do tabeli book_copies . Kolejnym etapem będzie przedstawienie składni konstrukcji językowych potrzebnych do utworze- nia procedury. Następnie zapisany pseudokod zostanie ezamieniony na konkretne instrukcje. 5MđCFPKCVYQT\GPKCRTQEGFWT[ Poniżej znajduje się opis różnych części składowych procedury. Zazwyczaj procedury tworzy się za pomocą instrukcji o następującej składni: 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_wyjątku THEN instrukcje_wykonawcze ] END; / Powyższy wzorzec zawiera kombinację słów kluczowych języka PL/SQL (pisane dużymi literami i nie kursywą) oraz wyrażeń do zastąpienia (pisane kuersywą) w kodzie tworzonego programu. CREATE [ OR REPLACE ] Jest to szczególna instrukcja SQL, służąca do utworzeneia procedury. Fraza OR REPLACE (lub zastąp) jest opcjonalna i pozwala na uniknięcie koniecznoścei usuwania już istniejącej procedury w przypadku tworzenia jej nowej wersji. Zastosowaniee wyrażenia OR REPLACE zachowuje także wszelkie synonimy (synonyms) oraz granty (grants), jakie zostały uprzednio utworzone, a są zależne od działania procedury. Jest to duża zaeleta. 2KGTYU\G\CFCPKGRTQITCOKUV[E\PG  PROCEDURE nazwa_procedury W sekcji nagłówka podaje rodzaj tworzonej jednostkie 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 wywołania procedury, należy utworzyć listę definicji parametrów oddzielonych przecinkami, ea całą listę objąć w nawiasy. TRYB może mieć wartość: IN, OUT lub IN OUT. Poniżej znajduje się opis wszystkich opcji. IN Słowo kluczowe oznaczające tryb tylko do odczytu. Wyewołujący procedurę podaje wartość parametru, a PL/SQL nie pozwala na jej zmianę wewnątrz perogramu. OUT Słowo kluczowe oznaczające tryb tylko do zapisu. Oznaecza to, że procedura nadaje parametrowi pewną wartość, która jest odczytywana przeez program wywołujący. Podanie jakiejkolwiek wartości takiego parametru podczas wyewołania procedury jest ignorowane. IN OUT Słowo kluczowe oznaczające tryb do odczytu lub zapiesu. Słowo to jest używane w sytuacji, gdy wartość zmiennej, przekazywanej do procedury jakoe parametr, ma być zarówno odczytywana, jak i zmieniana, a następnie zwracana doe programu wywołującego. TYP_DANYCH Znaczenie tego parametru przedstawiono w rozdziale e2. — dopuszczalnymi wartościami są na przykład: NUMBER, INTEGER, VARCHAR2, DATE. Jedyna różnica polega na tym, że w tym miejscu należy podać jedynie rodzaj typu, bez jego dokładnej specyfikacji. Innymi słowy, należy użyć VARCHAR2 zamiast VARCHAR2(30) i NUMBER zamiast NUMBER(10,2). DEFAULT wyrażenie Pozwala na przypisanie parametrowi wartości domyślneej w przypadku, gdy wywołanie procedury jej nie określa. Można także użyć symbolu „:=” (dwukropek i znak równości) zamiast słowa kluczowego DEFAULT. AS Słowo kluczowe AS oddziela nagłówek od reszty jednostki programowej.e Opcjonalnie można użyć słowa kluczowego IS, które jest równoważne AS. BEGIN..END Słowa BEGIN i END oddzielają zwykłe, czyli wykonawcze instrukcje od ereszty programu. EXCEPTION Oznacza początek kodu obsługi wyjątku — tej części proegramu, która jest wykonywana tylko w przypadku przechwycenia wyjątku w sekcji wykonawcezej. Wszystkie elementy umieszczone po słowie kluczowym EXCEPTION i przed instrukcją END są częścią obsługi wyjątku.  4Q\F\KCđ2TQITCOQYCPKG WHEN nazwa_wyjątku THEN instrukcje_wykonawcze Możliwym do wystąpienia sytuacjom błędnego działaniae programu zazwyczaj są nadawane nazwy — albo przez system Oracle, albo przez programiestę. Dzięki temu można w kodzie programu zapisać instrukcje „wychwytujące” te sytuacjee i umożliwić odpowiednią na nie reakcję, którą jest wykonanie pewnego fragmentu kodue. Jeśli taka nazwa jest nieznana lub w celu wychwytywania błędów, które nie zostały nazwanee, można posłużyć się słowem OTHERS, które dotyczy wszystkich sytuacji wyjątkowych. W zaepisie wyglądałoby to następująco: WHEN OTHERS THEN.... Pewne elementy kodu procedury są opcjonalne. Najprostsza, możliwa do utworzenia procedura po- siada następującą formę: CREATE PROCEDURE nie_rob_nic AS BEGIN NULL; END; Z powyższego wynika, że parametry, zmienne i kod obsłeugi wyjątków są opcjonalne. Słowo kluczowe NULL zostało tutaj zastosowane jako instrukcja wykonawceza. Oznacza ona tyle, co „nie rób nic”. 2TQEGFWTCCFFADQQM Korzystając 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 VARCHAoR2, barcode_id_in IN VARCHAR2, title_in IN VARCHAR2, author_in oIN VARCHAR2, page_count_in IN NUMBER, summary_in IN VARCHAR2 DEFAULT NULLo, 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,o page_count) VALUES (isbn_in, title_in, summary_in, author_in, date_published_in,o 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; / 2KGTYU\G\CFCPKGRTQITCOKUV[E\PG  Poniżej znajduje się opis działania utworzonej proceedury. Nazwa procedury i kolejność parametrów. Nazwą procedury jest wyrażenie czasownikowe, które opisuje działanie 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 końcu, 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ą końcówkę _in. Taka konwencja nadawania nazw nie jest obowiązkowa, ale jest pomocna w unikaniu konfliktów z na- zwami kolumn podczas używania instrukcji SQL. Gdyby pozostały one identyczne, otrzymana in- strukcja miałaby następującą 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 mogłoby okazać się problematyczne nawet dla doświadczonego programisty. Jednakże sama in- strukcja zostałaby wykonana prawidłowo, gdyż PL/SQL zineterpretowałby wszystko następująco: INSERT INTO book_copies (barcode_id, isbn) /* nazwy kolumn */ VALUES (barcode_id, isbn); /* zmienne PL/SQLo */ Jednakże instrukcja: UPDATE ksiazki SET summary = summary /* Błąd! */ WHERE isbn = isbn; /* Nie wolno tak robić! */ nie zostanie wykonana prawidłowo. PL/SQL zinterpretuje każde wystąpienie summary oraz isbn jako nazwy kolumn. Weryfikacja danych wejściowych. Zapis pierwszej linii zaprezentowanego wcześniej pseudoko- du mówił: „Sprawdź, czy dane wejściowe są prawidłowe”. Konieczne jest jednak podjęcie jeszcze kilku ustaleń. Przykładowo, można założyć, że użytkowneicy systemu będą domagać się minimalnych wymagań ze strony procedury w momencie jej wywoływania. Może to oznaczać, że jedynym ab- solutnie wymaganym parametrem tworzonej procedury jest ISBN. Stąd też sekcja weryfikacji da- nych wejściowych została zapisana jako: IF isbn_in IS NULL THEN RAISE VALUE_ERROR; END IF; Bez dokładniejszej 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 wykonywaniae programu.  4Q\F\KCđ2TQITCOQYCPKG W dalszej części kodu jest także wykonywane sprawdzenie kodu kreskowego. Program został skon- struowany w ten sposób, aby uniknąć wykonania niepoprawnej instrukcji INSERT, co spowodo- wałoby błąd. 1DUđWICU[VWCELKY[LæVMQY[EJ W rozdziale 2. wyjaśniono, że w razie wystąpienia błędu PL/SQL zatrzymuje wykonywanie progra- mu za pomocą mechanizmu zwanego przechwytywaniem wyjątku (raising an exception). Jak wy- nika z rysunku 3.5, instrukcja: RAISE VALUE_ERROR zatrzymuje wykonywanie instrukcji sekcji wykonawczej i przekazuje sterowanie do kodu obsługi wyjątku. Jeśli taki kod nie istnieje, wyjątek zwraca pewien błąd do programu wywołującego, a ten reaguje w określony przez programistę sposób. Rysunek 3.5. Prosty przykład obsługi wyjątku Wyjątek VALUE_EXCEPTION należy do grupy wyjątków wewnętrznych, które w pewnych sytu- acjach są przechwytywane przez system Oracle. Program wywołujący procedurę add_book po- winien umożliwiać obsługę wszelkich możliwych do przewidzenia wyjątków i na podstawie infor- macji dotyczących napotkanego błędu zdecydować o dalszym funkcjonowaniu programu. W tym przypadku pożądanym działaniem byłoby przerwanie procesu dodawania do bazy danych niekom- pletnych informacji. Najlepiej byłoby, gdyby program wywołujący zwracał użytkownikowi infor- mację o błędzie. Być może Czytelnik zastanawia się na celowością podejmowania takich działań zamiast, przykła- dowo, umożliwienia samej procedurze add_book wyświetlania komunikatu o napotkanym błę- dzie. Celowość użycia mechanizmu wyjątków staje się jasna po uświadomieniu sobie, że przeka- zanie obsługi sytuacji wyjątkowych do procedury ograniczyłoby w znacznym stopniu możliwości jej ponownego wykorzystania. Jeśli procedura add_book obsługuje wyjątek i wyświetla komunikat o błędzie, niemożliwe jest wykorzystanie jej przez program, dla którego działania takie komuni- katy są niewskazane. Przykładowo, można założyć istnienie programu, który odczytuje informacje o książkach z pliku i jednorazowo wprowadza do bazy danych informacje dotyczące tysięcy książek. 2KGTYU\G\CFCPKGRTQITCOKUV[E\PG  Program ten ma wywoływać procedurę add_book dla każdej kolejnej pozycji i w razie wystą- pienia błędu zapamiętać informację o jego przyczynie, nie przerywając jednak swojego działania, aż do zakończenia wprowadzania danych dotyczących 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ę wyjątków na ze- wnątrz — do programu wywołującego. Uogólniając, jeśli istnieje prawdopodobieństwo napoątkania przez program błędu, którego nie da się naprawić w prosty sposób, należy zapewniąć możliwość przechwycenia wyjątku. W dalszej części niniejszej książki opisano wyjątki,ą które należy brać pod uwagę. Jeżeli weryfikacja poprawności danych wejściowych przebiega pomyślnie, program kontynuuje swoje działanie wykonując instrukcje INSERT języka SQL. Nie ma potrzeby zwracania jakichkolwiek danych do programu wywołującego. Jednak gdyby zaszła 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ęścei niniejszego rozdziału. 7ľ[EKGRTQEGFWT[YEGNWFQFCPKCMUKæľMKFQMCVCNQIW Najłatwiejszym sposobem wywołania procedury z poziomu kodu PL/SQL jest napisanie jej nazwy wraz z potrzebnymi argumentami, umieszczonymi w naweiasach i oddzielonymi przecinkami: BEGIN nazwa_procedury (argument1, argument2, ...); END; Przykładowo, aby dodać do katalogu nową książkę, należey napisać: BEGIN add_book( 1-56592-335-9 , 100000001 , Programowanie w Oracle PL/SQL , Feuerstein, Steven, Bill Pribyl , 987, Kompendium informacji o języku PL/SQL, || wraz z przykładami i poradami na temat programowania. , TO_DATE( 01-WRZ-1997 , DD-MON-YYYY )); END; / Takie wywołanie procedury spowoduje wstawienie po jednym rekordzie do tabel books oraz book_ copies. W powyższym przykładzie 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 wywoływanym. Informacje te przedstawiono w poniższej tabeli: 1 Wyrażenie przekazywane przez program wywołujący nosią nazwę argumentu lub parametru aktualnego, podczas gdy zmienne zdefiniowane w nagłówku programąu wywołującego są nazywane parametrami formalnymi lub po prostu parametrami. W tym kontekście „formalny” oznacza „formujący” postać zmiennej.  4Q\F\KCđ2TQITCOQYCPKG Pozycja Nazwa parametru Typ danych parametru Wartość użyta w przykładowym wywołaniu 1 2 3 4 5 6 7 isbn_in VARCHAR2 1-56592-335-9 barcode_id_in VARCHAR2 100000001 title_in author_in VARCHAR2 Programowanie w Oracle PL/SQL VARCHAR2 Feuerstein, Steven, Bill Pribyl page_count_in NUMBER 987 summary_in VARCHAR2 Kompendium informacji o języku PL/SQL wraz z przykładami i poradami na temat programowania. date_published_in DATE TO_DATE( 01-WRZ-1997 , DD-MON-YYYY ) 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 ciąg znakowy, parametrowi typu NUMBER odpowiada seria cyfr. Czytelnik zapewne zauważył, że parametrowi typu DATE odpo- wiada wartość o dość dziwnym wyglądzie. 2TCEC\V[RGO #6 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, miesiąca i dnia. Często stosowaną metodą otrzymania takiej wartości jest wykorzystanie wewnętrznej funkcji systemu Oracle o nazwie TO_DATE. Podczas wywoływania tej funkcji należy podać datę, zapisaną w formie ciągu 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 ciągu znaków z odpowiednimi elementami maski formatującej. 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 wyjąetku. Wróćmy do omawianego przykładu: 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 literałów jest równie dobrym roz- wiązaniem, co uwzględnienie wyniku działania funkcjie, takiej jak na przykład TO_DATE. Zastosowanie funkcji TO_DATE nie zawsze jest konieczne, ponieważ system Oracle automatycznie podejmuje próbę konwersji ciągu znakoąwego na datę. W sytuacji takiej trzeba opierać się na domyślnej masce formatu systemu Oracląe, która może zostać zmieniona przez administratora bazy danych. Zwiększa to prawdopodobieąństwo wystąpienia pewnych problemów, jak na przykład interpretacja wartości rąoku (jaki rok jest oznaczony wartością 00 ?). Ogólnie można powiedzieć, że w celu konwersji na formaąt daty systemu Oracle należy skorzystać z funkcji TO_DATE. 2KGTYU\G\CFCPKGRTQITCOKUV[E\PG  Powyższy fragment kodu zawiera argumenty podane w formie literałó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 wywoła- niach. Wartości zmiennych są zazwyczaj ustalane nie poprzez bezpośredni zapis w kodzie programu, ale na przykład przez użytkownika korzystającego z klawiatury i ekranu, wyświetlającego odpowied- nie informacje. #TIWOGPV[QRELQPCNPG Warto się zastanowić nad sposobem wywoływania procedury w przypadku posiadania niepełnej informacji dotyczącej dodawanej książki — na przykład w przypadku braku daty wydania lub opisu. Przykładowo, w takim przypadku można podać wartości NULL dla tych parametrów i sprawdzić, czy nie spowoduje to problemów z wykonywaniem programu:e2 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 wywołanie poprawne, gdyż w sekcji nagłó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 pełni poprawnymi wartościami. Korzystając z wartości domyślnych, można przedstawione powyżej wywołanie 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 brakujących 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 posiadąających wartość domyślną jest niezwykle przydatną cechą języka PL/SQL, ponieważ umożliwąia prawidłowe działanie jednostki programowej nawet bez podania tych argumeąntów. Ponadto mechanizm ten może w ogromnym stopniu zredukoąwać negatywny wpływ ewentualnych, przyszłych modyfikacji. Przykładowo, jeśąli zaistnieje potrzeba dodania do programu pewnych parametrów, to dzięki zdefiniowaąniu ich wartości domyślnych nie będzie trzeba przeglądać całego kodu, aby zmienić kąażde występujące w nim wywołanie. 2 Ze względu na oszczędność miejsca w niniejszej ksiąążce nie zawsze jest przedstawiany pełny kod programąu. W tym przypadku należałoby dodać instrukcję EXECUTE lub oąbjąć wywołanie słowami kluczowymi BEGIN i END oraz dodać końcowe “/” w celu uruchomienia tej procedury z poziomu SQL*Plus.  4Q\F\KCđ2TQITCOQYCPKG Warto też wiedzieć, że wywołując procedurę można jednocześnie pomijać parametry posiadające 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. 0QVCELCKOKGPPC Rozwiązaniem tych problemów może być zastosowanie innego, bardzo użytecznego mechanizmu — notacji imiennej (named notation). Sposób działania notacji imiennej najlepiej można wyjaśnić na przykładzie. W przypadku poniższego wywołania preocedury add_book wykorzystano właśnie ten mechanizm: add_book(isbn_in = 1-56592-335-9 , title_in = Programowanie w Oracle PL/SQL , summary_in = Kompendium informacji o języku PL/SQL, || wraz z przykładami 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 całkowicie zależy od programisty — dla kompilatora jest to bez znaczenia. Argu- mentem przemawiającym 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 wąt- 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ć, przykładowo, date_published_in: add_book(isbn_in = 1-56592-335-9 , title_in = Programowanie w Oracle PL/SQL , summary_in = Kompendium informacji o języku PL/SQL, || wraz z przykładami 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ść, wynikająca ze stosowania tej notacji. W razie potrzeby zmiany nazwy parametru konieczne jest uaktualnienie nie tylko samej procedury, ale także każdego jej wywołania w notacjiimiennej. Z drugiej jednak stro- ny zmiana nazwy parametru jest raczej rzadko wykonyewaną operacją. 2QDKGTCPKGKPHQTOCELKQNKE\DKGMUKæľGM\CRQOQEæHWPMELK  Istnieje także możliwość wykorzystania obydwóch notacji w jednym wywołaniu. 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 końca. Oto przykład: 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ę wymieniającą wszędzie tam, gdzie znaczenie poszczególnych argumentów nie jest obczywiste. Przykładowo: uaktualnij_moj_profil(ulub_ksiazka_isbn = 1-56592-335-9 ); Notacji pozycyjnej należy używać w przypadku często używanych programów użytkowych, które posiadają jeden lub dwa parametry, a znaczenibe tych parametrów jest oczywiste: DBMS_OUTPUT.PUT_LINE( Witaj Muddah. ); Zastosowanie obydwóch notacji może okazać się przydatne w sytuacji, gdy na przykład pierwszy argument jest oczywisty, zaś kolejne nie: moje_put_line( Witaj Fadduh. , linie_do_pominiecia = 2); W tym podrozdziale przedstawiono przykład 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 końcezy działanie nie obsłużonym wyjątkiem). 2QDKGTCPKGKPHQTOCELKQNKE\DKGMUKæľGM \CRQOQEæHWPMELK Przed podjęciem próby zapisania kodu funkcji trzebae najpierw zapoznać się z ogólną składnią two- rzenia funkcji. Funkcje stanowią drugi typ programówe magazynowanych. 5MđCFPKCVYQT\GPKCHWPMELK 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  4Q\F\KCđ2TQITCOQYCPKG [ zmienna1 TYP_DANYCH; zmienna2 TYP_DANYCH; ... ] BEGIN instrukcje_wykonawcze; RETURN wyrażenie; [ EXCEPTION WHEN nazwa_wyjątku THEN instrukcje_wykonawcze ] END; / Różnice pomiędzy wzorcem dotyczącym funkcji i wzorcem procedury są minimalne. Poza zamianą słowa kluczowego PROCEDURE na FUNCTION w instrukcji CREATE, kod różni się tylko w dwóch miejscach. Pierwszym z nich jest nagłówek, gdzie podaje się zwracany typ danych, a drugim jest część wykonawcza, gdzie następuje bezpośrednie przekazanie zwracanej wartości do programu wy- wołującego. RETURN TYP_DANYCH W nagłówku wyrażenie RETURN stanowi część deklaracji funkcji. Jest to informacja eo typie danych wartości, które mają być zwracane w wyniku wyweołania funkcji. RETURN wyrażenie Wewnątrz sekcji wykonawczej wyrażenie RETURN jest instrukcją i oznacza, że działania zostały zakończone i że należy zwrócić (return) wartość, którą definiuje wyrażenie. Instrukcja RETURN może znaleźć się także w sekcji EXCEPTION. Obydwie wymienione instrukcje są wymagane. W następnym podrozdziale przedstawiono kod go- towej funkcji. -QFHWPMELKDQQMAEQR[ASV[ Funkcja book_copy_qty zwraca liczbę książek, których numer ISBN odpowiada poedanemu. W poniższym, przykładowym kodzie funkcji do pobrania danych z bazy danych wykorzystano kursor (cursor). Szczegółowe omówienie tej struktury znajduje się dopiero w rozdziale 5. Uogólnia- jąc, 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 powiązanie pewnej instrukcji SELECT z kur- sorem. Powiązanie 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 końcu go zamknąć (close). CREATE OR REPLACE FUNCTION book_copy_qty(isbn_in IN VARCHoAR2) RETURN NUMBER AS number_o_copies NUMBER := 0; CURSOR bc_cur IS SELECT COUNT(*) FROM book_copies WHERE isbn = isbn_in; BEGIN 2QDKGTCPKGKPHQTOCELKQNKE\DKGMUKæľGM\CRQOQEæHWPMELK  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óły dotyczące działania funkcji przedstawioeno na rysunku 3.6. Rysunek 3.6. Wykorzystanie funkcji języka PL/SQL w celu zwrócenia pewnej wartości do programu wywołującego; dla danej wartości ISBN funkcja zwraca liczbę egzemplarzy znajdujących się. w bazie danych Zasadnicza różnica pomiędzy wywołaniem funkcji i procedury wynika z tego, że funkcje zwracają pewną wartość. 7ľ[YCPKGHWPMELK 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 wygląda to w następujący sposób: DECLARE zmienna_lokalna TYP_DANYCH; BEGIN zmienna_lokalna := nazwa_funkcji (argument1, argument2, ...); END; / Jest to zatem typowa instrukcja przypisania, gdzie wywołanie funkcji znajduje się po prawej stronie operatora przypisania, a zmienna lokalna po lewej. Moeżna więc napisać: DECLARE ile INTEGER; BEGIN ile := book_copy_qty( 1.56592-335-9 ); END; /  4Q\F\KCđ2TQITCOQYCPKG 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 ciągiem znaków i użycie funkcji PUT_LINE. Takie zagnieżdżanie funkcji wewnątrz innych in- strukcji jest często stosowaną techniką. 0KGMVÎTG\CUCF[FQV[E\æEGY[MQT\[UVCPKCHWPMELK Poniżej wymieniono kilka wartych zapamiętania zasad edotyczących 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 naezywania procedur wyrażeniem czasownikowym, a funkcji — wyrażeniem rzeczownikowyme może uchronić przed potencjalnymi problemami. 2. Nieuwzględnienie w nagłówku wyrażenia RETURN spowoduje, że funkcja nie zostanie skompilowana. Jest to działanie pozytywne, gdyż błędy eczasu kompilacji uważa się za metodę wczesnego ostrzegania przed ewentualnymi problemamie. Jeśli jednak słowo kluczowe RETURN zostanie pominięte w sekcji wykonawczej, system Oraclee poinformuje o tym dopiero po uruchomieniu funkcji. Zostanie wtedy wygenerowany komeunikat o błędzie ORA-06503: PL/SQL: Function returned without value. Dlatego zawsze warto przeprowadzać dogłębne testy napisanych programów. Procedury a funkcje Uogólniając, funkcja służ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 postępowanie nie jest zalecane. Warto też pamiętać, że nie należy pisać programów, które zwracają wartość informującą o stanie zakończenia. Postępowanie takie jest uzasadnione w języku takim jak C, lecz w przypadku PL/SQL informowanie o błędach powinno się odbywać poprzez przechwytywanie wyjątków. Jeśli program magazynowany nie przechwyci wyjątku, zakłada się, że podczas wykonania tego programu nie napotkano żadnych problemów. Czasami okazuje się, że istnieje potrzeba zwrócenia więcej 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 wywołujący po zakończeniu działania procedury. Zdefiniowanie kilku parametrów w trybie OUT może wprowadzić nieco zamieszania, jednak istnieje metoda zapisywania programów, któ- re muszą zwracać większą ilość danych w bardziej czytelny sposób. Można bowiem różne ele- menty połączyć w jedną całość przez zastosowanie jednego ze złożonych typów danych, jak na przykład rekord, kolekcja lub tak zwany typ obiektobwy. Zagadnienia te opisano w rozdziale 5. 2QDKGTCPKGKPHQTOCELKQNKE\DKGMUKæľGM\CRQOQEæHWPMELK  3. Program wywołujący po wywołaniu funkcji musi w jakieś sposób wykorzystać zwróconą wartość, na przykład przypisać ją pewnej zmiennej. PL/SQL, w przeceiwieństwie do języka C, nie dopuszcza wywołania funkcji i zignorowania zwracanej wartoście. 4. Po wykonaniu instrukcji RETURN w sekcji wykonawczej do programu wywołującego zosteaje przekazana nie tylko wartość, ale także sterowanie wyekonaniem programu. Innymi słowy, 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ć właś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. 9[LæVMKRT\GEJY[V[YCPGRT\G\HWPMELGYUGMELKFGMNCTECELK K\YKæ\CPG\PKOKOQľNKYGRTQDNGO[ Powyżej przedstawiono następujący sposób wywołania efunkcji: DECLARE ile INTEGER; BEGIN ile := book_copy_qty( 1-56592-335-9 ); END; / Wydawałoby się, że powyższy kod można zapisać w bardziej zwięzły sposób poprzez wywołanie funkcji podczas inicjalizacji zmiennej: DECLARE ile INTEGER := book_copy_qty( xyz ); BEGIN Z pozoru wszystko jest w porządku. Jednak jeśli funkcja przechwyci wyjątek, to okazuje się, że żaden kod obsługi wyjątku w tej sekcji nie zdoła przechwycić wyjątku, który ewentualnie może pojawić się po takim wywołaniu funkcji book_copy_qty. A zatem: DECLARE ile INTEGER := book_copy_qty( xyz ); BEGIN ...cokolwiek... EXCEPTION WHEN OTHERS THEN /* NIESPODZIANKA! Wyjątki przechwycone w sekcji deklaracji || NIE MOGĄ być obsłużone w tym miejscu! */ ... END; / Wytłumaczenie powodu takiego zachowania wykracza poeza zakres niniejszej książki. Dlatego należy po prostu zapamiętać, że nie należy dokonywać prób iniecjalizowania zmiennych za pomocą funkcji.  4Q\F\KCđ2TQITCOQYCPKG 6YQT\GPKGGNCUV[E\PGIQMQFW Z pewnością Czytelnik chciałby kontynuować rozwijanie tworzonej, przykładowej aplikacji. Nie można jednak zapominać o konsekwentnym upewnianiu się, że zapisany od nie zawiera błędów. Z tego też względu poniżej zamieszczono pewnego rodzaju dyegresję. Z pewnością każdy zetknął się już z wyrażeniem garbage in, garbage out (GIGO). Jest to wyraże- nie dość często używane lub słyszane przez telefon podczas rozmowy z obsługą techniczną. Oznacza ono mniej więcej tyle, co „wprowadzasz błędne dane — uezyskujesz błę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ę założenie tidy in, tidy out (wprowadzasz poprawne dane — uzyskujesz poprawne wyniki)3. Nikt nie lubi z góry planować działań zapobiegawczych względem zastosowaniea niepoprawnych danych wejściowych. W celu uniknięcia nieprzewidzianych załamań 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 cały 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ęczącego procesu za pomocą takich programów. 0CT\úF\KGURTCYF\CLæEGY[PKMK Działanie pierwszego, sprawdzającego 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 właśnie porównywanie wartości — wartości faktycznej ze spodziewaną wartością wyjściową. Dlatego też wspomniany program jest bardzo użyteczny. Zawierał 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 proceedury „test równości” (testrownosci): CREATE OR REPLACE PROCEDURE reporteq (description IN VARCHAoR2, 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 Nieprzetłumaczalna gra słów: garbage to po angielsku śmieci, bzdury; tidy — czysty, schludny — przyp. tłum. 6YQT\GPKGGNCUV[E\PGIQMQFW  ELSE DBMS_OUTPUT.PUT_LINE( FAILED. Expected || expected_value || ; got || actual_value); END IF;
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Oracle PL/SQL. Wprowadzenie
Autor:
,

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: