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

advertisement
2010-11-10
Plan wykładu





BAZY DANYCH II
WYKŁAD 3

Zasięg zmiennych
Zmienne powiązane
Instrukcje warunkowe
Pętle
Pobieranie danych – SQL w PL/SQL
Rekordy
dr inż. Agnieszka Bołtuć
Zasięg zmiennych




Zmienna jest dostępna tylko w bloku, w którym
jest zadeklarowana,
Kiedy zmienna wychodzi z zasięgu, system
zwalnia i pamięć i takiej zmiennej nie można
używać,
Zmienna z bloku zagnieżdżonego jest
niewidoczna w bloku zewnętrznym,
Zmienna zadeklarowana w bloku zewnętrznym
jest widoczna w bloku zagnieżdżonym.
Zasięg zmiennych
v_nazwa dostępna jest
DECLARE
w całym bloku
v_nazwa VARCHAR2(20);
BEGIN
DECLARE
v_druga_nazwa VARCHAR2(20);
BEGIN
v_druga_nazwa dostępna jest
…
w bloku zagnieżdżonym
END;
END;
1
2010-11-10
Widoczność zmiennych


Gdy mam dwie zmienne o tych samych
nazwach zadeklarowane w bloku
zewnętrznym i zagnieżdżonym to zmienna ta
jest ukryta w bloku wewnętrznym,
Można to rozwiązać używając etykiet.
Etykiety
<<l_zewnetrzna>>
DECLARE
v_nazwa VARCHAR2(20);
BEGIN
DECLARE
v_nazwa NUMBER(2);
BEGIN
l_zewnetrzna.v_nazwa:=’blok_zew’;
DBMS_OUTPUT.PUT_LINE(l_zewnetrzna.v_nazwa);
END;
END;
Widoczność zmiennych
DECLARE
v_nazwa VARCHAR2(20);
BEGIN
DECLARE
v_nazwa VARCHAR2(20);
BEGIN
…
END;
END;
Zmienne powiązane




tzw. zmienne środowiskowe, podobne
własności do zmiennych globalnych,
Widoczne i dostępne w wielu programach,
Często używane są do przekazywania
wartości z PL/SQL do SQL, do optymalizacji
zapytań,
W PL/SQL zachowują się jak zwykłe zmienne.
2
2010-11-10
Zmienne powiązane
Zmienne powiązane - przykład
deklaracja
VARIABLE nazwa typ_danych;

VARIABLE v_imie VARCHAR2(20);
BEGIN
SELECT first_name INTO :v_imie
FROM employees WHERE employee_id=200;
END;
/
PRINT v_imie;
Zmienne powiązane - przykład
Zmienne powiązane - przykład
VARIABLE v_imie VARCHAR2(20);
BEGIN
:v_imie :=’LEX’;
END;
/
PRINT v_imie;
SELECT last_name FROM employees
WHERE first_name= :v_imie;
VARIABLE v_imie VARCHAR2(20);
SET AUTOPRINT ON;
BEGIN
automatyczne włączenie wyświetlania
zmiennych powiązanych
:v_imie :=’LEX’;
END;
/
SELECT last_name FROM employees
WHERE first_name= :v_imie;

odwołanie do zmiennej
:nazwa

wyświetlenie zawartości zmiennej
PRINT nazwa;
3
2010-11-10
Struktury sterujące

Wykonywanie warunkowe

Wykonywanie w pętli

Nawigacja sekwencyjna
IF-THEN-ELSE
IF warunek THEN
operacje;
[ELSE
operacje;]
END IF;
IF-THEN
IF warunek THEN
operacje;
END IF;
DECLARE
v_wiek NUMBER := 19;
BEGIN
IF v_wiek>=18 THEN
DBMS_OUTPUT.PUT_LINE(’Jesteś pełnoletni’);
END IF;
END;
IF-THEN-ELSE
DECLARE
v_wiek NUMBER := 19;
BEGIN
IF v_wiek>=18 THEN
DBMS_OUTPUT.PUT_LINE(’Jesteś pełnoletni’);
ELSE
DBMS_OUTPUT.PUT_LINE(’Nie jesteś pełnoletni’);
END IF;
END;
4
2010-11-10
IF-THEN-ELSEIF
IF warunek THEN
operacje;
[ELSIF warunek THEN
operacje;]
[ELSE
operacje;]
END IF;
IF-THEN-ELSEIF
DECLARE
v_wiek NUMBER := 19;
BEGIN
IF v_wiek<18 THEN
DBMS_OUTPUT.PUT_LINE(’Nie jesteś pełnoletni’);
ELSIF v_wiek<40 THEN
DBMS_OUTPUT.PUT_LINE(’Nie jesteś w średnim wieku’);
ELSE
DBMS_OUTPUT.PUT_LINE(’Jesteś stary’);
END IF;
END;
NULL w instrukcji IF
CASE
DECLARE
Jeśli wyrażenie IF zwraca NULL to sterowanie
jest przekazywane do ELSE
v_wiek NUMBER;
BEGIN
IF v_wiek>=18 THEN
DBMS_OUTPUT.PUT_LINE(’Jesteś pełnoletni’);
END IF;
END;


Od wersji 9i,
Alternatywa warunkowego wykonywania kodu,
upraszczająca składnię,
CASE warunek
WHEN test1 THEN operacje;
WHEN test1 THEN operacje;
…
[ELSE operacje;]
END CASE;
5
2010-11-10
CASE
DECLARE
v_ocena VARCHAR2(1);
v_ocena_konw NUMBER(1);
BEGIN
SELECT ocena INTO v_ocena FROM uczen WHERE
przedmiot=’algebra’ and id=’11234’;
CASE v_ocena
WHEN ’A’ THEN v_ocena_konw:=5;
WHEN ’B’ THEN v_ocena_konw:=4;
…
ELSE v_ocena_konw:=0;
END CASE;
END;
CASE z wyszukiwaniem



W takiej konstrukcji nie trzeba przekazywać
wyrażenia na początku instrukcji CASE,
Każda klauzula WHEN przyjmuje wyrażenie,
którego wartość trzeba sprawdzić,
Można podawać albo to samo wyrażenie w
każdej klauzuli WHEN, lub za każdym razem
inne.
CASE z wyszukiwaniem
Wykonywanie w pętli
CASE
WHEN v_dochod<85000 THEN
v_podatek:=dochod*0.18;
WHEN v_dochod>=85000 THEN
v_podatek:=85000*0.18+(v_dochod-85000)*0.32;
ELSE
DBMS_OUTPUT.PUT_LINE(’Brak dochodu’);
END CASE;

Pętle proste

Pętle liczbowe FOR

Pętle WHILE
6
2010-11-10
Pętle proste
LOOP
operacje;
EXIT [WHEN warunek];
END LOOP;
Pętla FOR
FOR licznik IN [REVERSE]
liczba_porzadkowa..liczba_koncowa
LOOP
operacje;
END LOOP;
Pętle proste
DECLARE
v_licznik PLS_INTEGER :=1;
BEGIN
LOOP
DBMS_OUTPUT.PUT_LINE(’Wiersz numer’ ||
v_licznik);
v_licznik:=v_licznik+1;
EXIT WHEN v_licznik=10;
END LOOP;
END;
Pętla FOR
BEGIN
FOR v_licznik IN 1..9 LOOP
DBMS_OUTPUT.PUT_LINE(’Wiersz numer’ ||
v_licznik);
END LOOP;
END;
7
2010-11-10
Pętla WHILE
Pętla WHILE
DECLARE
v_licznik PLS_INTEGER :=1;
BEGIN
WHILE v_licznik<10 LOOP
DBMS_OUTPUT.PUT_LINE(’Wiersz numer’ ||
v_licznik);
v_licznik:=v_licznik+1;
END LOOP;
END;
WHILE warunek
LOOP
operacje;
END LOOP;
Pętle i etykiety


Pętle i etykiety
Umożliwiają korzystanie z pętli tak, jakby miały
nazwę,
Nazywają nienazwane elementy języka
PL/SQL,
<<nazwa_petli>>
pętla, instrukcje
END LOOP nazwa_petli;

Wówczas możemy używać konstrukcji typu:
EXIT nazwa_petli;
EXIT nazwa_petli WHEN v_licznik=10;
opcjonalne
8
2010-11-10
CONTINUE




Dodatkowe sterownie pętlą,
Przekazuje sterowanie do następnej iteracji,
Od wersji 11g,
Można używać w połączeniu z etykietami.
BEGIN
FOR i IN 1..10 LOOP
DBMS_OUTPUT.PUT_LINE( i );
CONTINUE WHEN i> 5 ;
DBMS_OUTPUT.PUT_LINE(’tylko mniejsze, rowne 5′);
END LOOP;
END;
Polecenie SELECT
SQL w PL/SQL



Polecenie SELECT

SELECT lista_wyboru
[INTO lista_zmiennych]
FROM lista_tabel
[WHERE warunki]
[ORDER BY lista_kolumn];
PL/SQL nie wspiera bezpośrednio poleceń
DDL i DCL, w tym celu należy używać
dynamicznego SQL,
PL/SQL wspiera także polecenia z zakresu
obsługi transakcji,
Do pobierania danych służy polecenie
SELECT.




Lista_wyboru – kolumny, łańcuchy, funkcje
SQL, *, operacje arytmetyczne,
Lista_zmiennych – zmienna lub grupa
zmiennych odpowiadających wartościom z
listy wyboru, typy skalarne, zakotwiczone lub
rekordy,
Lista_tabel – tabele, widoki,
Pobrane wartości muszą trafić do zmiennej za
pomocą INTO,
Polecenie musi zwracać pojedynczy wiersz.
9
2010-11-10
Polecenie SELECT
Polecenie SELECT
DECLARE
v_salary employees.salary%TYPE;
v_last_name employees.last_name%TYPE;
BEGIN
SELECT last_name, salary
INTO v_last_name, v_salary
FROM employees
WHERE employees_id=105;
DBMS_OUTPUT.PUT_LINE(’Pracownik’||v_last_name);
DBMS_OUTPUT.PUT_LINE(’Zarabia’||v_salary);
END;
DECLARE
v_salary employees.salary%TYPE;
v_jobs employees.job_id%TYPE :=’IT_PROG’;
BEGIN
SELECT AVG(salary)
INTO v_salary
FROM employees
WHERE job_id=v_jobs;
DBMS_OUTPUT.PUT_LINE(’Na stanowisku’||v_jobs);
DBMS_OUTPUT.PUT_LINE(’Średnia płaca wynosi’||v_salary);
END;
Rekordy
Rekordy




Zbiór zmiennych różnych typów,
Wprowadzone w bazie danych Oracle 7,
Typami pól rekordu mogą być wszystkie typy
danych dostępne w Oracle , zdefiniowane
przez użytkownika oraz kolekcje,
Bardzo często zawartość rekordów jest
wzorowana na strukturze tabel z bazy danych,





Może mieć dowolną liczbę pól,
Pola mogą mieć zainicjowaną wartość oraz
być zdefiniowane jako NOT NULL,
Są definiowane w części deklaracyjnej bloków,
funkcji czy procedur,
Mogą być zagnieżdżone,
Definiowane za pomocą atrybutu
%ROWTYPE lub jawnie.
10
2010-11-10
%ROWTYPE
Powoduje dziedziczenie definicji wierszy po
kursorach, tabelach, obiektach lub widokach,
Nazwy i typy pól rekordu są tworzone na
podstawie wskazanego wiersza,
Definicja jawna
DECLARE
v_employee employees%ROWTYPE;
v_jobs jobs%ROWTYPE;
Definiowanie typu rekordowego
TYPE nazwa_rec IS RECORD
(deklaracja_pola [,deklaracja_pola]…);
 Definiowanie zmiennej typu rekordowego
Identyfikator nazwa_rec;
 Deklaracja pola
nazwa_pola {typ | tabela.kolumna%TYPE |
tabela%ROWTYPE}
[[NOT NULL] { := | DEFAULT } wyrażenie]
Deklaracja jawna
Inicjowanie wartości pól
DECLARE
TYPE r_emp IS RECORD
(v_numer NUMBER(2),
v_pensja NUMBER(8) :=1000,
v_zatrudnienie employees.hire_date%TYPE,
v_spis jobs%ROWTYPE);
BEGIN
v_my_rec.v_pensja:=v_my_rec.v_pensja+200;
v_my_rec.v_zatrudnienie:=sysdate;
v_my_rec.v_numer:=1;
v_my_rec r_emp;
BEGIN
…
END;
DBMS_OUTPUT.PUT_LINE(v_my_rec.v_numer ||
v_my_rec.v_spis.last_name ||
TO_CHAR(v_my_rec.v_zatrudnienie ||
TO_CHAR(v_my_rec.v_pensja) );
END;


DECLARE
identyfikator tabela%ROWTYPE;

SELECT * INTO v_my_rec.v_spis
FROM employees WHERE employee_id=105;
11
2010-11-10
Zagnieżdżanie


Do tworzenia złożonych typów rekordowych
można używać tylko jawnej definicji,
Nie ma ograniczeń w zagnieżdżaniu, jeśli
chodzi o poziomy,
Wstawianie rekordu do tabeli
DECLARE
v_rec employees%ROWTYPE;
BEGIN
SELECT * INTO v_rec FROM employees
WHERE employee_id=105;
INSERT INTO new_employees VALUES
(v_rec.employee_id, v_rec.first_name, v_rec.last_name, …);
END;
Wstawianie rekordu do tabeli
Modyfikacja za pomocą rekordów
DECLARE
v_rec employees%ROWTYPE;
DECLARE
v_rec employees%ROWTYPE;
v_hire_date employees.hire_date%TYPE;
BEGIN
BEGIN
SELECT * INTO v_rec FROM employees
WHERE employee_id=105;
SELECT * INTO v_rec FROM employees
WHERE employee_id=105;
v_rec.hire_date:=sysdate;
INSERT INTO new_employees VALUES v_rec;
UPDATE employees SET ROW = v_rec
WHERE employee_id=105;
END;
END;
12
2010-11-10
Wykorzystana literatura



J. Price, Oracle Database 11g i SQL.
Programowanie. Helion, 2009.
S. Urman, R. Hardman, M. McLaughlin, Oracle
Database 10g. Programowanie w języku
PL/SQL. Helion, 2008.
www.oracle.com
13
Download