Laboratorio Di Basi Di Dati 04 P L S Q L E P Lpg S Q L
1. Corso di Basi di Dati e Laboratorio
PL/SQL e PLpgSQL
Alfio Ferrara - Stefano Montanelli
A.A. 2005/2006 Basi di Dati e Laboratorio 1
Estensioni procedurali di SQL
• Necessità
– Disporre di linguaggi con cui costruire
applicazioni nel contesto di una base di dati
SQL
• Soluzioni
– Linguaggio nativo
– Linguaggio ospite con procedure esterne
– Linguaggio ospite con precompilatore
(embedded SQL)
A.A. 2005/2006 Basi di Dati e Laboratorio 2
Embedded SQL
• Per inserire statement SQL in un programma
scritto in linguaggio ospite sono necessari:
• strumenti per descrivere lo stato delle
esecuzioni SQL
• SQL offre la variabile SQLCODE che si riferisce
allo stato di esecuzione di uno statement:
• SQLCODE = 0 - esecuzione corretta
• SQLCODE < 0 - errore
• SQLCODE = 100 - risultato vuoto
A.A. 2005/2006 Basi di Dati e Laboratorio 3
1
2. Embedded SQL
• Strumenti per scambiare valori tra variabili di
programma e SQL
• ciò implica:
• 1)una sintassi per referenziare variabili di
programma in statement SQL, e per assegnare
valori singoli a singole variabili
– si aggiunge ad una selezione la clausola INTO se il
risultato della selezione è una singola tupla:
SELECT nome, cognome
INTO :n, :c
FROM …
WHERE …
A.A. 2005/2006 Basi di Dati e Laboratorio 4
Embedded SQL
• 2)Uno strumento per trasferire un risultato
costituito da più tuple nelle variabili del
programma si fa ricorso al concetto di
cursore
• Un cursore può essere visto come una
variabile che contiene un insieme di dati
che é possibile referenziare
A.A. 2005/2006 Basi di Dati e Laboratorio 5
Embedded SQL
• Un cursore viene dichiarato associandolo
ad uno statement SELECT:
DECLARE nomecursore CURSOR
FOR select
• L’esecuzione dello statement avviene però
solo all’apertura del cursore:
OPEN nomecursore
A.A. 2005/2006 Basi di Dati e Laboratorio 6
2
3. Embedded SQL
• Ciò posiziona il cursore prima della prima
tupla:
FETCH nomecursore INTO lista
• questo provoca l’avanzamento del cursore
e la copia dei valori della tupla corrente
nelle variabili di ‘lista’
• Successivamente il cursore è posizionato
dopo l’ultima tupla e SQLCODE assume
valore 100
• L’istruzione: CLOSE nomecursore
disattiva il cursore
A.A. 2005/2006 Basi di Dati e Laboratorio 7
Oracle PL/SQL
Procedural Language/SQL
• Estensione procedurale di SQL
• Struttura del linguaggio:
– PL/SQL è diviso in unità dette blocks
– I programmi sono divisi dunque in unità che
eseguono una azione logica e possono essere
inserite le une nelle altre
A.A. 2005/2006 Basi di Dati e Laboratorio 8
I blocchi
I singoli blocchi hanno la seguente struttura:
DECLARE
/* dichiarazione di variabili, tipi e strutture di
programma */
BEGIN
/* esecuzione: le procedure e i comandi SQL sono
specificati in questa sezione si tratta dell’unica
sezione indispensabile di un blocco */
EXCEPTION
/* dichiarazione di procedure di gestione degli
errori */
END;
A.A. 2005/2006 Basi di Dati e Laboratorio 9
3
4. Elementi SQL in PL/SQL
• Gli elementi SQL ammessi in un blocco
PLSQL sono:
SELECT, INSERT, UPDATE, DELETE
• Non sono ammessi:
CREATE, DROP, ALTER
• Per eseguire un programma PLSQL ad
END deve seguire un punto e il comando
RUN;
A.A. 2005/2006 Basi di Dati e Laboratorio 10
Variabili e tipi
• Le informazioni sono condivise dal
programma PLSQL e dal database
attraverso variabili
• Ad ogni variabile è associato un tipo
• I tipi ammessi sono:
– Uno dei tipi ammessi per gli attributi SQL
– Un tipo PLSQL (ad esempio number)
– Si possono dichiarare variabili che siano dello
stesso tipo assegnato ad un attributo
A.A. 2005/2006 Basi di Dati e Laboratorio 11
Esempio di dichiarazione
DECLARE
Dichiarazione dei tipi
x NUMBER;
y VARCHAR(20);
DECLARE X assume il tipo del campo “campo”
x tabella.campo%TYPE;
DECLARE X assume il tipo dei campi
della tabella “tabella”
x tabella%ROWTYPE;
• Una variabile dichiarata ha sempre valore
NULL fino ad una assegnazione
• Operatore di assegnazione :=
A.A. 2005/2006 Basi di Dati e Laboratorio 12
4
5. Uso di una query SQL
• Un programma PLSQL può far ricorso ad una
Query SQL, con una sintassi leggermente
diversa:
• La clausola SELECT deve essere seguita da una
clausola INTO che specifichi le variabili entro cui
vanno inseriti i risultati della query
• E’ dunque necessaria una variabile per ogni
attributo:
SELECT e,f
INTO a,b FROM T1
WHERE e>1;
A.A. 2005/2006 Basi di Dati e Laboratorio 13
Esempio di programma
CREATE TABLE T1(
e INTEGER,
f INTEGER );
INSERT INTO T1 VALUES(1, 3);
INSERT INTO T1 VALUES(2, 4);
DECLARE
a NUMBER;
b NUMBER;
BEGIN
SELECT e,f
INTO a,b FROM T1 WHERE e>1;
INSERT INTO T1 VALUES(b,a);
END;
.
run;
A.A. 2005/2006 Basi di Dati e Laboratorio 14
Limiti nell’uso di query SQL
• Un programma PLSQL che fa uso di
una query SQL risulta corretto solo se
la query produce come risultato una
sola tupla
• Per lavorare altrimenti occorre ricorrere
ad un cursore
A.A. 2005/2006 Basi di Dati e Laboratorio 15
5
6. Controllo di flusso - IF
Sintassi:
IF <condizione_1> THEN ...
ELSIF <condizione_2> THEN ...
... ...
ELSIF <condizione_n> THEN ...
ELSE ...
END IF;
A.A. 2005/2006 Basi di Dati e Laboratorio 16
Controllo di flusso - LOOP
Sintassi:
LOOP
<istruzioni>
END LOOP;
Almeno una delle istruzioni del loop deve essere una
istruzione di uscita, come la seguente:
EXIT WHEN <condizione>;
A.A. 2005/2006 Basi di Dati e Laboratorio 17
Esempio
DECLARE
i NUMBER := 1;
BEGIN
LOOP
INSERT INTO T1 VALUES(i,i);
i := i+1;
EXIT WHEN i>100;
END LOOP;
END;
.
run;
A.A. 2005/2006 Basi di Dati e Laboratorio 18
6
7. Altri controlli di flusso
• L’istruzione EXIT senza condizione permette
l’uscita incondizionata da un ciclo
While – sintassi:
WHILE <condizione>
LOOP
<istruzioni>
END LOOP;
A.A. 2005/2006 Basi di Dati e Laboratorio 19
Altri controlli di flusso
For – sintassi:
FOR <var> IN <inizio>..<fine>
LOOP
<istruzioni>
END LOOP;
• var è una variabile locale che non richiede di
essere dichiarata
A.A. 2005/2006 Basi di Dati e Laboratorio 20
Cursori
• Un cursore è una variabile che scorre sui valori
delle tuple di una relazione (tabella o risultato di
query)
• Esempio di uso di un cursore:
1) DECLARE
2) a T1.e%TYPE;
3) b T1.f%TYPE; /* dichiarazione del
cursore:*/
4) CURSOR T1Cursor IS
5) SELECT e, f
6) FROM T1
7) WHERE e < f
8) FOR UPDATE;
A.A. 2005/2006 Basi di Dati e Laboratorio 21
7
8. Cursori
9) BEGIN
10)OPEN T1Cursor;
11)LOOP
12)FETCH T1Cursor INTO a, b;
13)EXIT WHEN T1Cursor%NOTFOUND;
14)DELETE FROM T1 WHERE CURRENT OF T1Cursor;
15)INSERT INTO T1 VALUES(b, a);
16)END LOOP;
17)CLOSE T1Cursor;
18)END;
19).
20)run;
A.A. 2005/2006 Basi di Dati e Laboratorio 22
Procedure
Caratteristiche:
ogni parametro può essere seguito da un modo e
da un tipo
i modi ammessi sono:
– IN sola lettura
– OUT sola scrittura
– INOUT lettura e scrittura
per eseguire una procedura occorre invocarla entro
un comando PLSQL:
BEGIN aggiungitupla(1);
END;
A.A. 2005/2006 Basi di Dati e Laboratorio 23
Esempio
• Esempio di procedura di inserimento a due
parametri:
CREATE OR REPLACE PROCEDURE at2(
x T2.a%TYPE,
y T2.b%TYPE
)AS
BEGIN
INSERT INTO T2(a, b) VALUES(x, y);
END at2;
BEGIN
at2(10, 'abc');
END;
A.A. 2005/2006 Basi di Dati e Laboratorio 24
8
9. Funzioni
Caratteristiche:
• la principale differenza rispetto ad una procedura
consiste nel definire un valore di RETURN
sintassi:
CREATE FUNCTION
nomefunzione(parametri) RETURN
<tipo_di_return> AS …
nel corpo della funzione si usa la seguente
espressione per terminare l’esecuzione ed
ottenere il valore di ritorno:
RETURN <espressione>;
A.A. 2005/2006 Basi di Dati e Laboratorio 25
Verificare e cancellare
Controllare le procedure create:
SELECT object_type, object_name
FROM user_objects
WHERE object_type = 'PROCEDURE'
OR object_type = 'FUNCTION';
Cancellare una procedura:
DROP PROCEDURE nomeprocedura;
DROP FUNCTION nomefunzione;
A.A. 2005/2006 Basi di Dati e Laboratorio 26
PLpgSQL
• SQL procedurale su Postgres
• Attivazione del linguaggio
– host:~ postgres$ createlang --
dbname=nomedb plpgsql
• PlpgSLQ offre molte delle funzionalità di
PL/SQL con alcune differenze
• Lucidi tratti da:
– http://www.php-editors.com/postgres_manual/p_plpgsql-porting.html
– http://www.postgresql.org/docs/7.4/interactive/plpgsql.html
A.A. 2005/2006 Basi di Dati e Laboratorio 27
9
10. Differenze fra PLpgSQL e PL/SQL
• In PostgreSQL non ci sono valori di default
per i parametri
• Le funzioni PostgreSQL possono essere
sovraccaricate
• Assegnamenti, cicli and valori condizionali
sono simili
A.A. 2005/2006 Basi di Dati e Laboratorio 28
Esempio 1
• Incrementare numeri interi (per esempio
per definire una propria sequenza)
CREATE FUNCTION incrementsix
(integer) RETURNS INTEGER AS '
BEGIN
RETURN $1 + 6;
END;
' LANGUAGE 'plpgsql';
A.A. 2005/2006 Basi di Dati e Laboratorio 29
Esempio 2
• Concatenazione di stringhe:
CREATE FUNCTION concat_text
(TEXT, TEXT) RETURNS TEXT AS '
BEGIN
RETURN $1 || $2;
END;
' LANGUAGE 'plpgsql';
A.A. 2005/2006 Basi di Dati e Laboratorio 30
10
11. Esempio 3
• Uso delle funzioni coi valori delle tabelle
CREATE FUNCTION
concat_selected_fields(users)
RETURNS text AS '
DECLARE
in_t ALIAS FOR $1;
BEGIN
RETURN in_t.first_name || ‘‘ ’’ ||
in_t.second_name;
END;
' LANGUAGE plpgsql;
A.A. 2005/2006 Basi di Dati e Laboratorio 31
Esempio 3
• SELECT concat_selected_fields(users)
from users;
• Restituisce il risultato della funzione
A.A. 2005/2006 Basi di Dati e Laboratorio 32
Uso delle funzioni nei trigger
CREATE OR REPLACE FUNCTION w_users() RETURNS TRIGGER
AS '
BEGIN
NEW.name = NEW.first_name || '' '' ||
NEW.second_name;
RETURN NEW;
END;
' LANGUAGE plpgsql;
CREATE TRIGGER users_t BEFORE INSERT OR UPDATE ON
users FOR EACH ROW EXECUTE PROCEDURE w_users();
A.A. 2005/2006 Basi di Dati e Laboratorio 33
11
12. Esempio 4
CREATE FUNCTION emp_stamp () RETURNS TRIGGER AS '
BEGIN
-- Check that empname and salary are given
IF NEW.empname ISNULL THEN
RAISE EXCEPTION ''empname cannot be NULL value'';
END IF;
IF NEW.salary ISNULL THEN
RAISE EXCEPTION ''% cannot have NULL salary'', NEW.empname;
END IF;
-- Who works for us when she must pay for?
IF NEW.salary < 0 THEN
RAISE EXCEPTION ''% cannot have a negative salary'', NEW.empname;
END IF;
-- Remember who changed the payroll when
NEW.last_date := ''now'';
NEW.last_user := current_user;
RETURN NEW;
END;
' LANGUAGE 'plpgsql';
A.A. 2005/2006 Basi di Dati e Laboratorio 34
Esempio 4
CREATE TRIGGER emp_stamp BEFORE
INSERT OR UPDATE ON emp
FOR EACH ROW EXECUTE
PROCEDURE emp_stamp();
A.A. 2005/2006 Basi di Dati e Laboratorio 35
Altri linguaggi
• Oltre a plpgsql postgres offre altri linguaggi
embedded nel DBMS
• Ad esempio:
– PL/Tcl
– PL/Perl
– PL/Python
A.A. 2005/2006 Basi di Dati e Laboratorio 36
12