1. PL/SQL (Procedural Extension to
SQL)
E’ un linguaggio procedurale a tutti gli effetti come Ada,
Algol, C, Pascal, Fortran… Per questo fornisce un importante
supporto a SQL che non permette di realizzare strutture di
controllo complesse e cicli. Per altro all’interno del codice
PLSQL si fa largo uso di istruzioni SQL e di funzioni e tipi di
dati già implementati in Oracle.
In Oracle PL/SQL viene usato per creare Stored Procedure
sul server, poi invocate dai client (java, VB,…). Ma può
anche girare sui client come nel caso di Oracle Form.
2. Hello World
BEGIN
DBMS_OUTPUT.PUT_LINE('hello, world');
END;
Si tratta di un Blocco senza nome che esegue una stored procedure PUT_LINE
contenuta nel package predefinito DBMS_OUTPUT in SQL*PLUS per abilitare l’output è
necessario impostare:
SET SERVEROUTPUT ON
(E’ anche possibile salvare lo script in un file hello.sql per poi invocarlo scrivendo
@help)
3. Blocchi
Ci sono 3 tipi di blocchi:
Anonimi
Procedure
Function
Ogni blocco può contenere le seguenti sezioni:
Header: Definizione del blocco -> manca nei blocchi anonimi
Declaration: Dichiarazione delle variabili
Execution: Corpo del blocco con le istruzion
Exception handling:Gestione delle eccezioni
(E’ possibile avere blocchi innestati all’interno di altri nested blocks)
4. IF
IF salary BETWEEN 10000 AND 40000
THEN
bonus := 1500;
ELSIF salary > 40000 AND salary <= 100000
THEN
bonus := 1000;
ELSE bonus := 0;
END IF;
5. CASE Semplice
CASE voto
WHEN 5 THEN bonus := 1500;
WHEN 6 THEN bonus := 2000;
WHEN 7 THEN bonus := 10000;
ELSE bonus := 0
END CASE;
(In questo caso è possibile solo un confronto di uguaglianza)
6. CASE Avanzato
CASE
WHEN salary BETWEEN 10000 AND 40000
THEN bonus := 1500;
WHEN salary > 40000 AND salary <= 100000 THEN bonus := 10000;
ELSE bonus
END CASE;
(In questo caso manca il selector di fianco al CASE:
è possibile effettuare selezioni complesse)
8. FOR
FOR month_num IN 1 .. 6
LOOP show_books_borrowed (month_num);
END LOOP;
(E’ possibile scorrere all’inverso con
FOR i REVERSE IN 1..10)
9. CICLO GENERICO
counter := 0;
LOOP
counter := counter + 1;
prior_approx := approx;
approx := new_approx(approx);
EXIT WHEN counter = 1000 OR prior_approx - approx = 0.0;
END LOOP;
(Il ciclo è infinito, ma si ha una riga di uscita EXIT WHEN..)
10. WHILE
prior_approx := approx;
approx := new_approx(approx);
counter := 0;
WHILE counter <= 1000 AND prior_approx - approx != 0.0
LOOP
counter := counter + 1;
prior_approx := approx;
approx := new_approx(approx);
END LOOP;
(In realtà il CICLO generico può essere usato sempre e mostra una
flessibilità notevole anche se può essere meno leggibile)
11. CONVENZIONI
Il linguaggio è case-insensitive, ma la convenzione vuole:
Parole chiave e tipi di dati in maiuscolo
Variabili e funzionoi dell’utente in minuscolo
L’uso del ‘underscore’ _ per separare le parole distinte nei nomi delle
variabili e/o funzioni
Stilisticamente si ricorda l’importanza dell’ordine e dell’indentazione.
Anche le istruzioni SQL possono essere formattate così:
13. VARIABILI
Dichiarazioni
(Avvengono nella sezione dichiarativa)
DECLARE
birthdate DATE;
emp_count SMALLINT := 0;
acct_id VARCHAR2 (5) NOT NULL := 'AP001';
credit_limit CONSTANT REAL := 5000.00;
valid BOOLEAN DEFAULT FALSE; -- invece di :=
credit REAL(7,2);
debit credit%TYPE; -- lo stesso tipo di credit
my_dname scott.dept.dname%TYPE; -- lo stesso tipo di scott.dept.dname
-- quest’ultima definizione ha il vantaggio che si adatta ad eventuali
-- cambiamenti del tipo di dati nella colonna
14. Uso di %ROWTYPE
Permette di definire un tipo in grado di contenere una intera
riga estratta da una tabella con i campi dello stesso tipo di
dati.
DECLARE
dept_rec dept%ROWTYPE;
BEGIN
SELECT deptno, dname, loc INTO dept_rec
FROM dept WHERE deptno = 30;
…..
16. Scope delle variabili
In generale le variabili sono visibili all’interno dei blocchi in
cui sono definiti.
17. Operatori
Assegnamento: a:=3;
Aritmetici: + - / * ** (esponenz.)
Logici AND OR NOT
Comparazione = < >= <=
!= <> ^= (Diverso)
IN(..) BETWEEN…AND
NULL IS NULL IS NOT NULL
Stringhe || (contatena) LIKE
18. Tipi definiti dagli utenti
L’utente può definire tipi personalizzati:
Record (strutture dati contenenti membri)
Collection (Liste di valori)
Object (Strutture simili alle classi in linguaggi O.O.)
Subtypes
19. SUBTYPES
DECLARE
/* A local PL/SQL string of length 10 */
small_string VARCHAR2(10);
/* Create a subtype based on that variable */
SUBTYPE teensy IS small_string%TYPE;
SUBTYPE VOTI IS BINARY_INTEGER RANGE 1 .. 10;
20. RECORD
TYPE distance_t IS RECORD
( value NUMBER,
unit_of_measure VARCHAR2(30) );
dallas_to_houston distance_t; -- declare a record based on the type
BEGIN
dallas_to_houston.value := 239.5;
dallas_to_houston.unit_of_measure := 'MILES';
DBMS_OUTPUT.PUT_LINE('The distance between Houston and Dallas
is ' || dallas_to_houston.value || ' ' ||
dallas_to_houston.unit_of_measure);
END;
21. Index By tables e nested
tables
DECLARE
TYPE title_t IS TABLE OF books.title%TYPE INDEX BY
BINARY_INTEGER;
titles title_t;
DECLARE TYPE my_list_t IS TABLE OF NUMBER;
my_list my_list_t;
E’ anche possibile definire un tipo di dati non in PL/SQL, ma renderlo
disponibile poi in SQL con il comando CREATE TYPE di SQL
22. VARRAY
Sono simili alle nested table, ma si stabilisce un limite di
elementi contenuti
CREATE TYPE typename AS VARRAY(max) OF
DATATYPE;