Podstawowe właściwości języka PL/SQL

Podobne dokumenty
DECLARE <nazwa_zmiennej> typ [(<rozmiar> )] [ NOT NULL ] [ { := DEFAULT } <wartość> ];

Bloki anonimowe w PL/SQL

PODSTAWY BAZ DANYCH 13. PL/SQL

Oracle PL/SQL. Paweł Rajba.

1 Kursory 1. 2 Wyjątki Wyjątki predefiniowane Wyjątki niezdefiniowane wcześniej Definiowanie własnych wyjątków...

Oracle PL/SQL. Paweł Rajba.

Materiały. Technologie baz danych. Plan wykładu Kursory. Wykład 5: Kursory jawne. Podprogramy. Kursory jawne. Kursory niejawne

DECLARE VARIABLE zmienna1 typ danych; BEGIN

Procedury składowane. Funkcje vs. procedury Funkcja. Procedura. zazwyczaj ma parametry tylko typu IN; można wywoływać z poziomu

Kursory i wyjątki. (c) Instytut Informatyki Politechniki Poznańskiej 1

PL/SQL. Zaawansowane tematy PL/SQL

Deklarowanie kursora

Oracle11g: Wprowadzenie do SQL

Oracle11g: Programowanie w PL/SQL

Język PL/SQL. Rozdział 2. Kursory

Plan wykładu Projekt fizyczny bazy danych Wprowadzenie PL/SQL PL/SQL Cechy PL/SQL

Procedury i funkcje składowane

1 Podstawy c++ w pigułce.

Plan wykładu BAZY DANYCH II WYKŁAD 3. Zasięg zmiennych. Zasięg zmiennych

Plan wykładu BAZY DANYCH II WYKŁAD 2. Bloki. Struktura bloku

Kursor jawny. Rozdział 10a Kursory. Deklarowanie kursora (1) Deklarowanie kursora (2)

Język PL/SQL. Rozdział 5. Pakiety podprogramów. Dynamiczny SQL

Język PL/SQL. Rozdział 3. Obsługa błędów wykonania Wyjątki predefiniowane i użytkownika, zgłaszanie i obsługa wyjątków.

Październik Instytut Informatyki Teoretycznej i Stosowanej Politechnika Częstochowska. Systemy baz danych - wykład III. dr inż.

15. Funkcje i procedury składowane PL/SQL

Plan wykładu PL/SQL. PL/SQL - historia TWORZENIE APLIKACJI BAZODANOWYCH

Pakiety podprogramów Dynamiczny SQL

Deklarowanie kursora. CURSOR nazwa [ ( param1 typ1 [,param2 typ2]... ) ] [RETURN typ zwracany] IS zapytanie SQL;

Opis: Instrukcja warunkowa Składnia: IF [NOT] warunek [AND [NOT] warunek] [OR [NOT] warunek].

Systemy GIS Tworzenie zapytań w bazach danych

Język PL/SQL Procedury i funkcje składowane

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Kursor. Rozdział 10a Kursory. Otwieranie kursora. Deklarowanie kursora

Podstawy programowania skrót z wykładów:

PL/SQL. Lidia Małkiewicz i Cezary Skubała

Bazy danych wykład dwunasty PL/SQL, c.d. Konrad Zdanowski ( Uniwersytet Kardynała Stefana Bazy danych Wyszyńskiego, wykładwarszawa)

Pakiety są logicznymi zbiorami obiektów takich jak podprogramy, typy, zmienne, kursory, wyjątki.

Uwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre)

SQL - Structured Query Language -strukturalny język zapytań SQL SQL SQL SQL

ORACLE (Wykład 1) aragorn.pb.bialystok.pl/~aonisko. Typy rozproszonych baz danych. Systemy klient-serwer. Klient-serwer: Przykład

Instrukcje SQL można podzielić na pięć kategorii, które zostały przedstawione w poniższej tabeli.

Programowanie w SQL. definicja bloku instrukcji BEGIN...END, warunkowe wykonanie instrukcji IF...ELSE, wyrażenie CASE,

PRZESTRZENNE BAZY DANYCH WYKŁAD 2

Laboratorium Wstawianie skryptu na stroną: 2. Komentarze: 3. Deklaracja zmiennych

Plan wykładu BAZY DANYCH II WYKŁAD 4. Co to jest kursor? Rodzaje kursorów

Procedury wyzwalane. (c) Instytut Informatyki Politechniki Poznańskiej 1

w PL/SQL bloki nazwane to: funkcje, procedury, pakiety, wyzwalacze

Bloki anonimowe w PL/SQL

Oracle Developer Suite. Budowa aplikacji użytkownika końcowego

Wyzwalacz - procedura wyzwalana, składowana fizycznie w bazie, uruchamiana automatycznie po nastąpieniu określonego w definicji zdarzenia

Oracle10g: Programowanie w PL/SQL

Funkcje w PL/SQL Funkcja to nazwany blok języka PL/SQL. Jest przechowywana w bazie i musi zwracać wynik. Z reguły, funkcji utworzonych w PL/SQL-u

PL/SQL. Część 1 Bloki PL/SQL. Piotr Medoń

Po uruchomieniu programu nasza litera zostanie wyświetlona na ekranie

Projektowanie systemów baz danych

Oracle PL/SQL. Paweł Rajba.

Kursory - pobieranie danych z baz danych do programów PL/SQL

1 Podstawy c++ w pigułce.

Oracle PL/SQL. Paweł Rajba.

Programowanie strukturalne. Opis ogólny programu w Turbo Pascalu

1. ELEMENTY JĘZYKA PL/SQL

Przykład 3 Zdefiniuj w bazie danych hurtownia_nazwisko przykładową funkcję użytkownika fn_rok;

Wyzwalacze. do automatycznego generowania wartości kluczy głównych. Składnia instrukcji tworzacej wyzwalacz

Trigger jest obiektem związanym z tablicą, który aktywuje się gdy do tablicy następuje odpowiednie zapytanie.

E.14 Bazy Danych cz. 18 SQL Funkcje, procedury składowane i wyzwalacze

Przestrzenne bazy danych Podstawy języka SQL

Systemy operacyjne. Laboratorium 9. Perl wyrażenia regularne. Jarosław Rudy Politechnika Wrocławska 28 lutego 2017

Języki programowania zasady ich tworzenia

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

Podstawy Programowania C++

Programowanie w języku Python. Grażyna Koba

Wstęp do programowania INP003203L rok akademicki 2018/19 semestr zimowy. Laboratorium 2. Karol Tarnowski A-1 p.

Cheatsheet PL/SQL Andrzej Klusiewicz 1/9

29. Poprawność składniowa i strukturalna dokumentu XML

SQL Server i T-SQL w mgnieniu oka : opanuj język zapytań w 10 minut dziennie / Ben Forta. Gliwice, Spis treści

Materiały do laboratorium MS ACCESS BASIC

Blaski i cienie wyzwalaczy w relacyjnych bazach danych. Mgr inż. Andrzej Ptasznik

Wyzwalacze. Anna Fiedorowicz Bazy danych 2

Instrukcja podwaja zarobki osób, których imiona zaczynają się P i dalsze litery alfabetu zakładamy, że takich osbób jest kilkanaście.

Język programowania DELPHI / Andrzej Marciniak. Poznań, Spis treści

Widoczność zmiennych Czy wartości każdej zmiennej można zmieniać w dowolnym miejscu kodu? Czy można zadeklarować dwie zmienne o takich samych nazwach?

Umieszczanie kodu. kod skryptu

D D L S Q L. Co to jest DDL SQL i jakie s jego ą podstawowe polecenia?

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Pętle. Dodał Administrator niedziela, 14 marzec :27

ECDL Podstawy programowania Sylabus - wersja 1.0

Algorytmika i Programowanie VBA 1 - podstawy

Wykład 8: klasy cz. 4

Laboratorium nr 4. Temat: SQL część II. Polecenia DML

BAZY DANYCH W APLIKACJACH SIECIOWYCH

Oracle PL/SQL. Paweł Rajba.

Pascal - wprowadzenie

Krzysztof Kadowski. PL-E3579, PL-EA0312,

Podstawy programowania w C++

Plan. Formularz i jego typy. Tworzenie formularza. Co to jest formularz? Typy formularzy Tworzenie prostego formularza Budowa prostego formularza

Cele. Definiowanie wyzwalaczy

Rozdział 4 KLASY, OBIEKTY, METODY

Programowanie w SQL procedury i funkcje. UWAGA: Proszę nie zapominać o prefiksowaniu nazw obiektów ciągiem [OLIMP\{nr indeksu}] Funkcje użytkownika

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

Uzupełnij pola tabeli zgodnie z przykładem poniżej,

Transkrypt:

Podstawowe właściwości języka PL/SQL W celu wykorzystywania języka PL/SQL do wykonywania różnego rodzaju zadań, należy posiadać wiedzę dotyczącą konstruowania programu w języku PL/SQL, a przede wszystkim znać składnię tego języka, która jest niezbędna do tworzenia poszczególnych elementów występujących w danym języku. Wiedza ta powinna obejmować przede wszystkim znajomość elementów składowych bloku programu języka PL/SQL. Ponadto niezbędna jest też wiedza dotycząca deklaracji zmiennych w bloku języka PL/SQL, podstawowych konstrukcji proceduralnych oraz informacji wstępnych dotyczących bloków programowych występujących w języku PL/SQL. Pewne zagadnienia dotyczące stylu programowania, jak również dotyczące pomocnych technik, które ułatwiają pisanie eleganckiego, a przede wszystkim zrozumiałego i przejrzystego kodu języka PL/SQL, są również nieodzownym elementem nauki programowania w PL/SQL, szczególnie na etapie wstępnym. Struktura bloku języka PL/SQL Struktura języka PL/SQL stanowi jego fundament. Podstawowym elementem kodu napisanego w języku PL/SQL jest blok (ang. block). Każdy blok PL/SQL jest nieciągłym zbiorem kodu (składa się z pewnej liczby części tzw. sekcji), który w normalnych warunkach wykonuje pewną funkcje. Blok PL/SQL umożliwia też modularyzację kodu na logicznie powiązane jednostki. W strukturze programu istnieją: obszary do wpisywania jego parametrów (służące do przekazywania wartości spoza programu do programu), obszary do wpisywania jego zmiennych wewnętrznych, obszar głównego kodu programu i zależności logicznych, obszar określania mechanizmów działania programu w przypadku wystąpienia błędów. Należy podkreślić, że wszystkie bloki programu języka PL/SQL mogą składać się z trzech odrębnych części: sekcji deklaracji, sekcji wykonania, sekcji wyjątków. W każdym bloku musi wystąpić sekcja wykonania, natomiast dwie pozostałe są opcjonalne. Struktura każdego programu w języku PL/SQL, która zawiera wszystkie sekcje, ma postać: DECLARE /* Początek sekcji deklaracji */ -- Tutaj należy umieścić zmienne BEGIN /* Początek sekcji wykonania */ --Tutaj należy umieścić program EXCEPTION /* Początek sekcji wyjątków */ --Tutaj należy umieścić instrukcje obsługi wyjątków END; / 1

Poniższa tabela prezentuje podstawowe informacje o każdej z możliwych sekcji bloku PL/SQL, tj. jej przeznaczenie, własność opcjonalności występowania, strukturę. Nazwa sekcji Sekcja deklaracji (ang. declaration section) Sekcja wykonania (ang. executable section) Sekcja obsługi wyjątków (ang. exception handling section) deklaracje: zmiennych kursorów typów danych lokalnych podprogramów dostępnych i wykorzystywanych tylko w obrębie danego bloku jest opcjonalna początek sekcji słowo kluczowe DECLARE w tej sekcji zachodzi właściwe działanie bloku, tj. wykonanie kodu programu. Sekcja ta zawiera logikę proceduralną oraz instrukcje SQL. występuje w każdym bloku języka PL/SQL początek sekcji słowo kluczowe BEGIN w tej sekcji są obsługiwane błędy serwera Oracle i/lub języka PL/SQL o ile występują w bloku programu. Jeśli błąd nie wystąpi, kod tej sekcji nie jest wykonywany. choć jest opcjonalna, zalecane jest jej umieszczanie w każdym bloku początek sekcji słowo kluczowe EXCEPTION zakończenie bloku słowo kluczowe END oraz końcowy znak średnika, który jest również częścią składową bloku Uwaga: Słowo kluczowe DECLARE nie jest potrzebne do utworzenia procedury. W rzeczywistości jego stosowanie jest błędem. Słowa tego wymaga się natomiast podczas tworzenia wyzwalacza. Wszystkie programy PL/SQL są złożone z bloków, które występują sekwencyjnie (jeden po drugim) lub są zagnieżdżone (jeden w drugim). Wyróżniamy dwa różne rodzaje bloków: anonimowe (nienazwane), nazwane. Bloki anonimowe (ang. anonymous block) są przydatne do tworzenia krótkich programów, zazwyczaj tworzonych dynamicznie i wykonywanych tylko jeden raz. Blok anonimowy jest jedną instrukcją lub serią kilku instrukcji, ograniczonych pewnymi słowami kluczowymi (zazwyczaj są to słowa BEGIN i END). Tego rodzaju bloki są zazwyczaj przekazywane z programu działającego po stronie klienta w celu wywołania podprogramu zapisanego w bazie danych. Z blokiem anonimowym nie jest skojarzona żadna nazwa można zatem określić go mianem bloku bez nazwy. Blok anonimowy może występować w kilku formach, z których najprostsza ma postać: 2

BEGIN instrukcje END; gdzie instrukcje oznacza jedynie obecność jednej lub większej liczby instrukcji wykonawczych. W tym przypadku sekcja deklaracji nie istnieje i blok rozpoczyna się słowem kluczowym BEGIN. Gdy nie uwzględniono sekcji wyjątków, wówczas słowo kluczowe EXCEPTION jest również pominięte i blok jest kończony słowem kluczowym END, po którym występuje znak średnika. W przypadku, gdy w bloku anonimowym występuje sekcja deklaracji, blok zaczyna się od słowa kluczowego DECLARE, a nie BEGIN: [ DECLARE deklaracje ] BEGIN instrukcje [ EXCEPTION instrukcje obsługi wyjątków ] END; gdzie: deklaracje (ang. declarations) jest to jedna lub większa liczba linii kodu, które ustalają związek zdefiniowanych przez programistę identyfikatorów z odpowiednimi typami danych, instrukcje (ang. statements) jest to jedna lub większa liczba linii kodu, które po uruchomieniu programu, służą do rozwiązania pewnego problemu lub do wykonania pewnych działań. instrukcje obsługi wyjątków (ang. exception handlers) jest to jedna lub większa liczba linii kodu wykonywanych w razie wystąpienia określonego błędu. Inaczej mówiąc, jest to kod opisujący odpowiedź bloku na wystąpienie w sekcji wykonawczej błędów. Nawiasy kwadratowe, które występują w powyżej przedstawionej formie bloku anonimowego języka PL/SQL w tym konkretnym przypadku wskazują, że odpowiednie sekcje są opcjonalne. Bloki nazwane (ang. named blocks) są blokami, którym przypisano nazwę. Można je podzielić na następujące kategorie: bloki oznaczone etykietą (ang. labeled block) to bloki anonimowe, którym przydzielono etykietę będącą nazwą bloku. Są one zazwyczaj tworzone dynamicznie i wykonywane tylko raz, zwykle w taki sam sposób jak bloki anonimowe, ale etykieta pozwala na odwołania do zmiennych, które w innym przypadku nie byłyby widoczne. Aby utworzyć tego rodzaju blok nazwany, należy przed słowem kluczowym DECLARE wstawić etykietę. Etykieta może pojawić się również po słowie kluczowym END. <<etykieta>> DECLARE deklaracje BEGIN 3

instrukcje END etykieta; / podprogramy można je przechowywać w bazie danych jako osobne obiekty, jako część pakietu lub metody typu obiektowego. Gdy bloki tego typu zostaną utworzone, nie podlegają zmianom i są wykonywane wielokrotnie. Podprogramy można także definiować wewnątrz innych bloków. Wyróżnia się dwa rodzaje podprogramów: procedury- są to nazwane programy, które wykonują pewne zdefiniowane instrukcje, a następnie po ich wykonaniu zwracają sterowanie do programu, które je wywołuje. Po utworzeniu procedury mogą być uruchamiane poprzez podanie ich nazwy; funkcje ich struktura jest podobna do składni procedur, z tą różnicą, iż zwracają one pewną wartość do programu, który je wywołuje. Typ zwracanej przez funkcję wartości jest definiowany wcześniej. wyzwalacze (ang. triggers) są blokami PL/SQL skojarzonymi ze zdarzeniami zachodzącymi w bazie danych. Bloki te po ich utworzeniu również nie zmieniają się i są wykonywane wielokrotnie. Wyzwalacze są wykonywane niejawnie, jeśli wystąpi zdarzenie prowadzące do wyzwalania. Zdarzenie wyzwalania może być instrukcją języka manipulacji danych DML (Data Manipulation Language) uruchomioną dla tabeli bazy danych. Do instrukcji DML zalicza się: INSERT, UPDATE oraz DELETE. Może to być instrukcja języka definicji danych DDL (Data Definition Language), np. CREATE lub DROP albo zdarzenie związane z bazą danych, np. uruchomienie lub zatrzymanie serwera. Bloki zagnieżdżone Istnieje możliwość zagnieżdżania bloków w sekcji wykonania oraz w sekcji wyjątków bloku zewnętrznego. Bloki PL/SQL można zagnieżdżać na arbitralną głębokość DECLARE /* Początek sekcji deklaracji */ BEGIN /* Początek sekcji wykonania bloku zewnętrznego*/ -- Początek bloku zagnieżdżonego, który zawiera jedynie sekcję wykonania BEGIN /* Początek sekcji wykonania bloku zagnieżdżonego*/ END; EXCEPTION /* Początek sekcji wyjątków bloku zewnętrznego*/ -- Początek bloku zagnieżdżonego, który zawiera sekcję wykonania i sekcję wyjątków BEGIN /* Początek sekcji wykonania bloku zagnieżdżonego*/ EXCEPTION /* Początek sekcji wyjątków bloku zagnieżdżonego*/ END; END; / 4

Jednostki leksykalne Każdy program w języku PL/SQL jest złożony z jednostek leksykalnych, które są jednostkami składowymi języka. Jednostka leksykalna jest sekwencją znaków pochodzących z zestawu znaków stosowanego w języku PL/SQL. Zestaw ten zawiera: Małe i duże litery: A-Z oraz a-z Cyfry: 0-9 Znaki odstępu: tabulatory, spacje i znaki nowego wiersza. symbole matematyczne: + - * / <> = znaki interpunkcyjne: () {} []?! ~ ; :. # @ $ ^ & _ W programach PL/SQL można wykorzystywać jedynie znaki uwzględnione w powyższym zestawie. Wśród jednostek leksykalnych wyróżnia się: identyfikatory, ograniczniki, literały, komentarze. Identyfikatory Identyfikatory są nazwami, które są nadawane obiektom języka PL/SQL, takim jak: zmienne, stałe, kursory, typy danych (zarówno wbudowane, jak i te, które są definiowane przez użytkownika), podprogramy. Nazwy te muszą odpowiadać pewnym zasadom: długość identyfikatora nie może przekroczyć 30 znaków, identyfikator musi zaczynać się od litery, identyfikatory mogą zawierać dowolną sekwencję znaków złożoną z liter, cyfr, znaków dolara, znaków podkreślenia i znaków #; użycie innych znaków niż wymienione powyżej jest niedozwolone, nie mogą brzmieć tak samo, jak słowa zastrzeżone lub słowa kluczowe języka PL/SQL, muszą być niepowtarzalne w swoim zasięgu, tzn. nie można zadeklarować dwóch zmiennych o tej samej nazwie w jednym bloku kodu programu. Uwaga: Dobrą zasadą, przydatną podczas pisania programów, jest stosowanie konsekwentnego nazewnictwa identyfikatorów, aby były one zrozumiałe. W celu rozróżnienia w identyfikatorze dużych i małych liter, a także kiedy ma on zawierać takie znaki jak spacje czy słowa kluczowe, należy ująć go w cudzysłów. Podobnie jak w przypadku identyfikatora zwykłego (nieujętego w cudzysłów), maksymalna długość identyfikatora ujętego w cudzysłów nie może przekroczyć 30 znaków. 5

Identyfikatory ujęte w cudzysłów W celu rozróżnienia w identyfikatorze dużych i małych liter oraz w przypadku, gdy zawiera on takie znaki, jak spacje czy słowa kluczowe, należy identyfikator ująć w cudzysłów. Poniżej podane identyfikatory są zatem dozwolone i rozróżniane między sobą: Liczba x Liczba X Mc Hammer W przypadku użycia jako identyfikatora słowa kluczowego lub słowa zastrzeżonego języka PL/SQL należy koniecznie ująć go w cudzysłów. Tym niemniej nie zaleca się stosowania słów zastrzeżonych do nazywania identyfikatorów, choć jest to dozwolone. Świadczy to o słabym stylu programowania, czyni program trudniejszym do zrozumienia, a nawet może prowadzić do nieporozumień lub błędnej interpretacji kodu. Wyjątkiem od tej reguły jest sytuacja, kiedy w tabeli bazy danych występuje nazwa kolumny, która jest słowem zastrzeżonym języka PL/SQL., bowiem język ten ma więcej słów zastrzeżonych niż SQL. Należy wówczas pamiętać, że choć w tabeli występuje kolumna, której nazwa jest słowem zastrzeżonym języka PL/SQL, to nazwa ta wciąż nie może być słowem zastrzeżonym języka SQL. Ograniczniki Ograniczniki są symbolami (jest to pojedynczy znak lub ciąg znaków), które są wykorzystywane do oddzielania identyfikatorów od siebie. Tabela 1. Ograniczniki języka PL/SQL Symbol Opis Symbol Opis + Operator dodawania - Operator odejmowania * Operator mnożenia / Operator dzielenia = Operator równości < Operator mniejszości > Operator większości ( Początkowy ogranicznik wyrażenia ) Końcowy ogranicznik wyrażenia ; Znak końca instrukcji % Wskaźnik atrybutu, Separator elementów. Wskaźnik składnika @ Wskaźnik łącza bazy danych Ogranicznik ciągu znaków Ogranicznik cytowanego ciągu znaków : Wskaźnik zmiennej związanej ** Operator potęgowania <> Operator nierówności!<> Operator nierówności (równoważny z <>) ~= Operator nierówności (równoważny!=) ^= Operator nierówności (równoważny z ~=) <= Operator mniejszy lub równy >= Operator większy lub równy := Operator przypisania => Operator skojarzenia.. Operator zakresu Operator konkatenacji ciągu znaków << Początkowy ogranicznik etykiety >> Końcowy ogranicznik etykiety -- Wskaźnik komentarza jednowierszowego /* Początkowy wskaźnik komentarza wielowierszowego */ Końcowy wskaźnik komentarza wielowierszowego 6 <spacja> Znak spacji <tab> Znak tabulatora <cr> Znak powrotu do nowego wiersza

Literały Literał jest wartością znakową, numeryczną lub logiczną (boolowską), która nie jest identyfikatorem, np. obydwie wartości 2,5 oraz NULL, są literałami. Literały znakowe Literały znakowe, nazywane również literałami ciągów znaków, składają się z jednego lub większej liczby znaków ujętych w znaki apostrofu (taki sam standard obowiązuje w języku SQL) i są przypisane zmiennym typu CHAR lub VARCHAR2 bez konieczności konwersji. Aby zapisać ciąg znaków składający się z jednego apostrofu w kodzie PL/SQL należy użyć czterech apostrofów, zaś literał składający się z dwóch apostrofów oznacza ciąg o zerowej liczbie znaków. W języku PL/SQL literał ciągu znaków o zerowej liczbie znaków jest równoważny wartości NULL. Literały numeryczne Literały numeryczne reprezentują wartości liczb całkowitych lub rzeczywistych i mogą być przypisywane bez konwersji zmiennym typu NUMBER. W wyrażeniach arytmetycznych można stosować tylko literały numeryczne. Literały liczb całkowitych składają z opcjonalnego znaku (+ lub -), po którym następują cyfry. Stosowanie kropki dziesiętnej dla literału liczb całkowitych jest niedopuszczalne. Literały logiczne Istnieją trzy możliwe literały logiczne (boolowskie): TRUE, FALSE lub NULL. W tym zakresie język PL/SQL różni się od większości języków, w których występują tylko dwie wartości logiczne: TRUE i FALSE. Wartości te mogą być przydzielane zmiennej logicznej (boolowskiej). Literały logiczne określają prawdę lub fałsz pewnych warunków. Są one wykorzystywane do tworzenia instrukcji IF lub LOOP. Komentarze Komentarze (ang. comments) są częścią programu, która spełnia funkcje dokumentacji. Poprawiają one ponadto czytelność programów i sprawiają, że stają się one bardziej zrozumiałe. Komentarze są ignorowane przez kompilator PL/SQL. Wskazówki dla optymalizatora SQL, wyglądające jak komentarze, są przetwarzane przez mechanizm SQL. Komentarz powinien dotyczyć w szczególności: informacji o środowisku zewnętrznym, założeń i ograniczeń w kodzie programu, które zostały postawione przez programistę, niestandardowych wymagań wobec użytkownika, kodu, którego jedynym zadaniem jest obejście jakiegoś błędu, pomysłów mających na celu przyszłe ulepszenie kodu, uzasadnienia i wyjaśnienia zastosowania dziwnych lub niespodziewanych konstrukcji językowych. W języku PL/SQL można stosować dwa rodzaje komentarzy: jednowierszowe, wielowierszowe (zwane także komentarzami w stylu języka C). 7

Komentarze jednowierszowe Komentarz jednowierszowy rozpoczyna się dwoma znakami myślnika i zamyka wraz z końcem wiersza (zatem komentarz tego typu jest ograniczony znakiem powrotu do następnego wiersza). Komentarze wielowierszowe Komentarze wielowierszowe rozpoczynają się ogranicznikiem złożonym z znaków prawego ukośnika i gwiazdki /*, a kończą ogranicznikiem złożonym ze znaków gwiazdki i prawego ukośnika */. Komentarze wielowierszowe mogą mieć dowolną długość (w zależności od potrzeb), a zatem są najbardziej przydatne w sytuacji, gdy komentarz w kodzie programu zajmuje więcej niż jedną linię. Nie można ich jednak zagnieżdżać każdy komentarz musi być zakończony przed rozpoczęciem następnego. Deklaracje zmiennych Komunikacja z bazą danych Oracle odbywa się za pomocą zmiennych występujących w bloku PL/SQL. Właściwie zawsze w programie napisanym w języku PL/SQL istnieje konieczność użycia zmiennych. Zmienna jest chwilowym zapisem danych określonego typu. Przed zastosowaniem jakiejkolwiek zmiennej w programie języka PL/SQL, należy ją zadeklarować, tzn. nadać jej nazwę oraz przypisać określony typ danych. Cechy charakterystyczne zmiennych języka PL/SQL zmienna może przechowywać różne wartości danych tego typu, w trakcie pracy programu zmienna może ulegać zmianom, zmiennej mogą być przydzielane informacje z bazy danych, wartość zmiennej może zostać wprowadzona do bazy danych, zmienna może być modyfikowana bezpośrednio przez polecenia języka PL/SQL, zmienna jest deklarowana w sekcji deklaracji bloku, każda zmienna posiada określony typ, który decyduje o rodzaju informacji przechowywanych w danej zmiennej. Przeznaczenie i rola zmiennych języka PL/SQL poprzez definicję zmiennych użytkownik definiuje sposób przechowywania danych w czasie przetwarzania ich przez program, przypisywanie wartości zmiennym może być dokonane w dowolnej sekcji kodu programu, umieszczenie zmiennej w sekcji deklaracji ma zwykle na celu inicjalizację wartości zmiennej przed jej użyciem w programie lub zdefiniowanie wartości, które będą wykorzystywane w programie jako stałe. Składnia deklaracji zmiennej jest następująca: nazwa zmiennej typ danych [CONSTANT] [NOT NULL] [:=wartosc] gdzie: identyfikator nazwa zmiennej jest nazwą zmiennej - nazwą zmiennej może być dowolny identyfikator PL/SQL, 8

typ jest typem zmiennej (np. VARCHAR2, NUMBER, DATE, BOOLEAN), wartość początkową wartością zmiennej. Zasady inicjowania zmiennych w języku PL/SQL jeżeli zmienna nie została zainicjowana, to domyślnie jest jej przydzielana wartość NULL, w razie uwzględnienia w deklaracji określenia NOT NULL zmienna musi zostać zainicjowana, nie jest dozwolone przydzielanie wartości NULL zmiennej, dla której w sekcji wykonania lub sekcji wyjątków wymuszono wartość różną od NULL, jeżeli w deklaracji zmiennej występuje określenie CONSTANT, to zmienna musi zostać zainicjowana i jej wartość początkowa nie może zostać zmieniona. W pozostałej części bloku zmienna o stałej wartości jest traktowana jako zmienna tylko do odczytu. Stałe są często wykorzystywane dla wartości znanych w momencie tworzenia bloku. zamiast operatora przypisania := można również stosować słowo kluczowe DEFAULT, w jednym wierszu sekcji deklaracji może wystąpić tylko jedna deklaracja zmiennej, język PL/SQL określa wartość niezainicjowanej zmiennej i jest nią wartość NULL, która w istocie oznacza brakującą lub nieznaną wartość. W związku z tym wartość tę przypisuje się domyślnie każdej niezainicjowanej zmiennej. Przykład bloku języka PL/SQL, w którym zainicjowano zmienną i wykorzystano komentarze: DECLARE /* Początek sekcji deklaracji */ z_id NUMBER; z_produkt VARCHAR2(35):= czekolada mleczna ; -- przypisanie wartości początkowej zmiennej z_cena NUMBER(7,2); BEGIN /* Początek sekcji wykonania */ -- Pobranie towaru o nazwie czekolada mleczna SELECT id, nazwa, cena INTO z_id, z_produkt, z_cena FROM towary WHERE nazwa=z_produkt; -- Wyświetlenie danych o pobranym z tabeli towarze DBMS_OUTPUT.PUT_LINE( Produkt o nazwie z_produkt ma id z_id oraz cenę z_cena zł ); EXCEPTION /* Początek sekcji wyjątków */ WHEN NO_DATA_FOUND THEN -- Obsługa błędu DBMS_OUTPUT.PUT_LINE( Brak produktu o nazwie z_produkt); END; / 9

Styl programowania w języku PL/SQL Nie istnieją wprawdzie żelazne reguły dotyczące pisania kodu programów języka PL/SQL. Częściowo może być to uzasadnione faktem, iż standardy tworzenia programów nie są częścią żadnego języka programowania i język PL/SQL nie jest odosobniony w tym względzie. W przypadku początkujących programistów daje się zauważyć tendencja do ignorowania pewnych użytecznych wskazówek dotyczących poprawnego stylu pisania kodu programów języka PL/SQL, który byłby zrozumiały przede wszystkim dla innych użytkowników z niego korzystających. Taki programista nie stosuje tego typu zasad, np. nie używa wielkich liter, wcięć tekstu, nie używa spacji i wielu innych możliwości, jakie oferuje język PL/SQL, które są użyteczne, jeśli chodzi o napisanie zrozumiałego pod względem swej formy kodu. A przecież można samodzielnie podczas pisania kodu języka PL/SQL wypracować własny styl programowania, który umożliwi pisanie takich bloków języka PL/SQL, które będą bardziej czytelne i łatwiejsze do analizy nie tylko dla ich twórców, ale innych użytkowników, nawet takich, którzy pierwszy raz z nimi obcują. Ponieważ skrypty pisane w języku PL/SQL mogą być w niektórych przypadkach dość skomplikowane, zarówno ze względu na swoją złożoność strukturalną, jak i ze względu różnorodność zawartych w nich poleceń, instrukcji, itp., a także ze względu na fakt, iż oprócz samego języka PL/SQL, również mogą być w nich zawarte elementy charakterystyczne dla języka SQL, warto zastanowić się nad stylem pisania tych skryptów. Trudno tu mówić o jakiś konkretnych przepisach dotyczących stylu programowania w języku PL/SQL. Tym niemniej, choćby z powyżej przytoczonych faktów wynika, iż warto tak projektować pisanie skryptów w języku programowania (nie tylko w PL/SQL), aby napisany program był bardziej czytelny, Przez styl programowania rozumie się sposób nazywania zmiennych, zasady stosowania dużych liter, odstępów czy wprowadzenie komentarzy oraz efektywne stosowanie innych aspektów języka PL/SQL oferowanych w tym względzie. Styl programowania niekoniecznie przekłada się na działanie programu. Dwa programy napisane w różnym stylu w dalszym ciągu mogą spełniać to samo zadanie. Ważne jest jednak to, że program dobrze napisany można łatwiej zrozumieć i lepiej aktualizować niż program napisany nieczytelnie. Jeżeli kod programu jest widziany po raz pierwszy przez osobę, która go nie pisała i jest ona w stanie w miarę szybko zrozumieć jego działanie, oznacza to, że program jest dobrze napisany. Dobry styl pomaga również w zrozumieniu sposobu działania programu zarówno w chwili jego pisania, jak i w razie konieczności jego późniejszej analizy. Jako przykład przeanalizujmy następujące dwa bloki języka PL/SQL i spróbujmy ustalić, który z nich jest bardziej zrozumiały: declare x number; y number; begin if x<12 then y:=8; else y:=3; end if; end; DECLARE z_zmienna NUMBER; -- Zmienna, która będzie badana 10

z_wynik NUMBER; -- Zmienna do zapamiętania wyniku BEGIN /* Badanie zmiennej z_zmienna i przypisanie 8 do zmiennej z_wynik, jeżeli z_zmienna < 12 */ IF z_zmienna < 12 THEN z_wynik:= 8; ELSE z_wynik:= 3; END IF; END; Obydwa bloki wykonują to samo zadanie, jednak analiza sposobu pracy programu zapisanego w drugim bloku jest prawdopodobnie łatwiejsza, co nie ulega żadnej wątpliwości. Wprowadzanie komentarzy Komentarze są głównym mechanizmem informowania użytkownika o celu utworzenia programu oraz o sposobie jego działania. Zaleca się wstawianie komentarzy w następujących miejscach: na początku każdego bloku i (lub) procedury tak wstawione komentarze powinny objaśniać użytkownikowi, jakie zadanie wykonuje dany blok lub procedura. W przypadku procedur ważne jest wskazanie, które zmienne lub parametry będą odczytywane przez procedurę (wejście), a które zmienne lub parametry będą zapisywane przez procedurę (wyjście). Dobrą zasadą jest podanie nazw tabel bazy danych, do których jest realizowany dostęp. przy deklaracji każdej zmiennej w ten sposób powinien być podany opis przeznaczenia zmiennej w danym programie, tj. do czego dana zmienna będzie wykorzystywana. Często mogą to być po prostu komentarze jednowierszowe, np.: z_nrprjaz CHAR(10) -- Numer prawa jazdy przed każdą główną sekcją bloku nie jest konieczne umieszczanie komentarzy dla każdej instrukcji, ale komentarz wyjaśniający działanie pewnej grupy instrukcji jest na ogół bardzo przydatny. Wprawdzie wykorzystany w programie algorytm może być zrozumiały na podstawie analizy samego kodu, tym niemniej lepiej opisać cel umieszczenia w programie algorytmu i przeznaczenia jego wyników niż podawać szczegóły danej metody. Nie należy popadać w zbytnią przesadę, co do opisu programu za pomocą komentarzy, gdyż można doprowadzić również i do takiej sytuacji, w której obecność zbyt wielu komentarzy utrudnia zrozumienie kodu. W razie wątpliwości, czy wprowadzić komentarz, należy sobie zadać pytanie: Co chciałby wiedzieć programista, widząc ten kod pierwszy raz? Komentarze powinny być sensowne i nie powtarzać tego, o czym informuje kod PL/SQL. Poniższy komentarz nie wnosi niczego nowego do informacji wyrażonej kodem PL/SQL i dlatego jest niepotrzebny: DECLARE 11

z_tymcz NUMBER:=0; -- Przypisanie 0 do zmiennej z_tymcz Poniższy komentarz jest lepszy, ponieważ opisuje przeznaczenie zmiennej z_tymcz: DECLARE z_tymcz NUMBER:=0; -- Zmienna przeznaczona do obliczeń w bloku głównym programu Styl nazw zmiennych Aby program był lepiej zrozumiały należy zmiennym nadawać w miarę opisowe nazwy, a przy tym trzymać się pewnych własnych subiektywnych reguł, co do ich przydzielania. Deklaracja postaci x NUMBER; nie zawiera żadnych dodatkowych informacji dotyczących zmiennej x i sposobu jej wykorzystania. Jeśli jednak zastosujemy następującą deklarację: z_idpracownik CHAR(7); to poprzez tak przydzieloną zmiennej nazwę, uzyskujemy podczas analizy kodu informację, iż zmienna ta prawdopodobnie będzie wykorzystana w programie do przechowywania numeru identyfikatora pracownika. Jest to oczywiste, pomimo że deklaracja tej zmiennej nie zawiera komentarza. Ponadto można wypracować pewne subiektywne reguły dotyczące choćby nadawania nazw zmiennym w programie. Regularne stosowanie tak wypracowanych, specyficznych reguł nazewnictwa zmiennych, może bardzo ułatwić zrozumienie kodu programu, a nawet przyśpieszyć tworzenie tego kodu. Należy przy tym pamiętać, że dopuszczalny rozmiar identyfikatora PL/SQL wynosi 30 znaków i każdy z nich może mieć znaczenie. Trzydzieści znaków pozwala na tworzenie opisowych nazw i taką ich konstrukcję według własnych zasad, które łatwo pozwalają na określenie przeznaczenia zmiennej w programie. Przykładowo, możemy stosować zasadę, według której pierwsza litera identyfikatora może mieć specyficzne znaczenie, jak np. w powyższym przypadku deklaracji, gdzie z wskazuje, iż identyfikatora z_idpracownik jest nazwą zmiennej, a np. identyfikator k_wszystkieprodukty może być nazwą kursora, gdyż pierwszą litera jest k. W ten sposób tak wypracowana reguła nazewnictwa zmiennych może informować nas o ich zastosowaniu. W tym celu, tak jak to zostało powyżej opisane, pierwsza litera zostaje oddzielona znakiem podkreślenia od pozostałej części nazwy zmiennej, np.: z_nazwazmiennej w_nazwawyjatku t_nazwatypu p_nazwaparametru s_wartoscstalej zmienna programu wyjątek zdefiniowany przez użytkownika typ zdefiniowany przez użytkownika parametr procedury lub funkcji zmienna ograniczona klauzulą CONSTANT Stosowanie tej reguły sprawia, iż kod staje się bardziej czytelny, nawet bez konieczności stosowania dodatkowych komentarzy służących do opisu przeznaczenia zmiennych w programie. 12

Stosowanie dużych liter Inną wypracowaną regułą, której stosowanie w programie, może pomóc w jego zrozumieniu, jest możliwość odpowiedniego stosowania dużych i małych liter w kodzie programu. Wprawdzie małe i wielkie litery nie są rozróżnione w programach PL/SQL, jednak ich zastosowanie może znacząco zwiększyć czytelność programu. W związku z tym w przykładowych blokach języka PL/SQL przedstawionych w ramach naszych rozważań zostały przestrzegane następujące zasady pisowni: słowa zastrzeżone są pisane wielkimi literami (np. BEGIN, DECLARE, ELSIF, itp.), funkcje wbudowane są pisane wielkimi literami (np. SUBSTR, COUNT, TO_CHAR, itp.), predefiniowane typy są pisane wielkimi literami (np. CHAR(5), NUMBER(7,2), BOOLEAN, DATE, itp.) słowa kluczowe SQL są pisane wielkimi literami (np. SELECT, INTO, UPDATE, WHERE, itp.), nazwy obiektów bazy danych są pisane małymi literami (np. osoby, zatrudnienia, itp.), do nazw zmiennych są stosowane wielkie i małe litery, przy czym wielką literą rozpoczyna się każde nowe słowo w nazwie (np. w_liczbaosob, t_typrekordosoba, itp.). Nie ma chyba większej potrzeby przekonywania, iż powyższe zasady czynią kod programu bardziej czytelny, o czym łatwo się przekonać analizując choćby przedstawione w dalszym ciągu naszych rozważań przykładowe programy języka PL/SQL. Stosowanie odstępów Inną użyteczną zasadą wykorzystaną do pisania kodu języka PL/SQL jest wykorzystanie znaków odstępu (znaków powrotu do nowego wiersza, spacji i tabulatorów). Jest to chyba jedna z najprostszych metod poprawienia czytelności programu. Ilustracją tego stwierdzenia jest choćby porównanie poniższych kodów programu z dwoma identycznie zagnieżdżonymi instrukcjami sterującymi IF-THEN-ELSE: IF x < y THEN IF z IS NULL THEN x:=3; ELSE x:=2; END IF; ELSE x:=4; END IF; IF x < y THEN IF z IS NULL THEN x:=3; ELSE x:=2; END IF; ELSE x:=4; END IF; 13

Ogólne uwagi dotyczące stylu programowania Podane powyżej ogólne zasady stylu pisania programów w języku PL/SQL, które zostały wykorzystane w przykładowych blokach tego języka podanych w ramach naszych rozważań, nie muszą być stosowane za wszelką cenę, chociaż na pewno mogą być użyteczne i przydatne. Oprócz tych powyżej podanych reguł można oczywiście wypracować i wprowadzić w procesie programowania własne zasady poprawiające zrozumienie pisanego kodu. Wiele firm zajmujących się tworzeniem oprogramowania posiada własne wytyczne dotyczące dokumentowania i tworzenia kodu. Zalecenia te mogą być stosowane dla różnych języków programowania, np. dobry styl programowania opracowany dla języka C może z powodzeniem zostać zaadaptowany również dla języka PL/SQL. Poniższa lista zawiera szereg wskazówek, które powinny ułatwić właściwe pisanie programów w języku PL/SQL. Tym niemniej można oczywiście nieco je zmodyfikować w zależności od potrzeb i własnych upodobań ważne jest w tym względzie ich przestrzeganie, aby kod programu był napisany jednolicie i tak sformatowany, by był już zrozumiały poprzez swój wygląd. Wskazówki odnośnie rozpoczęcia programowania w języku PL/SQL Należy przed samym przystąpieniem do pisania kodu opracować pewien zestaw zaleceń, które będą w sposób jasny określać wygląd poprawnego kodu PL/SQL. Należy określić wszystkie dane wejściowe i wyjściowe dla aplikacji, która zamierzamy napisać, a następnie należy wyróżnić te zdarzenia, które powinny być śledzone oraz te, na które powinna nastąpić odpowiednia reakcja z naszej strony. Projektowana aplikacja, w zależności od swego rozmiaru, powinna być podzielona na części, z których każda będzie wykonywała jakieś wydzielone, logicznie odrębne zadanie. Potem każda z tych części, każdy z modułów aplikacji, powinien być przetestowany osobno, zanim zostaną połączone w jedną całość. Należy zawsze formatować nowotworzony kod programu np. stosować wcięcia wierszy ułatwia to przeszukiwanie kodu, np. w celu lokalizacji błędów. Należy wypracować własny system nazewnictwa zmiennych, stałych, procedur, funkcji, elementów lokalnych i globalnych. Taki wypracowany przez siebie styl nazewnictwa różnego rodzaju obiektów języka PL/SQL pozwala na jednoznaczne określenie ich typu i odpowiednie zastosowanie takiego elementu w programie. Pozwoli to uniknąć wielu przykrych niespodzianek związanych z nieodpowiednim wykorzystaniem zaprojektowanych przez siebie obiektów, co spowodowane mogłoby być nierozpoznaniem ich ze względu na nieodpowiednie nazewnictwo, np. wywołanie w programie wyzwalacza zamiast funkcji. Należy, o ile tylko to możliwe, używać deklaracji zmiennych języka PL/SQL zawierających %TYPE oraz %ROWTYPE. Należy wykorzystywać instrukcję ELSIF, zamiast szeregu zagnieżdżonych instrukcji IF, we wszystkich tych miejscach w programie, gdzie to tylko możliwe. Taki sposób postępowania uchroni między innymi przed sytuacjami, w których w takim zagnieżdżonym ciągu instrukcji IF kilkakrotnie pojawia się ten sam warunek. 14

Należy używać instrukcji CASE, zamiast ciągu następujących po sobie instrukcji IF. Taki sposób postępowania upraszcza zarówno samo pisanie kodu, jak i jego późniejszą analizę i obsługę. Należy używać pętlę FOR we wszystkich tych przypadkach, gdy istnieje potrzeba przetworzenia wszystkich operacji od początku do końca pętli. Natomiast nie należy używać pętli FOR jako pętli, której liczba wykonań jest uzależniona od spełnienia jakiegoś warunku. Należy unikać przerywania instrukcji w pętlach. Jeśli zaistnieje potrzeba zakończenia działania pętli w momencie, który nie jest możliwy z góry do przewidzenia, to należy, zamiast pętli FOR, używać pętli WHILE, która jest przerywana instrukcją EXIT. W przypadku przetwarzania dużej porcji danych, należy ją podzielić na mniejsze części. W takim przypadku otrzymamy możliwość zatwierdzania ich partiami albo też wycofania się w błędnym przypadku. Ponadto taki sposób przetwarzania dużej porcji danych sprawia, iż częściej zwalniane są założone blokady, a zatem w danym momencie blokowana jest mniejsza partia danych. Wskazówki o programowania w języku PL/SQL - kursory Wskazówki i informacje praktyczne dotyczące użycia kursorów w programach języka PL/SQL: W przypadku, gdy zapytanie SELECT zwraca wiele wierszy to w celu uzyskania dostępu do nich należy bezwzględnie wykorzystywać kursory zwracające wiele wierszy, które są właśnie wynikiem takiego zapytania. Do poszczególnych (rekordów) wyników można się odwoływać w programie języka PL/SQL, przetwarzając po kolei wartości zwracane przez kursor takiego typu. Rozwiązanie takie jest zdecydowanie bardziej wydajne niż wielokrotne użycie kursorów zwracających po jednym wierszu. W przypadku wykorzystania kursorów niejawnych należy zawsze sprawdzać wartości atrybutów SQL%. W ten sposób uzyskujemy informację, czy instrukcje DML zawarte w programie PL/SQL wykonały się w sposób poprawny. Ponadto należy używać klauzulę RETURNING w celu uzyskania informacji, czy operacje wstawiania lub modyfikacji rekordów zakończyły się sukcesem. W tym celu można z powodzeniem wykorzystać atrybuty kursora SQL%FOUND, SQL%NOTFOUND czy też SQL%ROWCOUNT, a nie powinno się stosować konstrukcji SELECT COUNT(*). Również konstrukcje SELECT...INTO, stosowane dość często w sposób nadmiarowy w programach języka PL/SQL, mogą zostać z nich wyeliminowane poprzez użycie wspomnianych powyżej atrybutów kursora. W przypadku kursorów jawnych wykorzystywanych poza pętla FOR kursora należy pamiętać o wykonywani na nich takich operacji jak: OPEN, FETCH (jeśli występuje taka konieczność to wewnątrz pętli LOOP) i CLOSE (należy bezwzględnie pamiętać przy takim wykorzystaniu kursorów jawnych o ich jawnym zamknięciu). Należy zawsze przestrzegać reguły, iż należy pobierać dane z kursora do rekordów zadeklarowanych jako zmienne tego samego typu, co wynik działania kursora. W tym celu można do zadeklarowania rekordu wykorzystać konstrukcję: nazwa_kursora%rowtype. Należy raczej unikać pobierania z kursora wartości, które zostaną przypisane do szeregu pojedynczych zmiennych. W szczególności w przypadku kursorów postaci SELECT * należy używać zmiennych zadeklarowanych jako nazwa_tabeli%rowtype. Takie rozwiązanie 15

pozwala uniknąć wielu błędów zarówno podczas pisania programu w języku PL/SQL, jak i później, podczas modyfikowania schematu bazy danych. Także nie bez znaczenia jest fakt, że uzyskany w ten sposób kod programu jest o wiele czytelniejszy i ułatwia wyszukiwanie ewentualnych błędów. Kursor w pętli FOR kursora należy używać tylko w takim przypadku, gdy chcemy przetwarzać wszystkie wiersze zwracane przez ten kursor. Jeżeli z jakiegoś powodu przewidujemy, że program będzie przetwarzał tylko niewielką liczbę początkowych wierszy lub też pominie wiele wierszy, należy w takim przypadku używać instrukcji OPEN, FETCH i CLOSE. W przypadku, gdy chcemy przetwarzać wszystkie wiersze zwracane przez kursor wewnątrz pętli FOR kursora, to w takim przypadku należy deklaracje kursora należy umieścić w samej pętli FOR, a nie w bloku deklaracji (tzw. niejawny sposób deklarowania kursora w pętli FOR). W przypadku aplikacji języka PL/SQL, która ma się wykonywać po stronie klienta bazy danych, należy w miarę możliwości starać się używać kursorów jawnych zamiast konstrukcji SELECT...INTO. Wynika to z faktu, iż taki tryb postępowania zmniejszy liczbę dostępów do bazy danych dokonujących sprawdzenia, czy nie wystąpił w programie wyjątek TOO_MANY_ROWS lub NO_DATA_FOUND. Nigdy nie należy zatwierdzać ani też nie próbować operacji wycofania podczas przetwarzania kursora związanego z zapytaniem SELECT FOR UPDATE. Te dwie operacje należy wykonywać przed albo po wykonaniu wszystkich operacji na takim kursorze. W przypadku stosowania polecenia FETCH, natychmiast po jego wykonaniu należy sprawdzać wartość atrybutu %NOTFOUND. Wynika to z faktu, iż w przypadku niepowodzenia zostanie natychmiast przerwane wykonywanie pętli związane z przetwarzaniem danych pochodzących ze zbioru wartości zwracanych przez ten kursor. Natomiast w przypadku użycia większej liczby instrukcji FETCH w celu pobrania większego zbioru danych, należy po każdej takiej instrukcji FETCH zdefiniować warunek EXIT WHEN nazwa_kursora%notfound. Należy bezwzględnie zawsze przestrzegać zasady zamykania wszystkich otwartych kursorów, niezależnie od tego, czy program w języku PL/SQL kończy się bezbłędnie czy też podczas jego wykonywania wystąpiły błędy. Wykonanie operacji zamknięcia wszystkich otwartych kursorów można zawsze przecież dokonać w bloku obsługi wyjątków. Takie sposób postępowania pozwala na zwolnienie zasobów pamięci zarezerwowanych dla niepotrzebnych już w tym momencie, ale ciągle jeszcze otwartych kursorów. Należy pamiętać o tym. iż zmienne kursorowe i kursory nie są pojęciami, które można utożsamiać i tym samym stosować wymiennie. A zatem, jeśli z kontekstu programu wynika konieczność zastosowania zmiennej kursorowej, to w tym miejscu nie można zamiennie wstawić kursora i na odwrót, jeśli w danym miejscu programu powinien wystąpić kursor, to nie należy w tym miejscu wstawiać zmiennej kursorowej. Zmienną kursorową należy wykorzystywać w celu zwracania zbiorów wyników działania podprogramu. W takim przypadku należy zdefiniować odpowiedni typ REF CURSOR w pakiecie. Tym niemniej należy również 16

pamiętać o tym, iż po przekazaniu zmiennej kursorowej jako parametru do podprogramu, nie powinno się jej otwierać wewnątrz tego podprogramu. Zalecanym jest używanie wyrażeń z kursorami, aby wyeliminować złożone połączenia wewnątrz zapytań definiujących te kursory. Wskazówki o programowania w języku PL/SQL rekordy Wskazówki i informacje praktyczne dotyczące wykorzystania rekordów w programach języka PL/SQL: Należy chronić definicje typów rekordowych przed niepowołanym dostępem i w tym celu umieszczać je w pakietach. W trakcie wykonywania operacji dostępu do poszczególnych elementów składowych typu rekordowego należy pamiętać o tym, iż należy używać nazwy zmiennej typu rekordowego, a nie nazwy samego typu. Zalecanym postępowaniem jest wykonywanie przypisania dla grupy pól zmiennych typu rekordowego, zamiast szeregu przypisywań dla poszczególnych pól tej zmiennej. W ten sposób można zaoszczędzić sporo czasu, a poza tym kod programu będzie dużo czytelniejszy. Zalecanym jest używanie rekordów zdefiniowanych jako nazwa_tabeli%rowtype we wszystkich typ przypadkach, gdzie istnieje potrzeba przypisania wartości wszystkich kolumn do odpowiednich zmiennych. Taki sposób ma również tę zaletę, iż wszelkie zmiany w strukturze tabeli zostaną automatycznie uwzględnione w odpowiednich zmiennych rekordowych. Zalecanym jest używanie zmiennych rekordowych w poleceniach INSERT i UPDATE. Pozwala to m.in. uniknąć błędów TOO_MANY_VARIABLES. Wskazówki o programowania w języku PL/SQL tabele indeksowe Wskazówki i informacje praktyczne dotyczące użycia tabel indeksowych w programach języka PL/SQL: Należy chronić definicje typów tabel indeksowych przed niepowołanym dostępem i w tym celu umieszczać je w pakietach. W celu przekształcenia tabel baz danych do odpowiednich struktur języka PL/SQL należy w tym celu wykorzystywać właśnie tabele indeksowe. W celu przekształcenia tabeli indeksowej w szereg poszczególnych wierszy należy wykorzystać pętle. Należy używać grupowe przypisania do pól tabeli indeksowej zamiast szeregu pojedynczych przypisań do poszczególnych pól. Tabele wymiarowe można symulować, używając do tego celu określonej liczby tabel indeksowych. W celu uzyskania dostępu do odpowiednich elementów tabel indeksowych należy wykorzystywać metody FIRST, LAST i NEXT. 17

W celu przechowywania tabel indeksowych zawierających pola typu VARCHAR2 należy wykorzystywać tzw. tabele asocjacyjne. Taki sposób postępowania umożliwia zwiększenie efektywności wyszukiwania poszczególnych elementów takiej tabeli. Wskazówki o programowania w języku PL/SQL obsługa błędów Wskazówki i informacje praktyczne dotyczące eleganckiego sposobu obsługiwania błędów w programach języka PL/SQL: Należy podzielić błędy na kategorie poprzez przydzielenie ich do wywoływania wyjątków systemowych, niepredefiniowanych błędów Oracle, wyjątków zdefiniowanych przez użytkownika oraz błędów języka PL/SQL definiowanych przez użytkownika. Należy wczytywać błędy do specjalnie do tego celu utworzonej tabeli zawierającej przynajmniej takie dane, jak kod błędu i jego opis. Należy zdefiniować wyjątki użytkownika do przechwytywania błędów specyficznych dla danej aplikacji. Dodatkowo można zdefiniować specyficzne komunikaty o błędach, ostrzeżenia oraz informacje oraz obsługiwać każdy z nich w odpowiedni dla niego sposób. Nie należy używać EXCEPTION_INIT, aby skojarzyć niepredefiniowane błędy Oracle z własnymi wyjątkami. Zamiast tworzenia procedury wykorzystującej wywołanie RAISE_APPLICATION_ERROR, można wykorzystywać mechanizm zgłaszania komunikatów o błędach w języku PL/SQL. Jednak w celu informowania o niektórych błędach należy wykorzystywać RAISE_APPLICATION_ERROR. W takim przypadku trzeba określić dalszy sposób postępowania programu po występowaniu takiego błędu. Częstym postępowaniem w takim przypadku jest po prostu wyświetlenie komunikatu o błędzie i dalsze kontynuowanie pracy, a czasami program powinien natychmiast zakończyć swoje działanie. Należy pamiętać o korzyściach, jakie niesie ze sobą wykorzystanie RAISE_APPLICATION_ERROR do obsługi niektórych błędów. Polecenie to nie tylko wstrzymuje działanie podprogramu i zgłasza odpowiedni wyjątek, ale również zwraca kod błędu i odpowiedni komunikat o nim w zmiennych SQLCODE i SQLERRM. Należy definiować procedury obsługi tylko dla tych wyjątków, które mogą wystapić w danym fragmencie programu PL/SQL. Wyjątki użytkownika powinno się definiować wewnątrz pakietów, co spowoduje, iż wszyscy z nich będą mogli korzystać. Należy pamiętać o zasadzie, iż nie należy wielokrotnie definiować tych samych wyjątków wewnątrz zagnieżdżonych bloków programu. Natomiast każdy ze zdefiniowanych tak wyjątków należy obsługiwać w przeznaczonym dla niego bloku obsługi. Nie należy też nigdy wiązać więcej niż jednego wyjątku z jednym numerem błędu. Należy zachować szczególną ostrożność przy wyjątkach wywoływanych w bloku deklaracji oraz w przypadku bloków obsługi wyjątków zagnieżdżonych w blokach wykonywalnych PL/SQL. 18

Zalecanym sposobem obsługi wyjątków jest definiowanie w każdej sekcji obsługi wyjątków predefiniowanego wyjątku WHEN OTHERS. Taki sposób postępowania umożliwia obsługę tych błędów, które nie zostały jawnie obsłużone w ramach danej sekcji. W takim przypadku należy również wykorzystać zmienne SQLCODE i SQLERRM, aby uzyskać informacje o tym, jaki wyjątek jest aktualnie obsługiwany. Nigdy nie należy deklarować własnych wyjątków o nazwach identycznych z nazwami wyjątków z nazwami wyjątków predefiniowanych w systemie Oracle. Należy wypracować swój własny, jednolity styl nadawania nazw własnym wyjątkom. W większości przypadków, gdy mamy do czynienia z zagnieżdżonymi blokami, wystarczy zdefiniować obsługę wyjątku WHEN OTHERS tylko na najwyższym poziomie programu PL/SQL. Wskazówki o programowania w języku PL/SQL podprogramy Poniższe wskazówki i informacje praktyczne stanowią standardy pisania podprogramów w języku PL/SQL: Projektując strukturę programu w języku PL/SQL, należy go podzielić na podprogramy (o ile jest to konieczne), wydzielając specyficzne funkcje oraz umieszczając logicznie powiązane fragmenty w odpowiednich pakietach. Taki sposób postępowania jest zalecany z uwagi na zalety stosowania pakietów, które wynikają z ich własności. Pakiety pozwalają m.in. na odizolowanie kodu wykonywalnego od innych programów. Należy również pamiętać o takiej zalecie pakietów, iż podczas deklarowania zmiennych globalnych i kursorów zmianie ulega tylko specyfikacja pakietu, a jego struktura wewnętrzna pozostaje bez zmian. W przypadku wprowadzania jakichkolwiek zmian do pakietu, należy wykorzystywać w tym celu polecenie CREATE OR REPLACE, co pozwala uniknąć dublowania pakietów. Należy przeciążać podobne podprogramy, tj. podprogramy które różnią się tylko typami lub liczbą parametrów. W podprogramach typu funkcja nie należy używać wielu instrukcji RETURN. Należy raczej starać się stosować zmienne lokalne do przechowywania wyniku i wielu instrukcji warunkowych, aby wyliczyć te wartość, którą na końcu zwraca instrukcja RETURN. Nie należy używać parametrów wyjściowych w funkcjach. Jeżeli podprogram powinien zwrócić wiele wartości, to lepiej zastosować w miejsce funkcji procedury z wieloma parametrami wyjściowymi. W przypadku do czynienia z zapytaniami, które zwracają wiele wierszy, należy zdefiniować je w specyfikacji pakietu jako kursory. Innym rozwiązaniem jest zdefiniowanie tego rodzaju zapytania jako REF CURSOR, zwłaszcza w przypadku, gdy wynik takiego zapytania ma być przekazany do podprogramu. Natomiast zawsze należy używać zmiennych kursowych zdefiniowanych w pakiecie do przekazywania wyników działania podprogramów. Dzięki takiemu zabiegowi definicje zmiennych kursorowych nie są wymuszane przez podprogramy. Należy pamiętać o tym, aby przy usuwaniu podprogramów zachować szczególną ostrożność, a szczególnie zwrócić uwagę na powiązania pomiędzy obiektami. 19

W celu zwiększenia wydajności programu należy, we wszystkich przypadkach przekazywania dużych danych jako parametry (podprogramów), używać parametry przekazywane przez odwołania z wykorzystaniem NOCOPY. Należy używać uprawnień obiektowych, w celu osiągnięcia celu, jakim jest centralizacja kodu i decentralizacja danych. Należy używać zmienne pakietowe w celu definiowania stałych języka PL/SQL i zawsze należy definiować metody odpowiedzialne za odczyt i ustawianie wartości tych zmiennych. Natomiast w celu nadania wartości wszystkim zmiennym niezbędnym do prawidłowej pracy podczas danej sesji, należy wykorzystać w tym celu sekcję inicjalizacyjną pakietu. Należy pamiętać o tym, aby w sposób jawny przypisywać wartości do parametrów wyjściowych procedur. Należy korzystać z tzw. pierwotnej kompilacji kodu PL/SQL podczas pisania podprogramów wymagających wielu obliczeń używanych do zadań niezależnych od bazy danych. Pierwotna kompilacja daje w takim przypadku szybsze wykonanie kodu PL/SQL. Wskazówki o programowania w języku PL/SQL triggery Wskazówki i informacje praktyczne, które mogą być przydatne przy wykorzystaniu triggerów języka PL/SQL: Należy wykorzystywać możliwość śledzenia zmian w tabelach na poziomie pojedynczych wierszy i możliwości propagowania tych zmian do odpowiednich tabel zawierających historię operacji. W celu śledzenia operacji DDL język PL/SQL oferuje narzędzie w postaci triggerów, które reagują na odpowiednie zdarzenia użytkownika. Należy wypracować swój własny, jednolity styl dotyczący nazywania triggerów powinien on również różnić się od nazewnictwa stosowanego w przypadku nazywania innych obiektów bazy danych. Należy pamiętać o tym, aby mieć na uwadze to, aby blok wykonywalny zaprojektowanego triggera nie przekraczał maksymalnych rozmiarów przewidzianych dla bloku wykonywalnego. Zamiast pisać wiele triggerów reagujących na różne operacje DML, należy postarać się tworzyć takie, które będą reagowały na wiele instrukcji DML, a wynik ich działania będzie uzależniony od rodzaju akcji powodującej ich uruchomienie. Zawsze należy tworzyć takie triggery, które będą starały się w maksymalnym stopniu zabezpieczyć obiekty bazy danych przed możliwością przypadkowych modyfikacji czy naruszenia więzów integralności. Dla operacji DML wykonywanych na perspektywach należy wykorzystywać triggery typu INSTEAD-OF. Dobrym rozwiązaniem jest zaprojektowanie triggera, którego zadaniem jest dokonywanie analizy tabel, a ponadto zbieranie informacji statystycznych w momencie, gdy użytkownik loguje się do bazy danych. Należy przestrzegać zasadę, która mówi, iż nie należy definiować triggerów tego samego typu na różnych poziomach, a ponadto nie należy definiować wielu triggerów reagujących na tę samą akcję. 20