Kosmous beyond the clouds: Sviluppo, Formazione e Consulenza Informatica

IL PL/SQL

Questo è il primo documento dedicato al Procedural Language di Oracle. Questo documento non è un sostituto della guida PL/SQL di Oracle, al quale si ispira, ma soltanto una breve raccolta di appunti che possono risultare particolarmente utili a chi si sta avvicinando al mondo Oracle.

Il linguaggio SQL (STRUCTURED QUERY LANGUAGE) viene definito come linguaggio di quarta generazione, in quanto esprime cosa dovrebbe esser fatto, ma non come deve essere fatto. I linguaggi di terza generazione invece sono quelli che implementano degli algoritmi che, passo passo, dicono quello che deve essere fatto e come. Tale linguaggio è stato standardizzato dall'ANSI, tuttavia le varie software house ne hanno esteso le funzionalità, imponendo anche il rispetto di determinati construtti. Per questo si possono trovare differenze, anche sensibili, tra un prodotto ed un altro, per cui è possibile che una determinata query funzioni su un sistema e non su un'altro, e viceversa. In questo articolo sii fa riferimento al linguaggio di Oracle.

Il PL/SQL permette di combinare la potenza e la flessibilità dell'SQL con estensioni di tipo procedurale tipici dei linguaggi di terza generazione. Ad esempio:
Strutture di controllo
Variabili, Constanti, Array
Procedure, funzioni e Package.

Il codice PL/SQL viene inglobato in strutture definite “Blocchi”. Un blocco è generalmente costituito da tre elementi:

DECLARE
-
BEGIN
-
EXCEPTION
--
END;


DECLARE:
Questa è la sezione dichiarativa del blocco. In essa vengono pertanto definiti gli elementi utilizzati nel corpo del blocco. Ad esempio Variabili, Constanti, Cursori, Array, etc.
In questa sezione tali elementi possono essere anche inizializzati.
La sezione non è obbligatoria, per cui potrei avere benissimo un blocco PL/SQL in cui non esiste questa sezione perchè non vengono utilizzati nè variabili nè costanti.

BEGIN:
Questa è l'unica sezione obbligatoria di un blocco PL/SQL, detta anche "corpo". All'interno di essa vengono definiti i comandi che devono essere eseguiti, le istruzioni SQL, l'assegnazione di valori alle variabili, il controllo del flusso etc.

EXCEPTION:
Anche questa sezione è opzionale, ma è buona norma inserirla sempre, in quanto è la parte del blocco destinata alla gestione degli errori. Come vedremo meglio più avanti, gli errori gestibili possono essere errori di default od errori definiti dagli utenti che vogliono un controllo più puntuale sull'esecuzione del codice.

END;
Questo è il comando che chiude il blocco, e deve sempre essere presente (come il BEGIN).
Notare che il comando è seguito da un punto e virgola (;). Se ci si dimentica di inserirlo, il blocco non funziona.

I blocchi possono anche essere innestati. Nella sezione BEGIN potrei avere la definizione di un altro blocco (e quindi un altro DECLARE, BEGIN, EXCEPTION ed END;). In questi casi devo prestare molta attenzione alla visibilità degli elementi. Generalmente una variabile definita nel blocco più esterno è visibile anche nel blocco più interno, ma non il viceversa. Tale argomento verrà trattato in maniera più approfondita negli articoli successivi.

I blocchi vengono poi classificati in:

ANONYMOUS:
Si tratta di codice costruito dinamicamente all'occorenza, che viene eseguito soltanto una volta. Generalmente viene lanciato da un Client (dove viene creato o dove risiede). Dopo la loro esecuzione, sul server non rimane traccia del blocco, ma solo delle eventuali modifiche da esso apportate.

NAMED:
Sono blocchi cui è associato un nome. Possono essere a loro volta catalogati come:
  • LABELED BLOCKS; sono come i blocchi anonimi, ma hanno una LABEL che permette di far riferimento ad alcune variabili che altrimenti non sarebbero visibili.
  • PROCEDURE e FUNZIONI; sono blocchi registrati sul DB e che possono essere richiamati in qualunque momento da altri blocchi o direttamente tramite il loro nome.
  • TRIGGERS; sono blocchi associati ad eventi del Database, come comandi DML o DDL.

Adesso che abbiamo fatto una breve panoramica, cominciamo con l'addentrarci nei dettagli.

GLI IDENTIFICATORI
Gli identificatori sono i nomi che possono essere assegnati ad oggetti quali variabili, costanti, Label etc. Essi possono essere:
  • Lunghi fino a 30 caratteri

  • Devono cominciare per lettera

  • Possono contenere solo i caratteri speciali _, $ e #

  • Non possono contenere spazi

  • Non possono essere parole riservate (come SELECT, FROM etc.)

  • Non sono Case-sensitive (var1, Var1, VAR1 sono cioè la stessa cosa).


Tali regole fanno eccezione se inserisco l'identificatore tra doppi apici (es: “var1”); In questi casi diventano:
  • Case sensitive (quindi “var1” sarà diverso da “VAR1”)

  • Possono essere delle parole riservate (quindi “SELECT” può essere usato)

  • Possono contenere anche caratteri speciali (come lo spazio, !, £ etc.)

  • Il limite massimo, invece, rimane sempre di 30 caratteri.

Tuttavia è buona norma non utilizzare identificatori con i doppi apici, in quanto sarei costretto a riferirmi ad essi sempre con i doppi apici. A parte la scomodità di tale soluzione, potrei anche aver dei problemi se decido di interfacciarmi ad Oracle con applicazioni che fanno un uso diverso dei doppi apici, apici singoli ed apici inversi.

Occorre anche prestare molta attenzione se ci si riferisce ad oggetti del Data Dictionary: essi sono tutti registrati nel DB in Upper-Case. Pertanto se mi riferisco a tali oggetti, utilizzando i doppi apici, devo ricordarmi di scriverne i nomi in maiuscolo.





DELIMITATORI
I delimitatori sono invece i simboli utilizzati nel DB aventi un significato speciale. Ad esempio il <, >, =, := , - - , /*


LITERALS
Con questo termine si intende invece un qualunque valore di tipo numerico, carattere o booleano che non è un identificatore. Tali elementi possono essere suddivisi in tre categorie diverse:

1) Stringa
Tale valore deve sempre essere inserito tra due apici singoli.Se scrivo:
SQL> SELECT * FROM tabella1 WHERE colonna1= 'ciao' ;
In questa istruzione, 'ciao' è una stringa. Le stringhe sono tutte case-sensitive. Quindi 'ciao' sarà diverso da 'CIAO'.
Se la stringa contiene un apostrofo, devo quotarlo con l'apice stesso.
Nell' esempio precedente, se dovessi fare una query che deve estrarre il valore Fabio's dovrei scrivere:
SQL> SELECT * FROM tabella1 WHERE colonna1 = 'Fabio''s' ;

Mi ritrovo quindi 4 apici singoli, dove il secondo mi serve per quotare il terzo.

Se dovessi eseguire una nuova ricerca nella colonna1, dalla quale voglio estrarre un eventuale apice singolo, dovrei scrivere:

SQL> SELECT * FROM tabella1 WHERE colonna1 = '''' ;

Quindi ho 4 apici in totale, di cui: il primo indica l'inizio della stringa, il secondo ed il terzo mi individuano l'apice singolo, il quarto mi chiude la stringa.

2) Numero
Può essere un valore Intero o Reale (cioè preceduto dal segno + o dal segno -). In questi casi non vanno messi tra apici.
Esempi:

SQL> SELECT * FROM tabella1 WHERE colonna1 = 32;
SQL> SELECT * FROM tabella1 WHERE colonna1 = +32;
SQL> SELECT * FROM tabella1 WHERE colonna1 = -32;
SQL> SELECT * FROM tabella1 WHERE colonna1 = -32.44;
SQL> SELECT * FROM tabella1 WHERE colonna1 = 32.0;
SQL> SELECT * FROM tabella1 WHERE colonna1 = 1.234E5;
SQL> SELECT * FROM tabella1 WHERE colonna1 = 1.234E-5;
SQL> SELECT * FROM tabella1 WHERE colonna1 = -1.23e+4;


3) Booleano
Può assumere solo tre valori: TRUE, FALSE e NULL.


COMMENTI
I commenti sono una parte molto importante nella scrittura del codice, in quanto permettono di documentare passo passo i vari pezzetti che costituiscono il nostro codice. Nel PL/SQL posso avere:
  • Commenti sulla singola riga, che cominciano col doppio trattino e finiscono alla fine della riga.

  • Commenti su più righe (cominciano con /* e finiscono con */)
Inserirli correttamente permette di limitare gli errori in fase di scrittura del codice; ad esempio
posso indicare schematicamente quello che l'istruzione deve fare, e poi trasformare questo breve riassunto in codice. Es:

SQL> -- estrazione del campo col1 e col2 dalla tabella tab1
SQL> SELECT col1, col2 FROM tab1;


oppure indicare la funzione del blocco di codice

SQL> /*
SQL> Blocco che estrae dalle tabelle tab1 e tab2 i record che devono essere modificati
SQL> memorizzandoli temporaneamente nella tabella temporanea.
SQL> verificando che .....
SQL> */


o di una variabile

SQL> -- var1 contiene la matricola degli utenti.

Questo tipo di commenti risulta molto utile quando occorre fare delle modifiche al codice molto tempo dopo averlo scritto. Permette di individuare rapidamente la parte del blocco che esegue quella funzione specifica, limitando il rischio di modificare una parte sbagliata.

Può risultare anche particolarmente utile in fase di Debug:
posso far stampare a video il valore di una variabile per controllare se contiene effettivamente il dato che mi aspetto. Poi invece di eliminare l'istruzione, la commento perchè potrei avere la necessità di ricontrollare quel valore durante un'altra fase di test dell'applicazione.

SQL> DBMS_OUTPUT.PUT_LINE('il valore di var1 è: ' || var1);


Attenzione: per vedere la stampa dell'istruzione devo abilitare l'output a video mediante il comando

SQL> set serveroutput on



Questo documento non è un documento ufficiale della Oracle Corporation. Oracle detiene tutti i diritti sulla propria documentazione. Alcuni termini usati sono trademarks registrati. In caso di dubbi o incertezze consultate la documentazione ufficiale di Oracle o contattate il Customer Support di Oracle.

Commenti (2)2003-06-16

21/08/2012 - stefano scrive:
debbo importare in una colonna delle stringhe di caratteri al netto dei doppi apici di apertura e chiusura dell'attributo. come si fa? Es. "Ragionier Filini" in tabella anagrafica: vorrei avere solo Ragionier Filini Grazie
22/09/2010 - crelui scrive:
pagina ok testo esaustivo