SlideShare a Scribd company logo
1 of 75
RDBMS ORACLE
ELEMENTI di SQL-PL/SQL
Michele gariglio
Introduzione al PL/SQL per Oracle - I fondamentali
• Linguaggio procedurale che integra ed estende l’ SQL
standard
• E’ di fatto proprietario di Oracle Corporation. Non esiste
nessuno standard per PL/SQL ma ANSI ci sta lavorando.
• Basato sui concetti di programmazione ADA.
• Inizialmente forniva logiche di batch-processing per script
SQL
• Poi, è diventato un vero e proprio ambiente di
programmazione.
L’acronimo: Procedural Language SQL
PL/SQL - I fondamentali
 Una buona strada per cominciare ad esplorare il PL/SQL è cominciare
da un esempio:
• Il programma, elabora gli ordini per delle racchette da tennis
verificandone la quantità disponibile ad inventario
• Dichiara una variabile di tipo NUMBER per mantenere la quantità di
racchette a disposizione
• Recupera questo valore dalla tavola “inventario” del db
• Se la quantità è >0 il programma modifica la tavola ed inserisce
un nuovo record nella tabella “ordini”
• Altrimenti, il programma evidenzia un record di “esaurito” nella
tabella “ordini”
PL/SQL - I fondamentali
DECLARE
qta_disp NUMBER(5);
BEGIN
SELECT quantita INTO qta_disp FROM inventario
WHERE prodotto LIKE ’TENNIS RACKET’ FOR UPDATE OF quantita;
IF qta_disp > 0 THEN
UPDATE inventario SET quantita=quantita - 1
WHERE prodotto LIKE ’TENNIS RACKET’;
INSERT INTO ordini
VALUES (’Racchetta da Tennis ordinata’, SYSDATE);
ELSE
INSERT INTO ordini
VALUES (’Racchette da Tennis Esaurite!’, SYSDATE);
END IF;
COMMIT;
END;
PL/SQL - I fondamentali
• Con PL/SQL è possibile adoperare gli statement SQL per
manipolare dati nel db in abbinamento al controllo di flusso di un
ambiente di programmazione
• E’ possibile dichiarare variabili di programma, costanti, definire
procedure, definire funzioni e gestire errori di run-time (eccezioni)
In definitiva PL/SQL combina la potenza interattiva della
manipolazione dei dati attraverso SQL con la potenza
del data processing dei linguaggi procedurali
PL/SQL - I fondamentali
 STRUTTURA a BLOCCHI
 PL/SQL è un linguaggio block-structured
• Le unità fondamentali (procedure, funzioni, e blocchi generici) che
costituiscono un programma PL/SQL equivalgono a blocchi logici
che possono contenere un qualsiasi numero di sotto-blocchi
annidati
• Tipicamente, ogni blocco logico corrisponde ad un problema o
sotto-problema da risolvere (dividi e conquista)
• Un blocco (o sotto-blocco) consente di raggruppare logicamente
dichiarazioni e statement correlati
• Le dichiarazioni sono locali al blocco in cui sono definite e cessano
di esistere quando il blocco termina
• Un blocco PL/SQL ha tre parti:
 una parte dichiarativa (opzionale)
 una parte di esecuzione
 una parte di gestione delle eccezioni (opzionale)
PL/SQL - I fondamentali
 I BLOCCHI
• Osservano una struttura di base
• Due tipi di blocchi: named and anonymous
• I named blocks sono functions and procedures
• Quattro sessioni in un blocco:
Header (rilevante solo per procedures and functions)
Declaration (opzionale)
Execution (sempre)
Exception (opzionale)
• I blocchi definiscono lo scope per le variabili e la gestione delle
eccezioni
• Vale l’annidamento !
Block Header
BEGIN
EXCEPTION
Execution Section
Declaration Section
Exception Section
END;
IS
PL/SQL - I fondamentali
I BLOCCHI: struttura
PL/SQL - I fondamentali
 STRUTTURA a BLOCCHI
• Solo oggetti dichiarati nella prima parte possono essere adoperati
nella fase di esecuzione
• Le eccezioni (runtime error + warning) scatenate nella fase di
esecuzione sono essere gestite dalla parte di exception handling
• All’interno delle parti di esecuzione e di gestione eccezioni è
possibile annidare altri blocchi
• Possono essere definiti dei sottoprogrammi nella fase dichiarativa,
tuttavia questi sono locali sola al blocco dove sono definiti
[DECLARE
---- dichiarazioni ]
BEGIN
------
statements
[EXCEPTION
---handlers ]
END;
PL/SQL - I fondamentali
 DICHIARAZIONE di VARIABILI
Le variabili possono avere tipi di dato nativi SQL
(CHAR, DATE, NUMBER, ecc.)
Anche tipi di dato PL/SQL (BOOLEAN, REAL, BINARY_INTEGER, ecc.)
Esempi di dichiarazione
codice_articolo NUMBER(4);
art_presente BOOLEAN;
E’ possibile dichiarare anche tipi di dato più strutturati
TABLE (tabelle annidate)
VARRAY (array a lunghezza variabile)
RECORD (tipo di dato composto) tipico nell’uso dei cursori
PL/SQL - I fondamentali
 ASSEGNAZIONE di Valori a Variabili
• Adoperando l’operatore di assegnamento (:=)
 tax := price * tax_rate;
 bonus := current_salary * 0.10;
 amount := TO_NUMBER(SUBSTR(’750 dollars’, 1, 3));
 valid := FALSE;
• Assegnando valori provenienti da select (fetch) sul database
• Calcolo del bonus come 10% del salario di un impiegato:
 SELECT sal * 0.10 INTO bonus FROM emp WHERE
empno = emp_id;
• Il valore può essere adoperato in altri calcoli o per futuri
inserimenti a db
 DICHIARAZIONE di COSTANTI
• Come per le variabili ma con la parola chiave CONSTANT e
con l’immediata assegnazione di un valore alla costante.
• Da qui in poi tale valore rimarrà inalterato
 credit_limit CONSTANT REAL := 5000.00;
PL/SQL - I fondamentali
 CURSORI e VARIABILI CURSORE
• Dei CURSOR e della loro definizione ed utilizzo abbiamo già visto
• Come un cursore, una variabile cursore punta alla riga corrente di un result
set ottenuto da query multirow
• Ma può essere aperta dinamicamente per ogni tipo di query compatibile
• Non è necessario specificare una query: le variabili cursore sono variabili
PL/SQL ! (Vale l’assegnamento, il passaggio di parametri, ecc.)
• La procedura seguente apre una variabile cursore “generic_cv” per una
query prescelta
 PROCEDURE open_cv (generic_cv IN OUT GenericCurTyp, choice IN NUMBER)
IS
 BEGIN
 IF choice = 1 THEN
 OPEN generic_cv FOR SELECT * FROM emp;
 ELSIF choice = 2 THEN
 OPEN generic_cv FOR SELECT * FROM dept;
 ELSIF choice = 3 THEN
 OPEN generic_cv FOR SELECT * FROM salgrade;
 END IF;
PL/SQL - I fondamentali
 ATTRIBUTI
• Varibili e cursori PL/SQL hanno attributi
• Sono proprietà che consentono di referenziare datatype e struttura di
oggetti senza doverne ripetere la loro definizione
• Colonne e tavole del db hanno attributi simili per la gestione
• Il segno di (%) è l’indicatore di attributo
 %TYPE
• L’attributo %TYPE fornisce il datatype di una variabile o colonna di db
• Utile per dichiarare variabili che manterranno valori dal db
• Per esempio, se esiste una colonna “titolo” in una tavola “libri”, potrebbe
servire dichiarare una variabile “mio_titolo” dello stesso tipo di quella
colonna
 mio_titolo libri.titolo%TYPE;
• Vantaggi
 conoscere l’esatto tipo di dato del titolo
 se cambia la definizione a db del campo titolo, la mia variabile cambia
a runtime
PL/SQL - I fondamentali
 ATTRIBUTI
 %ROWTYPE
• In PL/SQL, i record sono adoperati per mantenere valori di
dati provenienti da campi
• L’attributo %ROWTYPE fornisce un record type che
rappresenta una riga di una tavola
• Il record può mantenere righe di dati selezionate da tavole o
caricate da cursori
• Le colonne di una riga ed i corrispondenti campi di un record
hanno gli stessi datatypes.
• Nel primo esempio, si dichiara un record con nome
dept_rec, i suoi campi avranno lo stesso nome e lo stesso
tipo di dato delle colonne di dept
• Il secondo esempio è combinato con l’utilizzo dei cursori
PL/SQL - I fondamentali
 ATTRIBUTI
 %ROWTYPE
• Esempio 1:
DECLARE
dept_rec dept%ROWTYPE;
 Adoperare la dot notation per riferire i singoli campi:
my_deptno := dept_rec.deptno;
• Esempio 2:
DECLARE
CURSOR c1 IS SELECT ename, sal, hiredate, job FROM emp;
emp_rec c1%ROWTYPE;
Quando si adopererà lo statement:
FETCH c1 INTO emp_rec;
avremo la sostituzione dei valori
PL/SQL - Strutture di controllo
 Rappresentano il “gap” semantico del passaggio
SQL --> PL/SQL
 Fino a qui, nella fase di esecuzione di un blocco PL/SQL,
abbiamo visto come trattare singoli statement sequenziali
 Le strutture di controllo sono le vere e proprie strutture del
linguaggio che servono a governare ed a condizionare il flusso
di elaborazione sui dati
 Le principali (in quasi tutti i linguaggi) sono:
 IF-THEN-ELSE
 FOR-LOOP
 WHILE-LOOP
 EXIT-WHEN
 GOTO
PL/SQL - Strutture di controllo
 Il Controllo CONDIZIONALE
• Azioni alternative dipendenti da specifiche circostanze
• Lo statement IF-THEN-ELSE permette di eseguire
blocchi di statement in modo condizionale
• La clausola IF verifica una condizione
• il ramo THEN definisce cosa fare quando la condizione
è vera
• il ramo ELSE cosa fare quando è falsa
PL/SQL - Strutture di controllo
 Il Controllo CONDIZIONALE
DECLARE
acct_balance NUMBER(11,2);
acct CONSTANT NUMBER(4) := 3;
debit_amt CONSTANT NUMBER(5,2) := 500.00;
BEGIN
SELECT bal INTO acct_balance FROM accounts
WHERE account_id = acct
FOR UPDATE OF bal;
IF acct_balance >= debit_amt THEN
UPDATE accounts SET bal = bal - debit_amt WHERE account_id = acct;
ELSE
INSERT INTO temp VALUES (acct, acct_balance, ’Insufficient funds’);
END IF;
COMMIT;
END;
PL/SQL - Strutture di controllo
L’ITERAZIONE
Lo statement di LOOP permette di eseguire un blocco di
istruzioni più volte (ciclo)
La parola chiave LOOP anticipa il primo statement da ripetere
La parola chiave END LOOP chiude il blocco di istruzioni
ripetute
Il FOR-LOOP è un loop particolare definito da range di interi
FOR i IN 1..order_qty LOOP
UPDATE sales SET custno = customer_id
WHERE serial_num = serial_num_seq.NEXTVAL;
END LOOP;
Il WHILE-LOOP associa una condizione di ingresso per la
ripetizione del ciclo. La condizione viene valutata sempre
prima dell’esecuzione del ciclo ed il TRUE è il valore di
ingresso nel loop. Il loop viene saltato se la condizione è
FALSE o NULL, ed il controllo passa allo statement successivo
PL/SQL - Strutture di controllo
 L’ITERAZIONE
• Esempio: trovare il primo impiegato che ha un salario > 4000 $ ed
il suo manager a partire dalla matricola 7902:
DECLARE
salary emp.sal%TYPE;
mgr_num emp.mgr%TYPE;
last_name emp.ename%TYPE;
starting_empno CONSTANT NUMBER(4) := 7902;
BEGIN
SELECT sal, mgr INTO salary, mgr_num FROM emp WHERE empno =
starting_empno;
WHILE salary < 4000 LOOP
SELECT sal, mgr, ename INTO salary, mgr_num, last_name
FROM emp WHERE empno = mgr_num;
END LOOP;
INSERT INTO temp VALUES (NULL, salary, last_name);
COMMIT;
END;
PL/SQL - Strutture di controllo
 L’ITERAZIONE
• Lo statement EXIT-WHEN permette l’uscita anticipata
dal loop quando l’elaborazione successiva non è
desiderata
• Quando il programma incontra EXIT, la condizione
nella clausola WHEN viene valutata. Se TRUE, il loop
termina ed il controlla passa allo statement successivo
• Esempio: il ciclo termina quando il valore total supera
25000 $:
LOOP
...
total := total + salary;
EXIT WHEN total > 25000; -- esce dal loop se la condizione è
true
END LOOP;
-- il controllo di flusso prosegue qui
PL/SQL - Strutture di controllo
 Il SALTO INCONDIZIONATO
• Lo statement GOTO consente di saltare in modo
incondizionato ad un punto preciso del programma
identificato da una label
• La label (etichetta) è un identificatore non dichiarato e
deve precedere uno statement o un blocco PL/SQL
• Viene esplicitata con la dicitura <<label>> :
IF rating > 90 THEN
GOTO calc_raise; -- salto alla label
END IF;
...
<<calc_raise>>
IF job_title = ’SALESMAN’ THEN -- il programma continua da qui
amount := commission * 0.25;
ELSE
amount := salary * 0.10;
END IF;
PL/SQL - Modularità
 In PL/SQL è possibile definire strutture di
programma più semplici da richiamare in modo
modulare
 VANTAGGI:
 Strutturazione di un problema in problemi più semplici (divide et
impera)
 Modularità
 Ripetitività e riuso del codice sotto diverse premesse
 Migliore gestione dell’applicazione
 Semplicità di definizione e di implementazione
 Si organizzano in:
• Sottoprogrammi
 Procedure
 Funzioni
• Procedure esterne
• Packages
PL/SQL - Modularità
 PROCEDURE e FUNZIONI
• Sono blocchi di programma (subprogram) che prendono parametri e che
possono essere invocati (chiamati) da blocchi esterni
• Un subprogram è come un programma in miniatura che inizia con un
header, seguito da una parte dichiarativa opzionale, una parte di
esecuzione, e una sezione opzionale di exception-handling
 PROCEDURE award_bonus (emp_id NUMBER) IS
 bonus REAL;
 comm_missing EXCEPTION;
 BEGIN
 SELECT comm * 0.15 INTO bonus FROM emp WHERE empno = emp_id;
 IF bonus IS NULL THEN
 RAISE comm_missing;
 ELSE
 UPDATE payroll SET pay = pay + bonus WHERE empno = emp_id;
 END IF;
 EXCEPTION
 WHEN comm_missing THEN
 ...
 END award_bonus;
PL/SQL - Modularità
 PROCEDURE e FUNZIONI
 Alla sua invocazione, questa procedura accetta il valore di una
matricola
 Usa questo valore per selezionarne la commissione e per calcolarne un
bonus del 15%
 Un successivo controllo sul bonus innalza un’eccezione se questo è
null, altrimenti il payroll dell’impiegato viene modificato
• La PROCEDURE non restituisce alcun valore
• La FUNCTION può restituire valori
CREATE FUNCTION interpolazione(x FLOAT, y FLOAT)
RETURN FLOAT AS EXTERNAL
LIBRARY mathlib
NAME "c_interp"
LANGUAGE C;
• L’esempio di funzione richiama un programma (procedura) esterno
 la routine è definita in un linguaggio di più basso livello (C)
 occorre includere la libreria di definizione della routine
(mathlib)
PL/SQL - Modularità
 PACKAGES
• PL/SQL permette di raggruppare logicamente tipi,
variabili, cursori e sottoprogrammi in un package
• Sono semplici da capire e le loro interfacce sono
semplici chiare e ben definite
• I package aiutano lo sviluppo di applicazioni
• Realizzano astrazione del codice ed incapsulamento
• Package si costituiscono di due parti:
 la specifica del package
 il corpo de package (body)
• La specifica è l’interfaccia in cui si dichiarano: tipi,
costanti, variabili, exceptions, cursori, e
sottoprogrammi disponibili all’uso dell’applicativo
• Il body è l’implementazione della specifica; definisce
cursori e sottoprogrammi
PL/SQL - Modularità
PACKAGES
L’esempio raccoglie due procedure:
CREATE PACKAGE emp_actions AS -- specifica del package
PROCEDURE hire_employee (empno NUMBER, ename CHAR, ...);
PROCEDURE fire_employee (emp_id NUMBER);
END emp_actions;
CREATE PACKAGE BODY emp_actions AS -- package body
PROCEDURE hire_employee (empno NUMBER, ename CHAR, ...) IS
BEGIN
INSERT INTO emp VALUES (empno, ename, ...);
END hire_employee;
PROCEDURE fire_employee (emp_id NUMBER) IS
BEGIN
DELETE FROM emp WHERE empno = emp_id;
END fire_employee;
END emp_actions;
PL/SQL - Modularità
 PACKAGES
• Solo le dichiarazioni effettuate nella specifica del
package sono accessibili dall’applicazione
• Il dettaglio di implementazione del body è nascosto ed
inaccessibile
• I package possono essere compilati e mantenuti dal
database dove il loro contenuto può essere reso
disponibile a diverse applicazioni
• Alla prima chiamata fatta su di un oggetto del
package, l’intero package viene caricato in memoria
• Le successive chiamate non fanno I/O a disco
• I package aumentano la produttività e migliorano le
performance del sistema
PL/SQL - Tipi di dato Astratto
 Sono tipi di dato più complessi di quelli primitivi:
• COLLECTIONS: gruppo ordinato di elementi tutti dello stesso tipo,
corrispondono agli array dei linguaggi di terza generazione.
L’elemento corrente viene riferito da un indice
 TABLE
 VARRAY
• RECORD: aggregazione di campi di tipo diverso sotto un unico nome. Sono
adoperati dal %ROWTYPE, dai cursori, ma anche nelle esplicite definizione
di record dall’utente
DECLARE
TYPE TimeRec IS RECORD (minutes SMALLINT, hours SMALLINT);
TYPE MeetingTyp IS RECORD (
day DATE,
time TimeRec, -- record annidato
place VARCHAR2(20),
purpose VARCHAR2(50));
• OBJECT: incapsulamento di strutture dati complesse. Applicazione
della metodologia OO con definizione di strutture e metodi
PL/SQL - Gestione delle Eccezioni
• PL/SQL consente di rilevare e gestire eccezioni
• E’ il verificarsi a runtime di errori di programma o
warning
• Gestione del caso --> viene innalzata un’eccezione
• L’esecuzione normale termina ed il controllo del
programma viene trasferito alla sezione di exception-
handling del blocco PL/SQL
• Gli exception handlers sono le particolari routine
scritte per gestire le eccezioni
• Ne esistono di predefinite innalzate implicitamente dal
sistema (se divido un numero per zero, PL/SQL innalza
uno ZERO_DIVIDE in automatico)
• Le eccezioni definite dall’utente si devono innalzare
con lo statement RAISE
 Le eccezioni vengono definite nella parte dichiarativa del blocco
PL/SQL (o di un subprogram)
 Nella parte di esecuzione si controlla la condizione che
PL/SQL - Gestione delle Eccezioni
• L’esempio calcola il bonus posseduto da un venditore
• Il bonus si basa sul salario e sulla commissione per
cui, se la commissione è null, viene innalzata
un’eccezione di comm_missing.
 DECLARE
 ...
 comm_missing EXCEPTION; -- dichiarazione
 BEGIN
 ...
 IF commission IS NULL THEN
 RAISE comm_missing; -- raise dell’eccezione
 ELSE
 bonus := (salary * 0.10) + (commission * 0.15);
 END IF;
 EXCEPTION
 WHEN comm_missing THEN
 -- codice per la cgestione dell’errore
PL/SQL - Architetture
 Il sistema di runtime PL/SQL è una tecnologia
NON un prodotto
 E’ un motore che esegue blocchi PL/SQL
 Può essere installato indipendentmente su due tipi
di ambiente
• Oracle server
• Tools come Oracle Forms or Oracle Reports
 In entrambi i casi il PL/SQL engine accetta in input
blocchi PL/SQL validi
 Esempio di lavoro del motore PL/SQL
NB: Le istruzioni puro SQL
vengono eseguite dal db !
PL/SQL - Architetture
 Metodi di esecuzione
• Oracle Server PL/SQL Engine
 Anonymous Blocks: da tool interattivi come SQL*Plus o OEM
 Stored Subprograms: procedure compilate separatamente e
mantenute permanentemente nel db. Una procedura
debitamente creata con CREATE è detta stored procedure. A
tutti gli effetti diventa un oggetto del data dctionary. Posso
richiamarli da trigger, altri stored subprogram, applicazioni
Oracle Precompilate, OCI application, o interattivamente da
SQL*Plus o Enterprise Manager. ES:
SQL> EXECUTE create_dept(’FINANCE’, ’NEW YORK’);
 Database Triggers: procedura associata ad una tavola e a degli
eventi
• In Oracle Tools
 se dispone di un motore PL/SQL, un ambiente di sviluppo può
elaborare blocchi PL/SQL
 il tool passerà al db le sole chiamate relative alla elaborazione
di statement SQL
PL/SQL - Esempio di Procedura con
tutte e 4 le sessioni
PROCEDURE set_sales
(company_id_in IN NUMBER,
sales_in IN NUMBER,
calc_type_in IN VARCHAR2)
IS
sales_amt NUMBER;
upper_type VARCHAR2(30)
:= UPPER (calc_type_in);
BEGIN
IF upper_type = ‘ALL’
THEN
update_company
(company_id_in, sales_in);
END IF;
EXCEPTION
WHEN DIVIDE_BY_ZERO
THEN
display_error;
END;
Header
Execution
Declaration
Exception
PL/SQL - Esempio di Anonymous
Execution
Only
DECLARE
emp_name emp.ename%TYPE;
total_salary NUMBER;
invalid_employee EXCEPTION;
BEGIN
total_salary :=
get_sal (emp_name, ‘TOTAL’);
IF total_salary IS NULL
THEN
RAISE invalid_employee;
ELSE
DBMS_OUTPUT.PUT_LINE
(‘Total salary is ‘ ||
TO_CHAR (total_salary));
END IF;
EXCEPTION
WHEN invalid_employee
THEN
...
END;
Exception
Declaration
Execution
PL/SQL - Annidamento
 E’ possibile
inscatolare un
anonymous block
dentro le sezioni di
execution and
exception di un altro
blocco PL/SQL
PROCEDURE ...
BEGIN
DECLARE
BEGIN
END;
EXCEPTION
WHEN ...
THEN
BEGIN
END;
END;
• Il blocco annidato ha la medesima struttura di quello che lo
rachiude
• Importante ! Ha le sue sezioni di declaration ed exception.
Occhio allo scope delle variabili
PL/SQL - Esempio di Annidamento
DECLARE
<declarations>
BEGIN
DECLARE
<declarations>
BEGIN
<executable statements>
END;
BEGIN
<executable statements>
EXCEPTION
<exception handlers>
END;
EXCEPTION
<exception handlers>
END;
Inner Block 1
Inner Block 2
PL/SQL - Nota sulla Sintassi
• Identificatori --> nomi per cose !
• Fino a 30 caratteri
• Devono iniziare con una lettera
• Valgono: “_”, “$”, “#” come separatori
• Si riconoscono identificatori con nomi di
program, loop, o package.
• La logica di statement termina con semi-colon
“;”
• Statements possono essere su più righe senza
continuation char
• Non case-sensitive, eccetto in caso di valori
string (come SQL)
PL/SQL - Esempi di Identificatori
 I seguenti identificatori sono la stessa
cosa:
TOTAL_sales
TOTAL_SALES
total_sales
I seguenti sono illegali:
1st_year_total
company-name
match_found?
the_long_name_of_the_corporation
I seguenti sono OK:
row#
total_sales_$
First_year_total
PL/SQL - Identificatori - Tips (1)
 Rendere i nomi sia comprensibili che
facilmente “riferibili”
Troppo “Criptici” !
totnumcomps
yrind
i j k x y
Troppo verbali !
total_number_companies
fiscal_year_index_number
Right !
total_companies
year_index
PL/SQL - Identificatori - Tips (2)
• Adottare un naming convenzionale nello sviluppo delle
applicazioni
• Prefissi e suffissi standard per cursori e nomi di record, ecc
• Permettere differenti variazioni per lo stesso identificatore
non serve a nulla in particolare
• Anche se per differenti programmi, non c’è nessuna
ragione per avere abbreviazioni e interpretazioni diverse
• Se la variabile rappresenta informazioni dal db, incorporare
anche il nome dell’entità
• Sfruttare le informazioni standard disponibili dal database
• Tuttavia, è consigliabile non dichiarare mai variabili con lo
stesso nome di una colonna. E’ possibile, ma cosa accade
se serve adoperare entrambe nella medesima code area?
PL/SQL - Alcune convenzioni nel Naming
Cursori
Costanti
Variabili
Parametri
Record e
Record Types
suffisso: company_cur
prefisso: c_earliest_date
prefisso: v_company_id
appendere il parameter mode:
company_id_in
suffisso: company_rec
tot_sales_rectype
PL/SQL - Literals
 Un literal è un valore esplicito
• Stringhe sono racchiuse tra apici singoli: ‘stringa’
• I booleani sono TRUE, FALSE, NULL senza apici
 Permetter l’uso delle costanti esplicite nei programmi
 Regole per l’uso degli apici singoli:
• Per comprendere un apice nella stringa, usare due apici
singoli consecutivi
• Per concatenare un apice alla fine di una stringa, usare
tre apici singoli
‘Steven’’s House’ Steven’s House
Literal Value Evaluates To:
‘Steven’ || ‘‘‘s House’ Steven’s House
‘Steven’ || ‘‘‘,’’’ Steven’,’
PL/SQL - Commenti
 Commenti in singola linea partono con un
doppio tratto (--) e terminano alla fine della
linea fisica
 Commenti multi linea partono con (/*) e
fniscono con (*/)
IF status_cd = ‘C’ -- Closed
THEN
/*
|| Reject changes. I have lots to
|| say here so I use a multiple
|| comment block.
*/
action_status := rejected;
END IF;
PROCEDURE calc_totals
/* Return total sales for year. */
(year_in IN INTEGER, arg1 OUT NUMBER);
PL/SQL - Symboli e Operatori
 PL/SQL supporta l’intero set di operatori
relazionali, più:
Descrizione Simbolo
Assegnamento :=
Concatenazione ||
Identificatore di label << name >>
Diverso != oppure <>
new_total := 1000;
full_name := first_name || last_name;
<<outer_loop>>
IF curr_year != last_year THEN ...
PL/SQL - Famiglie di Tipi di Dati
Tipi di Dati PL/SQL per Famiglia
Composti
Scalari
Records
PL/SQL
Tables
BINARY_INTEGER
DEC
DECIMAL
DOUBLE PRECISION
FLOAT
INT
INTEGER
NATURAL
NUMBER
NUMERIC
POSITIVE
REAL
SMALLINT
CHAR
CHARACTER
LONG
LONG RAW
ROWID
STRING
VARCHAR
VARCHAR2
DATE
BOOLEAN
 PL/SQL supporta tutti i tipi di dati originari di Oracle
Server, con alcune aggiunte particolari:
PL/SQL - Numeri
 BINARY_INTEGER sono memorizzati come
numeri binari con segno
• Possono essere usati nei calcoli senza
conversioni, più efficiente
 Specificare precisione e scala decimale.
• Scala può essere negativa, che causa
arrotondamenti a sinistra del punto decimale
• Il default è 0 (integers).
• NUMBER supportano un massimo di precisione di
38.
 Usare sottotipi per migliorare in qualità e
documentazione del codice
company_count BINARY_INTEGER;
total_sales NUMBER (20,2);
PL/SQL - Stringhe
 CHAR è a lunghezza fissa e dovrebbe essere
inutilizzato se non per uso specifico (per flag,
risposte quotate, ecc)
 VARCHAR2 è a lunghezza variabile e può
arrivare sino a 32Kbytes in lunghezza
• LONG in PL/SQL è più corto di VARCHAR2:
32760.
• Non esiste alcuna ragione specifica per usare
LONG e LONG RAW in PL/SQL
 ROWID è un tipo specifico di Oracle che
identifica la LOCAZIONE FISICA di un record.
Il suo formato è: BBBBBBB.RRRR.FFFF
dove BBBBBBB è il numero del blocco del datafile, RRRR è
il numero della riga all’interno del blocco, e FFFF è il valore
HEX del datafile
PL/SQL - Date
 In PL/SQL i tipi data sono paralleli a quelli previsti nel
RDBMS Oracle
 Si compongono di (timestamp):
• Secolo, Anno, Mese, Giorno
• Ore, Minuti, Secondi
 Non si possono memorizzare frazioni di secondo in una
variabile di tipo data
 Le date hanno un intervallo di validità che va dal
1/1/4712 AC al 31/12/4712 DC
 Di default, la porzione di tempo è mezzanotte
 PL/SQL ha funzioni che permettono operazioni e
manipolazioni sulle date
PL/SQL - Booleani
 Una variabile dichiarata come BOOLEAN può
essere TRUE, FALSE o NULL
• Questi valori NON sono stringhe
 NB: Oracle NON supporta colonne BOOLEAN
• Tipo di dati naturale nella programmazione
• Miglior lettura del codice
• Occorre convertirli in Y/N o 1/0 se si desidera
memorizzare dati Booleani nel database
need_deposit := TRUE;
IF balance_too_low
THEN
...
END IF;
PL/SQL - Dichiarazioni
 SEMPRE dichiarare tutte le variabili e le
costanti prima di adoperarle
 Dichiarare una variabile per stmt
 Possibilità di definirne un valore di default in
dichiarzione
 Possibilità di applicarne la clausola NOT NULL
• Ma definirne un valore di default
 Usare gli attributi %TYPE e %ROWTYPE per
ancorare la variabile ad una variabile
esistente o ad un elemento di db
DECLARE
<var_name> <datatype>
[ NOT NULL ]
[ := <def_value> ];
PL/SQL - Esempi di Dichiarazioni
 Senza vincoli:
hire_date DATE;
total_sales NUMBER;
balance_too_low BOOLEAN;
Vincolate e con defaults
ename VARCHAR2(30) DEFAULT ‘ACME’;
sales_amt NUMBER(15,2) NOT NULL := 0;
Costanti
closed_status CONSTANT CHAR(1) := ‘C’;
Dichiarazione Ancorata
ename emp.ename%TYPE;
total_sales sales_amt%TYPE;
emp_rec emp%ROWTYPE;
PL/SQL - Ancoraggio
DECLARE
ename emp.ename%TYPE;
new_emp_name ename%TYPE;
BEGIN
ename
empno
hiredate
VARCHAR2(60)
NUMBER
DATE
The emp table structure
PL/SQL - Ancoraggio i Vantaggi
 Il meccanismo dell’ancoraggio sincronizza le
variabili PL/SQL con righe e colonne di
database
• Se una variabile o un parametro PL/SQL dovrà
rappresentare una informazione di database nel
programma userà SEMPRE %TYPE or
%ROWTYPE.
• Mantengono il programma in sintonia con le
strutture del db senza grosse modifiche del
codice
 L’ancoraggio normalizza le dichiarazioni delle
variabili derivate
• Essere certi della consistenza dei nomi di entità
• Ricompilare gli upgrade e le modifiche fatte ad
una dichiarazione
PL/SQL - il NULL in PL/SQL
 NULL significa “indeterminato”
• Non equivale a 0 o blank
• NULL non è mai uguale a nient’altro, nemmeno
a NULL
• NULL non è mai diverso da nient’altro
 Quando si applica un NULL come argomento
di una funzione, in ritorno si ha NULL.
Eccezioni:
• NVL: converte NULL in un altro valore
• La concatenazione ignora i NULL
• REPLACE: NULL causa la rimozione di caratteri
da stringhe
 Usare IS NULL e IS NOT NULL per accertarsi
della presenza di null values
PL/SQL - Null nelle Funzioni
 Normalmente, un argomento NULL gemera il
return di valori NULL
TO_DATE (NULL) NULL
NVL converts a NULL:
NVL (NULL, ‘N/A’) ‘N/A’
Concatenation ignores null values:
‘Steven ‘ || NULL || ‘Feuerstein’ ‘Steven Feuerstein’
Certamente è rara la codifica pura di NULL negli statements. NULL è
invece un valore assunto da una variabile
PL/SQL - Null da Verificare
 ATTENZIONE ! Le seguenti condizioni NON
verranno mai valutate con TRUE
 Remember: niente è mai uguale o diverso da
NULL
emp_rec.hiredate IS NULL
emp_rec.hiredate IS NOT NULL
Adoperare gli operatori IS NULL e IS NOT NULL:
emp_rec.hiredate = NULL
emp_rec.hiredate != NULL
NULL = NULL
PL/SQL - Scope e Visibilità
 Una volta dichiarata una variabile o, più in generale, un
identificatore è lecito adoperarli
 Si faranno riferimenti ad esso nel codice
 PL/SQL risolve i riferimenti alle variabili con regole baste
su scope e visibilità.
 SCOPE è la porzione di codice all’interno della quale è
possibile fare riferimento ad un identificatore
 Un identificatore è VISIBILE se è possibile fare ad esso
riferimento con un nome non qualificato
 I nomi qualificati sono quelli per cui vale la “dot
notation”, come per tabella.colonna o package.modulo
or record.campo
PL/SQL - Scope and Visibilità nei
blocchi annidati
DECLARE
N NUMBER;
BEGIN
...
DECLARE
N NUMBER;
BEGIN
...
END;
...
END;
DECLARE
N NUMBER;
BEGIN
...
DECLARE
N NUMBER;
BEGIN
...
END;
...
END;
DECLARE
N NUMBER;
BEGIN
...
DECLARE
N NUMBER;
BEGIN
...
END;
...
END;
DECLARE
N NUMBER;
BEGIN
...
DECLARE
N NUMBER;
BEGIN
...
END;
...
END;
Scope Visibilità
Outer
N
Inner
N
PL/SQL - Referenziamento
 PL/SQL richiede un riferimento “qualificato”
per distinguere due oggetti con lo stesso nome
ma dichiarati in scope diversi
<<outer_block>>
DECLARE
total_sales NUMBER;
BEGIN
<<inner_block>>
DECLARE
total_sales NUMBER;
BEGIN
total_sales :=
outer_block.total_sales;
END;
display_totals (total_sales);
END;
PL/SQL - Precedenze tra SQL e
PL/SQL
 Si possono eseguire stmt SQL da dentro
PL/SQL
 Regole generali per la precedenza:
 SQL ha SEMPRE precedenza su PL/SQL
• Dentro uno statement SQL, PL/SQL cerca prima
di risolvere tutti i referimenti ad oggetti del
database
• Anche nel PL/SQL nativo, si cerca spesso di
interpretare gli identificatori che hanno un
match con gli oggetti del db come oggetti di
database
 La soluzione migliore è di concedere il
naming di oggetti PL/SQL come gli oggetti
del db
v_company_id company.company_id%TYPE;
Consigli Finali - Evitare
sovrapposizioni nel Naming
 Nonostante PL/SQL fornisca strumenti molto
flessibili per la definizione di “qualcosa”, è
consigliabile NON adoperare nomi che si
sovrappongono o che creano conflitti per le
decisioni del compilatore
• Adoperare block labels, loop labels, nomi di
moduli e di package, ecc.
• Perché affaticare il lavoro del compilatore ?
 Se possibile, evitare l’uso di nomi uguali o
cnflittuali per identificatori
• Invece di adoperare label e “sperare” in un non
conflitto, usare nomi univoci
• E usarli in maniera consistente
Consigli Finali - Stile di
Programmazione (1)
 I programmi sono più leggibili e gestibili se si
sviluppo in maniera consistente ed elegante
• Stabilire standard di sviluppo per lo stesso team
• Al minimo, pensare che ogni sviluppatore sia
“internamente consistente”
 Il seguente esempio confronta due stili di
programmazione:
 Quale dei due è più semplice da capire, e di
conseguenza, più semplice da gestire?
Consigli Finali - Function #1
function
calc_total (year_in IN
NUMBER, cid NUMBER) return number IS BEGIN /* If in
current century,
then calculate company sales.*/
if year_in = to_number(to_char
(sysdate,’YYYY’)) then return comp_sales(cid);
/* If previous century no sales. */
elsif year_in < 1900
then
return 0;
end if; end;
 Tutto qui ? … Che roba è ?
 Anche se con i commenti è difficile seguire il filo
logico del programma
Consigli Finali - Function #2
FUNCTION total_sales
(year_in IN INTEGER,
company_id
company.company_id%TYPE)
RETURN NUMBER
IS
curr_year CONSTANT INTEGER :=
TO_CHAR (SYSDATE, ‘YYYY’);
BEGIN
IF year_in = TO_NUMBER (curr_year)
THEN
RETURN comp_sales (company_id);
ELSIF year_in < 1900
THEN
RETURN 0;
END IF;
END total_sales;
 Qui non vi è bisogno di commento per capire
come va il programma !!!
Consigli Finali - Stile di
Programmazione (2)
 Delegare quanto possibile ad una buona codifica
dei costrutti del linguaggio PL/SQL la pseudo
documentazione del codice
 Rafforzare l’uso di strutture locali nel programma
 Usare maiuscolo/minuscolo per diversificare il
codice tra le parole chiave e le variabili o
identificatori
Parole Chiave Identificatori specifici di Appl.
TO_CHAR company_id
PROCEDURE total_sales_in
ELSIF balance_too_low
Consigli Finali - Indentare gli stmt
SQL
 Gli statements SQL sono complessi e non
procedurali
• Un formato consistente è fondamentale per la
loro comprensione
 Consigli:
• Separare ed Allineare le diverse clausole degli
stmt
SELECT empno, ename
FROM emp, dept
WHERE emp.deptno = dept.deptno
AND dept.deptno = 100
ORDER BY ename
UPDATE emp
SET sal = sal * 2
WHERE deptno = 100
Consigli Finali - Esempio di Hard-to-
Read SQL Stmt
 Nessuno di noi ha mai scritto nulla di simile, vero
?
 Usare ABC... per gli alias di tabella è interessante:
rappresenta un metodo semplice e consistente
senza alcun significato
select company_id, SUM (sales),
address1, company_type_ds description, min_balance
FROM
company A, sales_amount B, company_type C, company_config D,
region E, regional_status F WHERE
A.company_id = B.company_id and
A.company_type_cd = C.company_type_cd
and C.company_type_cd = D.company_type_cd and A.region_cd =
E.region_cd and E.status = F.status;
Consigli Finali - Chiara lettura dello
stmt SQL
 Netta separazione tra le clausole
 Relazioni e significato della query sono molto
più evidenti
SELECT company_id, SUM (sales),
address1,
company_type_ds description,
min_balance
FROM company COM,
sales_amount SAL,
company_type TYP,
company_config CFG,
region REG,
regional_status RST
WHERE COM.company_id = SAL.company_id
AND COM.company_type_cd =
TYP.company_type_cd
AND TYP.company_type_cd = CFG.company_type_cd
AND COM.region_cd = REG.region_cd
AND REG.status = RST.status;
Consigli Finali - Indentare in
PL/SQL
 Usare 2 - 4 spazi per indentare (o TAB).
 Indentare per ogni cambiamento della logica dello
scope: IF, LOOP, exceptions, ecc
 Andare a capo per enfatizzare la logica di
programma
FUNCTION column_name
(type_in IN VARCHAR2 := 'FULL')
IS
colname VARCHAR2(100) :=
NAME_IN ('GLOBAL.col_'||list_name);
BEGIN
IF type_in = 'FULL'
THEN
RETURN colname;
ELSE
RETURN SUBSTR (colname, 10, 6);
END IF;
END;
Consigli Finali - Indentare un
Esempio
IF condition
THEN
executables;
ELSIF condition
THEN
executables;
END IF;
WHILE loop_condition
LOOP
executables;
END LOOP;
LOOP
executables;
END LOOP;
PROCEDURE ...
IS
declarations;
BEGIN
executables;
EXCEPTION
WHEN exception
THEN
executables;
END;
PACKAGE package
IS
FUNCTION ...
PROCEDURE ...
END package;
Consigli Finali - Blank
 Usare righe vuote per:
• Separare distintamente sezioni di codice da sezioni di
dichiarazione, sezioni di exception handling, ecc.
• Per separare i cambiamenti nei livelli logici di
programma, tra IF e loop e blocchi annidati
DECLARE
/* Starting location of search */
start_loc INTEGER := 0;
/* Last character analyzed */
curr_char VARCHAR2(1);
BEGIN
DECLARE
END;
IF <condition>
THEN
END IF;
END;
Consigli Finali - I Commenti
 Non adoperarli per ripetere quello già espresso
chiaramente dal codice
 Usarli per tradurre un computer-lang in una
regola di business
 Indentare i commenti allo stesso livello del codice
che commentano
 Commentare ogni stmt di dichiarazione
 Commentare mentre si codifica, cercare di non
farlo a posteriori
Consigli Finali - Esempi di
Commento
 Alta gestione:
Bassa gestione:
/*--------------------------------*
* Molto carino da vedersi *
* ma molto operoso da gestire *
* quando vi sono modifiche! *
*--------------------------------*/
/*
|| Questo formato è più grezzo
|| ma più semplice da modificare
|| quando vi sono cambiamenti
|| senza occuparsi dei bordi.
*/
Soluzione migliore: brevi commenti su linee di codice. Sigh....
Adottare uno Stile Personale OK?!?
 Nessun problema… se non si preferisce seguire la
letteratura
 L’importante è definirsi un proprio stile ed
applicarlo sistematicamente e rigorosamente con
l’obiettivo di migliorare la documentazione e la
manutenzione successiva del codice
Le mie regole o nessun’altra ?

More Related Content

Similar to corso oracle plsql.ppt

Note di Data Warehouse e Business Intelligence - Tecniche di Naming Conventio...
Note di Data Warehouse e Business Intelligence - Tecniche di Naming Conventio...Note di Data Warehouse e Business Intelligence - Tecniche di Naming Conventio...
Note di Data Warehouse e Business Intelligence - Tecniche di Naming Conventio...Massimo Cenci
 
Novità di SQL Server 2017
Novità di SQL Server 2017Novità di SQL Server 2017
Novità di SQL Server 2017Gianluca Hotz
 
Metadata Driven Pipeline with Microsoft Fabric
Metadata Driven Pipeline  with Microsoft FabricMetadata Driven Pipeline  with Microsoft Fabric
Metadata Driven Pipeline with Microsoft FabricMarco Pozzan
 
SQL Server Modern Query Processing
SQL Server Modern Query ProcessingSQL Server Modern Query Processing
SQL Server Modern Query ProcessingGianluca Hotz
 
Data Warehouse e Business Intelligence in ambiente Oracle - Il sistema di mes...
Data Warehouse e Business Intelligence in ambiente Oracle - Il sistema di mes...Data Warehouse e Business Intelligence in ambiente Oracle - Il sistema di mes...
Data Warehouse e Business Intelligence in ambiente Oracle - Il sistema di mes...Massimo Cenci
 
Progetto e sviluppo di un'applicazione per dispositivi mobili per la visualiz...
Progetto e sviluppo di un'applicazione per dispositivi mobili per la visualiz...Progetto e sviluppo di un'applicazione per dispositivi mobili per la visualiz...
Progetto e sviluppo di un'applicazione per dispositivi mobili per la visualiz...paolabassi91
 
SQL Server Worst Practices
SQL Server Worst PracticesSQL Server Worst Practices
SQL Server Worst PracticesGianluca Sartori
 
[BASH] Shell Scripting [ITA]
[BASH] Shell Scripting [ITA][BASH] Shell Scripting [ITA]
[BASH] Shell Scripting [ITA]Matteo Collica
 
Potenza e controllo con le Parallel Libraries (Raffaele Rialdi)
Potenza e controllo con le Parallel Libraries (Raffaele Rialdi)Potenza e controllo con le Parallel Libraries (Raffaele Rialdi)
Potenza e controllo con le Parallel Libraries (Raffaele Rialdi)DotNetMarche
 

Similar to corso oracle plsql.ppt (20)

ETL basics
ETL basicsETL basics
ETL basics
 
Note di Data Warehouse e Business Intelligence - Tecniche di Naming Conventio...
Note di Data Warehouse e Business Intelligence - Tecniche di Naming Conventio...Note di Data Warehouse e Business Intelligence - Tecniche di Naming Conventio...
Note di Data Warehouse e Business Intelligence - Tecniche di Naming Conventio...
 
SQL Server2000
SQL Server2000SQL Server2000
SQL Server2000
 
Oracle PL sql 2
Oracle PL sql 2Oracle PL sql 2
Oracle PL sql 2
 
Novità di SQL Server 2017
Novità di SQL Server 2017Novità di SQL Server 2017
Novità di SQL Server 2017
 
Metadata Driven Pipeline with Microsoft Fabric
Metadata Driven Pipeline  with Microsoft FabricMetadata Driven Pipeline  with Microsoft Fabric
Metadata Driven Pipeline with Microsoft Fabric
 
Sql 1
Sql 1Sql 1
Sql 1
 
SQL Server Modern Query Processing
SQL Server Modern Query ProcessingSQL Server Modern Query Processing
SQL Server Modern Query Processing
 
Excel development e sql 1.7
Excel development e sql   1.7Excel development e sql   1.7
Excel development e sql 1.7
 
C3es
C3esC3es
C3es
 
Java lezione 10
Java lezione 10Java lezione 10
Java lezione 10
 
Data Warehouse e Business Intelligence in ambiente Oracle - Il sistema di mes...
Data Warehouse e Business Intelligence in ambiente Oracle - Il sistema di mes...Data Warehouse e Business Intelligence in ambiente Oracle - Il sistema di mes...
Data Warehouse e Business Intelligence in ambiente Oracle - Il sistema di mes...
 
Progetto e sviluppo di un'applicazione per dispositivi mobili per la visualiz...
Progetto e sviluppo di un'applicazione per dispositivi mobili per la visualiz...Progetto e sviluppo di un'applicazione per dispositivi mobili per la visualiz...
Progetto e sviluppo di un'applicazione per dispositivi mobili per la visualiz...
 
SQL Server Worst Practices
SQL Server Worst PracticesSQL Server Worst Practices
SQL Server Worst Practices
 
Excel development e sql 1.3
Excel development e sql   1.3Excel development e sql   1.3
Excel development e sql 1.3
 
[BASH] Shell Scripting [ITA]
[BASH] Shell Scripting [ITA][BASH] Shell Scripting [ITA]
[BASH] Shell Scripting [ITA]
 
Office & VBA - Giorno 6
Office & VBA - Giorno 6Office & VBA - Giorno 6
Office & VBA - Giorno 6
 
Corso Oracle
Corso OracleCorso Oracle
Corso Oracle
 
Java codestyle & tipstricks
Java codestyle & tipstricksJava codestyle & tipstricks
Java codestyle & tipstricks
 
Potenza e controllo con le Parallel Libraries (Raffaele Rialdi)
Potenza e controllo con le Parallel Libraries (Raffaele Rialdi)Potenza e controllo con le Parallel Libraries (Raffaele Rialdi)
Potenza e controllo con le Parallel Libraries (Raffaele Rialdi)
 

corso oracle plsql.ppt

  • 1. RDBMS ORACLE ELEMENTI di SQL-PL/SQL Michele gariglio
  • 2. Introduzione al PL/SQL per Oracle - I fondamentali • Linguaggio procedurale che integra ed estende l’ SQL standard • E’ di fatto proprietario di Oracle Corporation. Non esiste nessuno standard per PL/SQL ma ANSI ci sta lavorando. • Basato sui concetti di programmazione ADA. • Inizialmente forniva logiche di batch-processing per script SQL • Poi, è diventato un vero e proprio ambiente di programmazione. L’acronimo: Procedural Language SQL
  • 3. PL/SQL - I fondamentali  Una buona strada per cominciare ad esplorare il PL/SQL è cominciare da un esempio: • Il programma, elabora gli ordini per delle racchette da tennis verificandone la quantità disponibile ad inventario • Dichiara una variabile di tipo NUMBER per mantenere la quantità di racchette a disposizione • Recupera questo valore dalla tavola “inventario” del db • Se la quantità è >0 il programma modifica la tavola ed inserisce un nuovo record nella tabella “ordini” • Altrimenti, il programma evidenzia un record di “esaurito” nella tabella “ordini”
  • 4. PL/SQL - I fondamentali DECLARE qta_disp NUMBER(5); BEGIN SELECT quantita INTO qta_disp FROM inventario WHERE prodotto LIKE ’TENNIS RACKET’ FOR UPDATE OF quantita; IF qta_disp > 0 THEN UPDATE inventario SET quantita=quantita - 1 WHERE prodotto LIKE ’TENNIS RACKET’; INSERT INTO ordini VALUES (’Racchetta da Tennis ordinata’, SYSDATE); ELSE INSERT INTO ordini VALUES (’Racchette da Tennis Esaurite!’, SYSDATE); END IF; COMMIT; END;
  • 5. PL/SQL - I fondamentali • Con PL/SQL è possibile adoperare gli statement SQL per manipolare dati nel db in abbinamento al controllo di flusso di un ambiente di programmazione • E’ possibile dichiarare variabili di programma, costanti, definire procedure, definire funzioni e gestire errori di run-time (eccezioni) In definitiva PL/SQL combina la potenza interattiva della manipolazione dei dati attraverso SQL con la potenza del data processing dei linguaggi procedurali
  • 6. PL/SQL - I fondamentali  STRUTTURA a BLOCCHI  PL/SQL è un linguaggio block-structured • Le unità fondamentali (procedure, funzioni, e blocchi generici) che costituiscono un programma PL/SQL equivalgono a blocchi logici che possono contenere un qualsiasi numero di sotto-blocchi annidati • Tipicamente, ogni blocco logico corrisponde ad un problema o sotto-problema da risolvere (dividi e conquista) • Un blocco (o sotto-blocco) consente di raggruppare logicamente dichiarazioni e statement correlati • Le dichiarazioni sono locali al blocco in cui sono definite e cessano di esistere quando il blocco termina • Un blocco PL/SQL ha tre parti:  una parte dichiarativa (opzionale)  una parte di esecuzione  una parte di gestione delle eccezioni (opzionale)
  • 7. PL/SQL - I fondamentali  I BLOCCHI • Osservano una struttura di base • Due tipi di blocchi: named and anonymous • I named blocks sono functions and procedures • Quattro sessioni in un blocco: Header (rilevante solo per procedures and functions) Declaration (opzionale) Execution (sempre) Exception (opzionale) • I blocchi definiscono lo scope per le variabili e la gestione delle eccezioni • Vale l’annidamento !
  • 8. Block Header BEGIN EXCEPTION Execution Section Declaration Section Exception Section END; IS PL/SQL - I fondamentali I BLOCCHI: struttura
  • 9. PL/SQL - I fondamentali  STRUTTURA a BLOCCHI • Solo oggetti dichiarati nella prima parte possono essere adoperati nella fase di esecuzione • Le eccezioni (runtime error + warning) scatenate nella fase di esecuzione sono essere gestite dalla parte di exception handling • All’interno delle parti di esecuzione e di gestione eccezioni è possibile annidare altri blocchi • Possono essere definiti dei sottoprogrammi nella fase dichiarativa, tuttavia questi sono locali sola al blocco dove sono definiti [DECLARE ---- dichiarazioni ] BEGIN ------ statements [EXCEPTION ---handlers ] END;
  • 10. PL/SQL - I fondamentali  DICHIARAZIONE di VARIABILI Le variabili possono avere tipi di dato nativi SQL (CHAR, DATE, NUMBER, ecc.) Anche tipi di dato PL/SQL (BOOLEAN, REAL, BINARY_INTEGER, ecc.) Esempi di dichiarazione codice_articolo NUMBER(4); art_presente BOOLEAN; E’ possibile dichiarare anche tipi di dato più strutturati TABLE (tabelle annidate) VARRAY (array a lunghezza variabile) RECORD (tipo di dato composto) tipico nell’uso dei cursori
  • 11. PL/SQL - I fondamentali  ASSEGNAZIONE di Valori a Variabili • Adoperando l’operatore di assegnamento (:=)  tax := price * tax_rate;  bonus := current_salary * 0.10;  amount := TO_NUMBER(SUBSTR(’750 dollars’, 1, 3));  valid := FALSE; • Assegnando valori provenienti da select (fetch) sul database • Calcolo del bonus come 10% del salario di un impiegato:  SELECT sal * 0.10 INTO bonus FROM emp WHERE empno = emp_id; • Il valore può essere adoperato in altri calcoli o per futuri inserimenti a db  DICHIARAZIONE di COSTANTI • Come per le variabili ma con la parola chiave CONSTANT e con l’immediata assegnazione di un valore alla costante. • Da qui in poi tale valore rimarrà inalterato  credit_limit CONSTANT REAL := 5000.00;
  • 12. PL/SQL - I fondamentali  CURSORI e VARIABILI CURSORE • Dei CURSOR e della loro definizione ed utilizzo abbiamo già visto • Come un cursore, una variabile cursore punta alla riga corrente di un result set ottenuto da query multirow • Ma può essere aperta dinamicamente per ogni tipo di query compatibile • Non è necessario specificare una query: le variabili cursore sono variabili PL/SQL ! (Vale l’assegnamento, il passaggio di parametri, ecc.) • La procedura seguente apre una variabile cursore “generic_cv” per una query prescelta  PROCEDURE open_cv (generic_cv IN OUT GenericCurTyp, choice IN NUMBER) IS  BEGIN  IF choice = 1 THEN  OPEN generic_cv FOR SELECT * FROM emp;  ELSIF choice = 2 THEN  OPEN generic_cv FOR SELECT * FROM dept;  ELSIF choice = 3 THEN  OPEN generic_cv FOR SELECT * FROM salgrade;  END IF;
  • 13. PL/SQL - I fondamentali  ATTRIBUTI • Varibili e cursori PL/SQL hanno attributi • Sono proprietà che consentono di referenziare datatype e struttura di oggetti senza doverne ripetere la loro definizione • Colonne e tavole del db hanno attributi simili per la gestione • Il segno di (%) è l’indicatore di attributo  %TYPE • L’attributo %TYPE fornisce il datatype di una variabile o colonna di db • Utile per dichiarare variabili che manterranno valori dal db • Per esempio, se esiste una colonna “titolo” in una tavola “libri”, potrebbe servire dichiarare una variabile “mio_titolo” dello stesso tipo di quella colonna  mio_titolo libri.titolo%TYPE; • Vantaggi  conoscere l’esatto tipo di dato del titolo  se cambia la definizione a db del campo titolo, la mia variabile cambia a runtime
  • 14. PL/SQL - I fondamentali  ATTRIBUTI  %ROWTYPE • In PL/SQL, i record sono adoperati per mantenere valori di dati provenienti da campi • L’attributo %ROWTYPE fornisce un record type che rappresenta una riga di una tavola • Il record può mantenere righe di dati selezionate da tavole o caricate da cursori • Le colonne di una riga ed i corrispondenti campi di un record hanno gli stessi datatypes. • Nel primo esempio, si dichiara un record con nome dept_rec, i suoi campi avranno lo stesso nome e lo stesso tipo di dato delle colonne di dept • Il secondo esempio è combinato con l’utilizzo dei cursori
  • 15. PL/SQL - I fondamentali  ATTRIBUTI  %ROWTYPE • Esempio 1: DECLARE dept_rec dept%ROWTYPE;  Adoperare la dot notation per riferire i singoli campi: my_deptno := dept_rec.deptno; • Esempio 2: DECLARE CURSOR c1 IS SELECT ename, sal, hiredate, job FROM emp; emp_rec c1%ROWTYPE; Quando si adopererà lo statement: FETCH c1 INTO emp_rec; avremo la sostituzione dei valori
  • 16. PL/SQL - Strutture di controllo  Rappresentano il “gap” semantico del passaggio SQL --> PL/SQL  Fino a qui, nella fase di esecuzione di un blocco PL/SQL, abbiamo visto come trattare singoli statement sequenziali  Le strutture di controllo sono le vere e proprie strutture del linguaggio che servono a governare ed a condizionare il flusso di elaborazione sui dati  Le principali (in quasi tutti i linguaggi) sono:  IF-THEN-ELSE  FOR-LOOP  WHILE-LOOP  EXIT-WHEN  GOTO
  • 17. PL/SQL - Strutture di controllo  Il Controllo CONDIZIONALE • Azioni alternative dipendenti da specifiche circostanze • Lo statement IF-THEN-ELSE permette di eseguire blocchi di statement in modo condizionale • La clausola IF verifica una condizione • il ramo THEN definisce cosa fare quando la condizione è vera • il ramo ELSE cosa fare quando è falsa
  • 18. PL/SQL - Strutture di controllo  Il Controllo CONDIZIONALE DECLARE acct_balance NUMBER(11,2); acct CONSTANT NUMBER(4) := 3; debit_amt CONSTANT NUMBER(5,2) := 500.00; BEGIN SELECT bal INTO acct_balance FROM accounts WHERE account_id = acct FOR UPDATE OF bal; IF acct_balance >= debit_amt THEN UPDATE accounts SET bal = bal - debit_amt WHERE account_id = acct; ELSE INSERT INTO temp VALUES (acct, acct_balance, ’Insufficient funds’); END IF; COMMIT; END;
  • 19. PL/SQL - Strutture di controllo L’ITERAZIONE Lo statement di LOOP permette di eseguire un blocco di istruzioni più volte (ciclo) La parola chiave LOOP anticipa il primo statement da ripetere La parola chiave END LOOP chiude il blocco di istruzioni ripetute Il FOR-LOOP è un loop particolare definito da range di interi FOR i IN 1..order_qty LOOP UPDATE sales SET custno = customer_id WHERE serial_num = serial_num_seq.NEXTVAL; END LOOP; Il WHILE-LOOP associa una condizione di ingresso per la ripetizione del ciclo. La condizione viene valutata sempre prima dell’esecuzione del ciclo ed il TRUE è il valore di ingresso nel loop. Il loop viene saltato se la condizione è FALSE o NULL, ed il controllo passa allo statement successivo
  • 20. PL/SQL - Strutture di controllo  L’ITERAZIONE • Esempio: trovare il primo impiegato che ha un salario > 4000 $ ed il suo manager a partire dalla matricola 7902: DECLARE salary emp.sal%TYPE; mgr_num emp.mgr%TYPE; last_name emp.ename%TYPE; starting_empno CONSTANT NUMBER(4) := 7902; BEGIN SELECT sal, mgr INTO salary, mgr_num FROM emp WHERE empno = starting_empno; WHILE salary < 4000 LOOP SELECT sal, mgr, ename INTO salary, mgr_num, last_name FROM emp WHERE empno = mgr_num; END LOOP; INSERT INTO temp VALUES (NULL, salary, last_name); COMMIT; END;
  • 21. PL/SQL - Strutture di controllo  L’ITERAZIONE • Lo statement EXIT-WHEN permette l’uscita anticipata dal loop quando l’elaborazione successiva non è desiderata • Quando il programma incontra EXIT, la condizione nella clausola WHEN viene valutata. Se TRUE, il loop termina ed il controlla passa allo statement successivo • Esempio: il ciclo termina quando il valore total supera 25000 $: LOOP ... total := total + salary; EXIT WHEN total > 25000; -- esce dal loop se la condizione è true END LOOP; -- il controllo di flusso prosegue qui
  • 22. PL/SQL - Strutture di controllo  Il SALTO INCONDIZIONATO • Lo statement GOTO consente di saltare in modo incondizionato ad un punto preciso del programma identificato da una label • La label (etichetta) è un identificatore non dichiarato e deve precedere uno statement o un blocco PL/SQL • Viene esplicitata con la dicitura <<label>> : IF rating > 90 THEN GOTO calc_raise; -- salto alla label END IF; ... <<calc_raise>> IF job_title = ’SALESMAN’ THEN -- il programma continua da qui amount := commission * 0.25; ELSE amount := salary * 0.10; END IF;
  • 23. PL/SQL - Modularità  In PL/SQL è possibile definire strutture di programma più semplici da richiamare in modo modulare  VANTAGGI:  Strutturazione di un problema in problemi più semplici (divide et impera)  Modularità  Ripetitività e riuso del codice sotto diverse premesse  Migliore gestione dell’applicazione  Semplicità di definizione e di implementazione  Si organizzano in: • Sottoprogrammi  Procedure  Funzioni • Procedure esterne • Packages
  • 24. PL/SQL - Modularità  PROCEDURE e FUNZIONI • Sono blocchi di programma (subprogram) che prendono parametri e che possono essere invocati (chiamati) da blocchi esterni • Un subprogram è come un programma in miniatura che inizia con un header, seguito da una parte dichiarativa opzionale, una parte di esecuzione, e una sezione opzionale di exception-handling  PROCEDURE award_bonus (emp_id NUMBER) IS  bonus REAL;  comm_missing EXCEPTION;  BEGIN  SELECT comm * 0.15 INTO bonus FROM emp WHERE empno = emp_id;  IF bonus IS NULL THEN  RAISE comm_missing;  ELSE  UPDATE payroll SET pay = pay + bonus WHERE empno = emp_id;  END IF;  EXCEPTION  WHEN comm_missing THEN  ...  END award_bonus;
  • 25. PL/SQL - Modularità  PROCEDURE e FUNZIONI  Alla sua invocazione, questa procedura accetta il valore di una matricola  Usa questo valore per selezionarne la commissione e per calcolarne un bonus del 15%  Un successivo controllo sul bonus innalza un’eccezione se questo è null, altrimenti il payroll dell’impiegato viene modificato • La PROCEDURE non restituisce alcun valore • La FUNCTION può restituire valori CREATE FUNCTION interpolazione(x FLOAT, y FLOAT) RETURN FLOAT AS EXTERNAL LIBRARY mathlib NAME "c_interp" LANGUAGE C; • L’esempio di funzione richiama un programma (procedura) esterno  la routine è definita in un linguaggio di più basso livello (C)  occorre includere la libreria di definizione della routine (mathlib)
  • 26. PL/SQL - Modularità  PACKAGES • PL/SQL permette di raggruppare logicamente tipi, variabili, cursori e sottoprogrammi in un package • Sono semplici da capire e le loro interfacce sono semplici chiare e ben definite • I package aiutano lo sviluppo di applicazioni • Realizzano astrazione del codice ed incapsulamento • Package si costituiscono di due parti:  la specifica del package  il corpo de package (body) • La specifica è l’interfaccia in cui si dichiarano: tipi, costanti, variabili, exceptions, cursori, e sottoprogrammi disponibili all’uso dell’applicativo • Il body è l’implementazione della specifica; definisce cursori e sottoprogrammi
  • 27. PL/SQL - Modularità PACKAGES L’esempio raccoglie due procedure: CREATE PACKAGE emp_actions AS -- specifica del package PROCEDURE hire_employee (empno NUMBER, ename CHAR, ...); PROCEDURE fire_employee (emp_id NUMBER); END emp_actions; CREATE PACKAGE BODY emp_actions AS -- package body PROCEDURE hire_employee (empno NUMBER, ename CHAR, ...) IS BEGIN INSERT INTO emp VALUES (empno, ename, ...); END hire_employee; PROCEDURE fire_employee (emp_id NUMBER) IS BEGIN DELETE FROM emp WHERE empno = emp_id; END fire_employee; END emp_actions;
  • 28. PL/SQL - Modularità  PACKAGES • Solo le dichiarazioni effettuate nella specifica del package sono accessibili dall’applicazione • Il dettaglio di implementazione del body è nascosto ed inaccessibile • I package possono essere compilati e mantenuti dal database dove il loro contenuto può essere reso disponibile a diverse applicazioni • Alla prima chiamata fatta su di un oggetto del package, l’intero package viene caricato in memoria • Le successive chiamate non fanno I/O a disco • I package aumentano la produttività e migliorano le performance del sistema
  • 29. PL/SQL - Tipi di dato Astratto  Sono tipi di dato più complessi di quelli primitivi: • COLLECTIONS: gruppo ordinato di elementi tutti dello stesso tipo, corrispondono agli array dei linguaggi di terza generazione. L’elemento corrente viene riferito da un indice  TABLE  VARRAY • RECORD: aggregazione di campi di tipo diverso sotto un unico nome. Sono adoperati dal %ROWTYPE, dai cursori, ma anche nelle esplicite definizione di record dall’utente DECLARE TYPE TimeRec IS RECORD (minutes SMALLINT, hours SMALLINT); TYPE MeetingTyp IS RECORD ( day DATE, time TimeRec, -- record annidato place VARCHAR2(20), purpose VARCHAR2(50)); • OBJECT: incapsulamento di strutture dati complesse. Applicazione della metodologia OO con definizione di strutture e metodi
  • 30. PL/SQL - Gestione delle Eccezioni • PL/SQL consente di rilevare e gestire eccezioni • E’ il verificarsi a runtime di errori di programma o warning • Gestione del caso --> viene innalzata un’eccezione • L’esecuzione normale termina ed il controllo del programma viene trasferito alla sezione di exception- handling del blocco PL/SQL • Gli exception handlers sono le particolari routine scritte per gestire le eccezioni • Ne esistono di predefinite innalzate implicitamente dal sistema (se divido un numero per zero, PL/SQL innalza uno ZERO_DIVIDE in automatico) • Le eccezioni definite dall’utente si devono innalzare con lo statement RAISE  Le eccezioni vengono definite nella parte dichiarativa del blocco PL/SQL (o di un subprogram)  Nella parte di esecuzione si controlla la condizione che
  • 31. PL/SQL - Gestione delle Eccezioni • L’esempio calcola il bonus posseduto da un venditore • Il bonus si basa sul salario e sulla commissione per cui, se la commissione è null, viene innalzata un’eccezione di comm_missing.  DECLARE  ...  comm_missing EXCEPTION; -- dichiarazione  BEGIN  ...  IF commission IS NULL THEN  RAISE comm_missing; -- raise dell’eccezione  ELSE  bonus := (salary * 0.10) + (commission * 0.15);  END IF;  EXCEPTION  WHEN comm_missing THEN  -- codice per la cgestione dell’errore
  • 32. PL/SQL - Architetture  Il sistema di runtime PL/SQL è una tecnologia NON un prodotto  E’ un motore che esegue blocchi PL/SQL  Può essere installato indipendentmente su due tipi di ambiente • Oracle server • Tools come Oracle Forms or Oracle Reports  In entrambi i casi il PL/SQL engine accetta in input blocchi PL/SQL validi  Esempio di lavoro del motore PL/SQL NB: Le istruzioni puro SQL vengono eseguite dal db !
  • 33. PL/SQL - Architetture  Metodi di esecuzione • Oracle Server PL/SQL Engine  Anonymous Blocks: da tool interattivi come SQL*Plus o OEM  Stored Subprograms: procedure compilate separatamente e mantenute permanentemente nel db. Una procedura debitamente creata con CREATE è detta stored procedure. A tutti gli effetti diventa un oggetto del data dctionary. Posso richiamarli da trigger, altri stored subprogram, applicazioni Oracle Precompilate, OCI application, o interattivamente da SQL*Plus o Enterprise Manager. ES: SQL> EXECUTE create_dept(’FINANCE’, ’NEW YORK’);  Database Triggers: procedura associata ad una tavola e a degli eventi • In Oracle Tools  se dispone di un motore PL/SQL, un ambiente di sviluppo può elaborare blocchi PL/SQL  il tool passerà al db le sole chiamate relative alla elaborazione di statement SQL
  • 34. PL/SQL - Esempio di Procedura con tutte e 4 le sessioni PROCEDURE set_sales (company_id_in IN NUMBER, sales_in IN NUMBER, calc_type_in IN VARCHAR2) IS sales_amt NUMBER; upper_type VARCHAR2(30) := UPPER (calc_type_in); BEGIN IF upper_type = ‘ALL’ THEN update_company (company_id_in, sales_in); END IF; EXCEPTION WHEN DIVIDE_BY_ZERO THEN display_error; END; Header Execution Declaration Exception
  • 35. PL/SQL - Esempio di Anonymous Execution Only DECLARE emp_name emp.ename%TYPE; total_salary NUMBER; invalid_employee EXCEPTION; BEGIN total_salary := get_sal (emp_name, ‘TOTAL’); IF total_salary IS NULL THEN RAISE invalid_employee; ELSE DBMS_OUTPUT.PUT_LINE (‘Total salary is ‘ || TO_CHAR (total_salary)); END IF; EXCEPTION WHEN invalid_employee THEN ... END; Exception Declaration Execution
  • 36. PL/SQL - Annidamento  E’ possibile inscatolare un anonymous block dentro le sezioni di execution and exception di un altro blocco PL/SQL PROCEDURE ... BEGIN DECLARE BEGIN END; EXCEPTION WHEN ... THEN BEGIN END; END; • Il blocco annidato ha la medesima struttura di quello che lo rachiude • Importante ! Ha le sue sezioni di declaration ed exception. Occhio allo scope delle variabili
  • 37. PL/SQL - Esempio di Annidamento DECLARE <declarations> BEGIN DECLARE <declarations> BEGIN <executable statements> END; BEGIN <executable statements> EXCEPTION <exception handlers> END; EXCEPTION <exception handlers> END; Inner Block 1 Inner Block 2
  • 38. PL/SQL - Nota sulla Sintassi • Identificatori --> nomi per cose ! • Fino a 30 caratteri • Devono iniziare con una lettera • Valgono: “_”, “$”, “#” come separatori • Si riconoscono identificatori con nomi di program, loop, o package. • La logica di statement termina con semi-colon “;” • Statements possono essere su più righe senza continuation char • Non case-sensitive, eccetto in caso di valori string (come SQL)
  • 39. PL/SQL - Esempi di Identificatori  I seguenti identificatori sono la stessa cosa: TOTAL_sales TOTAL_SALES total_sales I seguenti sono illegali: 1st_year_total company-name match_found? the_long_name_of_the_corporation I seguenti sono OK: row# total_sales_$ First_year_total
  • 40. PL/SQL - Identificatori - Tips (1)  Rendere i nomi sia comprensibili che facilmente “riferibili” Troppo “Criptici” ! totnumcomps yrind i j k x y Troppo verbali ! total_number_companies fiscal_year_index_number Right ! total_companies year_index
  • 41. PL/SQL - Identificatori - Tips (2) • Adottare un naming convenzionale nello sviluppo delle applicazioni • Prefissi e suffissi standard per cursori e nomi di record, ecc • Permettere differenti variazioni per lo stesso identificatore non serve a nulla in particolare • Anche se per differenti programmi, non c’è nessuna ragione per avere abbreviazioni e interpretazioni diverse • Se la variabile rappresenta informazioni dal db, incorporare anche il nome dell’entità • Sfruttare le informazioni standard disponibili dal database • Tuttavia, è consigliabile non dichiarare mai variabili con lo stesso nome di una colonna. E’ possibile, ma cosa accade se serve adoperare entrambe nella medesima code area?
  • 42. PL/SQL - Alcune convenzioni nel Naming Cursori Costanti Variabili Parametri Record e Record Types suffisso: company_cur prefisso: c_earliest_date prefisso: v_company_id appendere il parameter mode: company_id_in suffisso: company_rec tot_sales_rectype
  • 43. PL/SQL - Literals  Un literal è un valore esplicito • Stringhe sono racchiuse tra apici singoli: ‘stringa’ • I booleani sono TRUE, FALSE, NULL senza apici  Permetter l’uso delle costanti esplicite nei programmi  Regole per l’uso degli apici singoli: • Per comprendere un apice nella stringa, usare due apici singoli consecutivi • Per concatenare un apice alla fine di una stringa, usare tre apici singoli ‘Steven’’s House’ Steven’s House Literal Value Evaluates To: ‘Steven’ || ‘‘‘s House’ Steven’s House ‘Steven’ || ‘‘‘,’’’ Steven’,’
  • 44. PL/SQL - Commenti  Commenti in singola linea partono con un doppio tratto (--) e terminano alla fine della linea fisica  Commenti multi linea partono con (/*) e fniscono con (*/) IF status_cd = ‘C’ -- Closed THEN /* || Reject changes. I have lots to || say here so I use a multiple || comment block. */ action_status := rejected; END IF; PROCEDURE calc_totals /* Return total sales for year. */ (year_in IN INTEGER, arg1 OUT NUMBER);
  • 45. PL/SQL - Symboli e Operatori  PL/SQL supporta l’intero set di operatori relazionali, più: Descrizione Simbolo Assegnamento := Concatenazione || Identificatore di label << name >> Diverso != oppure <> new_total := 1000; full_name := first_name || last_name; <<outer_loop>> IF curr_year != last_year THEN ...
  • 46. PL/SQL - Famiglie di Tipi di Dati Tipi di Dati PL/SQL per Famiglia Composti Scalari Records PL/SQL Tables BINARY_INTEGER DEC DECIMAL DOUBLE PRECISION FLOAT INT INTEGER NATURAL NUMBER NUMERIC POSITIVE REAL SMALLINT CHAR CHARACTER LONG LONG RAW ROWID STRING VARCHAR VARCHAR2 DATE BOOLEAN  PL/SQL supporta tutti i tipi di dati originari di Oracle Server, con alcune aggiunte particolari:
  • 47. PL/SQL - Numeri  BINARY_INTEGER sono memorizzati come numeri binari con segno • Possono essere usati nei calcoli senza conversioni, più efficiente  Specificare precisione e scala decimale. • Scala può essere negativa, che causa arrotondamenti a sinistra del punto decimale • Il default è 0 (integers). • NUMBER supportano un massimo di precisione di 38.  Usare sottotipi per migliorare in qualità e documentazione del codice company_count BINARY_INTEGER; total_sales NUMBER (20,2);
  • 48. PL/SQL - Stringhe  CHAR è a lunghezza fissa e dovrebbe essere inutilizzato se non per uso specifico (per flag, risposte quotate, ecc)  VARCHAR2 è a lunghezza variabile e può arrivare sino a 32Kbytes in lunghezza • LONG in PL/SQL è più corto di VARCHAR2: 32760. • Non esiste alcuna ragione specifica per usare LONG e LONG RAW in PL/SQL  ROWID è un tipo specifico di Oracle che identifica la LOCAZIONE FISICA di un record. Il suo formato è: BBBBBBB.RRRR.FFFF dove BBBBBBB è il numero del blocco del datafile, RRRR è il numero della riga all’interno del blocco, e FFFF è il valore HEX del datafile
  • 49. PL/SQL - Date  In PL/SQL i tipi data sono paralleli a quelli previsti nel RDBMS Oracle  Si compongono di (timestamp): • Secolo, Anno, Mese, Giorno • Ore, Minuti, Secondi  Non si possono memorizzare frazioni di secondo in una variabile di tipo data  Le date hanno un intervallo di validità che va dal 1/1/4712 AC al 31/12/4712 DC  Di default, la porzione di tempo è mezzanotte  PL/SQL ha funzioni che permettono operazioni e manipolazioni sulle date
  • 50. PL/SQL - Booleani  Una variabile dichiarata come BOOLEAN può essere TRUE, FALSE o NULL • Questi valori NON sono stringhe  NB: Oracle NON supporta colonne BOOLEAN • Tipo di dati naturale nella programmazione • Miglior lettura del codice • Occorre convertirli in Y/N o 1/0 se si desidera memorizzare dati Booleani nel database need_deposit := TRUE; IF balance_too_low THEN ... END IF;
  • 51. PL/SQL - Dichiarazioni  SEMPRE dichiarare tutte le variabili e le costanti prima di adoperarle  Dichiarare una variabile per stmt  Possibilità di definirne un valore di default in dichiarzione  Possibilità di applicarne la clausola NOT NULL • Ma definirne un valore di default  Usare gli attributi %TYPE e %ROWTYPE per ancorare la variabile ad una variabile esistente o ad un elemento di db DECLARE <var_name> <datatype> [ NOT NULL ] [ := <def_value> ];
  • 52. PL/SQL - Esempi di Dichiarazioni  Senza vincoli: hire_date DATE; total_sales NUMBER; balance_too_low BOOLEAN; Vincolate e con defaults ename VARCHAR2(30) DEFAULT ‘ACME’; sales_amt NUMBER(15,2) NOT NULL := 0; Costanti closed_status CONSTANT CHAR(1) := ‘C’; Dichiarazione Ancorata ename emp.ename%TYPE; total_sales sales_amt%TYPE; emp_rec emp%ROWTYPE;
  • 53. PL/SQL - Ancoraggio DECLARE ename emp.ename%TYPE; new_emp_name ename%TYPE; BEGIN ename empno hiredate VARCHAR2(60) NUMBER DATE The emp table structure
  • 54. PL/SQL - Ancoraggio i Vantaggi  Il meccanismo dell’ancoraggio sincronizza le variabili PL/SQL con righe e colonne di database • Se una variabile o un parametro PL/SQL dovrà rappresentare una informazione di database nel programma userà SEMPRE %TYPE or %ROWTYPE. • Mantengono il programma in sintonia con le strutture del db senza grosse modifiche del codice  L’ancoraggio normalizza le dichiarazioni delle variabili derivate • Essere certi della consistenza dei nomi di entità • Ricompilare gli upgrade e le modifiche fatte ad una dichiarazione
  • 55. PL/SQL - il NULL in PL/SQL  NULL significa “indeterminato” • Non equivale a 0 o blank • NULL non è mai uguale a nient’altro, nemmeno a NULL • NULL non è mai diverso da nient’altro  Quando si applica un NULL come argomento di una funzione, in ritorno si ha NULL. Eccezioni: • NVL: converte NULL in un altro valore • La concatenazione ignora i NULL • REPLACE: NULL causa la rimozione di caratteri da stringhe  Usare IS NULL e IS NOT NULL per accertarsi della presenza di null values
  • 56. PL/SQL - Null nelle Funzioni  Normalmente, un argomento NULL gemera il return di valori NULL TO_DATE (NULL) NULL NVL converts a NULL: NVL (NULL, ‘N/A’) ‘N/A’ Concatenation ignores null values: ‘Steven ‘ || NULL || ‘Feuerstein’ ‘Steven Feuerstein’ Certamente è rara la codifica pura di NULL negli statements. NULL è invece un valore assunto da una variabile
  • 57. PL/SQL - Null da Verificare  ATTENZIONE ! Le seguenti condizioni NON verranno mai valutate con TRUE  Remember: niente è mai uguale o diverso da NULL emp_rec.hiredate IS NULL emp_rec.hiredate IS NOT NULL Adoperare gli operatori IS NULL e IS NOT NULL: emp_rec.hiredate = NULL emp_rec.hiredate != NULL NULL = NULL
  • 58. PL/SQL - Scope e Visibilità  Una volta dichiarata una variabile o, più in generale, un identificatore è lecito adoperarli  Si faranno riferimenti ad esso nel codice  PL/SQL risolve i riferimenti alle variabili con regole baste su scope e visibilità.  SCOPE è la porzione di codice all’interno della quale è possibile fare riferimento ad un identificatore  Un identificatore è VISIBILE se è possibile fare ad esso riferimento con un nome non qualificato  I nomi qualificati sono quelli per cui vale la “dot notation”, come per tabella.colonna o package.modulo or record.campo
  • 59. PL/SQL - Scope and Visibilità nei blocchi annidati DECLARE N NUMBER; BEGIN ... DECLARE N NUMBER; BEGIN ... END; ... END; DECLARE N NUMBER; BEGIN ... DECLARE N NUMBER; BEGIN ... END; ... END; DECLARE N NUMBER; BEGIN ... DECLARE N NUMBER; BEGIN ... END; ... END; DECLARE N NUMBER; BEGIN ... DECLARE N NUMBER; BEGIN ... END; ... END; Scope Visibilità Outer N Inner N
  • 60. PL/SQL - Referenziamento  PL/SQL richiede un riferimento “qualificato” per distinguere due oggetti con lo stesso nome ma dichiarati in scope diversi <<outer_block>> DECLARE total_sales NUMBER; BEGIN <<inner_block>> DECLARE total_sales NUMBER; BEGIN total_sales := outer_block.total_sales; END; display_totals (total_sales); END;
  • 61. PL/SQL - Precedenze tra SQL e PL/SQL  Si possono eseguire stmt SQL da dentro PL/SQL  Regole generali per la precedenza:  SQL ha SEMPRE precedenza su PL/SQL • Dentro uno statement SQL, PL/SQL cerca prima di risolvere tutti i referimenti ad oggetti del database • Anche nel PL/SQL nativo, si cerca spesso di interpretare gli identificatori che hanno un match con gli oggetti del db come oggetti di database  La soluzione migliore è di concedere il naming di oggetti PL/SQL come gli oggetti del db v_company_id company.company_id%TYPE;
  • 62. Consigli Finali - Evitare sovrapposizioni nel Naming  Nonostante PL/SQL fornisca strumenti molto flessibili per la definizione di “qualcosa”, è consigliabile NON adoperare nomi che si sovrappongono o che creano conflitti per le decisioni del compilatore • Adoperare block labels, loop labels, nomi di moduli e di package, ecc. • Perché affaticare il lavoro del compilatore ?  Se possibile, evitare l’uso di nomi uguali o cnflittuali per identificatori • Invece di adoperare label e “sperare” in un non conflitto, usare nomi univoci • E usarli in maniera consistente
  • 63. Consigli Finali - Stile di Programmazione (1)  I programmi sono più leggibili e gestibili se si sviluppo in maniera consistente ed elegante • Stabilire standard di sviluppo per lo stesso team • Al minimo, pensare che ogni sviluppatore sia “internamente consistente”  Il seguente esempio confronta due stili di programmazione:  Quale dei due è più semplice da capire, e di conseguenza, più semplice da gestire?
  • 64. Consigli Finali - Function #1 function calc_total (year_in IN NUMBER, cid NUMBER) return number IS BEGIN /* If in current century, then calculate company sales.*/ if year_in = to_number(to_char (sysdate,’YYYY’)) then return comp_sales(cid); /* If previous century no sales. */ elsif year_in < 1900 then return 0; end if; end;  Tutto qui ? … Che roba è ?  Anche se con i commenti è difficile seguire il filo logico del programma
  • 65. Consigli Finali - Function #2 FUNCTION total_sales (year_in IN INTEGER, company_id company.company_id%TYPE) RETURN NUMBER IS curr_year CONSTANT INTEGER := TO_CHAR (SYSDATE, ‘YYYY’); BEGIN IF year_in = TO_NUMBER (curr_year) THEN RETURN comp_sales (company_id); ELSIF year_in < 1900 THEN RETURN 0; END IF; END total_sales;  Qui non vi è bisogno di commento per capire come va il programma !!!
  • 66. Consigli Finali - Stile di Programmazione (2)  Delegare quanto possibile ad una buona codifica dei costrutti del linguaggio PL/SQL la pseudo documentazione del codice  Rafforzare l’uso di strutture locali nel programma  Usare maiuscolo/minuscolo per diversificare il codice tra le parole chiave e le variabili o identificatori Parole Chiave Identificatori specifici di Appl. TO_CHAR company_id PROCEDURE total_sales_in ELSIF balance_too_low
  • 67. Consigli Finali - Indentare gli stmt SQL  Gli statements SQL sono complessi e non procedurali • Un formato consistente è fondamentale per la loro comprensione  Consigli: • Separare ed Allineare le diverse clausole degli stmt SELECT empno, ename FROM emp, dept WHERE emp.deptno = dept.deptno AND dept.deptno = 100 ORDER BY ename UPDATE emp SET sal = sal * 2 WHERE deptno = 100
  • 68. Consigli Finali - Esempio di Hard-to- Read SQL Stmt  Nessuno di noi ha mai scritto nulla di simile, vero ?  Usare ABC... per gli alias di tabella è interessante: rappresenta un metodo semplice e consistente senza alcun significato select company_id, SUM (sales), address1, company_type_ds description, min_balance FROM company A, sales_amount B, company_type C, company_config D, region E, regional_status F WHERE A.company_id = B.company_id and A.company_type_cd = C.company_type_cd and C.company_type_cd = D.company_type_cd and A.region_cd = E.region_cd and E.status = F.status;
  • 69. Consigli Finali - Chiara lettura dello stmt SQL  Netta separazione tra le clausole  Relazioni e significato della query sono molto più evidenti SELECT company_id, SUM (sales), address1, company_type_ds description, min_balance FROM company COM, sales_amount SAL, company_type TYP, company_config CFG, region REG, regional_status RST WHERE COM.company_id = SAL.company_id AND COM.company_type_cd = TYP.company_type_cd AND TYP.company_type_cd = CFG.company_type_cd AND COM.region_cd = REG.region_cd AND REG.status = RST.status;
  • 70. Consigli Finali - Indentare in PL/SQL  Usare 2 - 4 spazi per indentare (o TAB).  Indentare per ogni cambiamento della logica dello scope: IF, LOOP, exceptions, ecc  Andare a capo per enfatizzare la logica di programma FUNCTION column_name (type_in IN VARCHAR2 := 'FULL') IS colname VARCHAR2(100) := NAME_IN ('GLOBAL.col_'||list_name); BEGIN IF type_in = 'FULL' THEN RETURN colname; ELSE RETURN SUBSTR (colname, 10, 6); END IF; END;
  • 71. Consigli Finali - Indentare un Esempio IF condition THEN executables; ELSIF condition THEN executables; END IF; WHILE loop_condition LOOP executables; END LOOP; LOOP executables; END LOOP; PROCEDURE ... IS declarations; BEGIN executables; EXCEPTION WHEN exception THEN executables; END; PACKAGE package IS FUNCTION ... PROCEDURE ... END package;
  • 72. Consigli Finali - Blank  Usare righe vuote per: • Separare distintamente sezioni di codice da sezioni di dichiarazione, sezioni di exception handling, ecc. • Per separare i cambiamenti nei livelli logici di programma, tra IF e loop e blocchi annidati DECLARE /* Starting location of search */ start_loc INTEGER := 0; /* Last character analyzed */ curr_char VARCHAR2(1); BEGIN DECLARE END; IF <condition> THEN END IF; END;
  • 73. Consigli Finali - I Commenti  Non adoperarli per ripetere quello già espresso chiaramente dal codice  Usarli per tradurre un computer-lang in una regola di business  Indentare i commenti allo stesso livello del codice che commentano  Commentare ogni stmt di dichiarazione  Commentare mentre si codifica, cercare di non farlo a posteriori
  • 74. Consigli Finali - Esempi di Commento  Alta gestione: Bassa gestione: /*--------------------------------* * Molto carino da vedersi * * ma molto operoso da gestire * * quando vi sono modifiche! * *--------------------------------*/ /* || Questo formato è più grezzo || ma più semplice da modificare || quando vi sono cambiamenti || senza occuparsi dei bordi. */ Soluzione migliore: brevi commenti su linee di codice. Sigh....
  • 75. Adottare uno Stile Personale OK?!?  Nessun problema… se non si preferisce seguire la letteratura  L’importante è definirsi un proprio stile ed applicarlo sistematicamente e rigorosamente con l’obiettivo di migliorare la documentazione e la manutenzione successiva del codice Le mie regole o nessun’altra ?

Editor's Notes

  1. 1
  2. 5
  3. 6
  4. 3
  5. 7
  6. 9
  7. 11
  8. 12
  9. 13
  10. 14
  11. 15
  12. 16
  13. 18
  14. 19
  15. 20
  16. 21
  17. 23
  18. 24
  19. 25
  20. 26
  21. 27
  22. 28
  23. 29
  24. 30
  25. 31
  26. 32
  27. 33
  28. 34
  29. 35
  30. 36
  31. 37
  32. 38
  33. 39
  34. 40
  35. 41
  36. 42
  37. 43
  38. 47
  39. 48
  40. 49
  41. 50
  42. 51
  43. 52
  44. 53
  45. 55
  46. 56