DB Database Data Base PLSQL Oracle
DB Database Data Base PLSQL Oracle
DB ORACLE
PLSQL
La struttura logica del database Oracle è separata dalla struttura fisica: la gestione
della memorizzazione fisica dei file è pertanto trasparente rispetto alle strutture
logiche del database.
DATABASE ORACLE
TABLESPACE TABLESPACE
… … …
DATAFILE DATAFILE
SEGMENT
EXTENT
EXTENT
RIASSUNTO
STRUTTURA
LOGICA
TABLESPACES OBJECTS DEL
DATABASE
DATAFILES SEGMENTS
STRUTTURA
EXTENTS FISICA
DEL
DATABASE
DBBLOCKS
1.5. TABLESPACES
In un database Oracle esiste sempre almeno la tablespace SYSTEM. Oracle
raccomanda di creare almeno un’altra tablespace per memorizzare gli oggetti degli
utenti separatamente dal dizionario dati contenuto nella SYSTEM.
La creazione di diverse tablespaces può dare maggiore flessibilità alle diverse
operazioni sui dati:
1. distribuire il carico sui BUS di I/O
a. creando le tabelle e gli indici su tablespace distinte i cui datafiles sono
su controller diversi (più usata);
b. creando le tabelle che sono in relazione tra loro su tablespaces diverse,
incrociando i relativi indici sulle tablespaces.
2. separare gli oggetti in base alla tipologia di dato:
a. tabelle statiche;
b. tabelle a crescita costante;
c. tabelle la cui dimensione è variabile nel tempo con andamento
oscillante.
3. creare tablespaces temporanee che non contengano oggetti permanenti;
4. creare tablespaces che contengano solo i segmenti di rollback
2. CORSO PL/SQL
PL/SQL è il linguaggio di Oracle che estende l’SQL con i costrutti tipici dei linguaggi di
programmazione procedurali consentendo la modularità, la dichiarazione di variabili, i loop e
altri costrutti logici, oltre ad una avanzata gestione degli errori.
Raggruppando i comandi SQL in un blocco PL/SQL si riduce il lavoro del client e si ottimizza
il traffico di rete, poiché il programma PL/SQL viene inviato al database come un’unica
transazione.
Manuale DB ORACLE - PLSQL
Una transazione è l’unità logica di lavoro che contiene una o più istruzioni SQL eseguite da
un singolo utente; gli effetti di tutte le istruzioni SQL in una transazione possono essere
tutte committed (applicate effettivamente al database) o tutte rolled back (non riportate
sul database).
3.1. Triggers
Sono blocchi di codice PL/SQL legati ad una tabella e vengono eseguiti al verificarsi di uno
specifico evento.
Il trigger va visto come un evento che scatena un’azione; è buona norma che il codice del
trigger contenga solo la chiamata alla funzione/procedura contenuta nella SP e quanto altro
è proprio necessario.
I trigger di database possono essere associati all’inserimento/modifica/cancellazione di una
tabella o di una vista;
Per la tabella sia nel momento BEFORE che nel momento AFTER,
per la vista solo come INSTEAD OF.
In generale si ha un trigger statement che scatta una sola volta al verificarsi dell’evento.
I trigger possono essere creati con l’opzione “FOR EACH ROW” che fa scattare il trigger ad
ogni riga che inserisco/aggiorno/cancello.
DECLARE
sezione_dichiarativa_variabili…
BEGIN
blocco_di_esecuzione
blocco_gestione_eccezioni
END;
Vengono create nello schema di un utente e il loro nome deve essere univoco all’interno
dello schema.
Gli argomenti della procedura sono le variabili utilizzate per ricevere e mandare valori da/al
programma. Possono essere di tipo:
IN - solo di input; i loro valori non possono essere variati dalla procedura che li
tratta come costanti;
OUT – output; variabili aggiornate dalla procedura;
IN OUT – variabili usate sia per l’input che per l’output di valori.
Il tipo di un argomento non è obbligatorio; il default è IN.
Per ogni argomento deve essere obbligatoriamente specificato il datatype, (senza indicare la
dimensione)
Per eseguire una Procedura: (in genere conviene prendere il codice script
generato dal debugger)
execute nome_procedura
oppure
declare
vStr VARCHAR2(10);
begin
dbms_output.enable(10);
Nome_PACKAGE.NomeProcedure(vStr);
dbms_output.put_line('VALORE' || vStr );
end;
Per essere utilizzate in comandi SQL non possono modificare lo stato del DB o il valore delle
variabili di un package.
Sezione_dichiarativa_variabili…
BEGIN
sezione_esecuzione
…
…
sezione di gestione eccezioni
RETURN …
END;
3.5. Packages
Un PACKAGE è uno SCHEMA OBJECT costituito da una collezione di procedure e funzioni,
cursori e variabili che viene trattata come un’unità.
I packages possono essere richiamati esplicitamente da un’applicazione o da un utente.
variable_name datatype; il tipo dato può essere un qualsiasi datatype Oracle o uno
dei tipi dati propri di PL/SQL; per assegnare un valore iniziale si fa
seguire := valore
constant_name CONSTANT datatype := valore;
exception_name EXCEPTION;
Manuale DB ORACLE - PLSQL
BEGIN
--- codice ---
IF condizione THEN
RAISE exception_name;
END IF;
--- codice ---
EXCEPTION
WHEN exception_name THEN
--- codice ---
END;
3.8. Identificatori
Un identificatore è un nome che possiamo assegnare ai diversi oggetti PL/SQL:
Costanti;
Variabili;
Record;
Cursori;
Exception;
Datatypes PL/SQL:
DEC, DECIMAL, REAL, DOUBLE_PRECISION, INTEGER
INT, SMALLINT, NATURAL
Manuale DB ORACLE - PLSQL
%type – per dichiarare una variabile con lo stesso datatype e la stessa dimensione della
colonna del database alla quale deve corrispondere.
%rowtype – permette di creare un datatype composto, ovvero un record, costituito da
tutte le colonne di una riga di una tabella o di un cursore.
IF…THEN…ELSE
IF condizione1 THEN
sequenza di istruzioni
ELSIF condizione2 THEN
sequenza di istruzioni
ELSE
ultima sequenza di istruzioni
END IF;
LOOP…END LOOP;
(è un loop infinito a meno che l’uscita non sia controllata da EXIT, EXIT WHEN, o dalla generazione di
un’exception
<<etichetta>>
LOOP
sequenza di istruzioni
IF condizione THEN EXIT etichetta; -- (oppure: EXIT etichetta WHEN condizione;)
END LOOP etichetta;
FOR
FOR indice IN [REVERSE] inf..sup LOOP
sequenza di istruzioni
END LOOP;
Non è possibile alterare lo step per l’intervallo di iterazioni, che vale sempre 1. Si può usare
il comando MOD(m,n) all’interno di una struttura IF…END IF.
Il comando EXIT può essere usato all’interno di questa struttura per forzare l’uscita
prematura da loop.
Manuale DB ORACLE - PLSQL
3.11. Etichette
Quando un identificatore di un sub-block assume lo stesso nome di un identificatore
dell’enclosing-block diventa impossibile utilizzare quest’ultimo all’interno del sub-block
anche se l’ambito di visibilità lo permette.
Infatti poiché PL/SQL non ha elementi per distinguere i due identificatori esso attribuisce la
priorità a quello locale.
Per ovviare a questo inconveniente dobbiamo far uso delle etichette cioè anteporre all’inizio
del blocco un nome racchiuso tra doppie parentesi angolari come nell’esempio che segue:
In questo modo possiamo far riferimento anche ad altri identificatori omonimi presenti
nell’enclosing-block (es .nome blocco.nome identificatore).
3.12. Records
Un record è un insieme di dati logicamente correlati memorizzati in campi distinti ognuno
dei quali ha un nome ed un tipo di dato.
Per usare i record è necessario prima definire un tipo di record e successivamente
dichiarare variabili di quel tipo:
E’ possibile accedere ai singoli campi del record indicandoli per note e utilizzando la
notazione punto:
nome_record.nome_campo
Usando questa notazione si possono compiere diverse operazioni con i records come
assegnare valori ai singoli campi, leggere valori, etc… come se si trattasse di semplici
variabili.
Esistono inoltre forme di record implicite che possono essere utilizzate in tipiche istruzioni
come quelle che scorrono le righe associate ad un cursore in un ciclo FOR LOOP:
FOR REC1 IN CUR1 LOOP
… istruzioni
Manuale DB ORACLE - PLSQL
END LOOP;
3.13. Cursori
La potenza del PL/SQL è in gran parte dovuta alla possibilità di utilizzare i cursori.
Un cursore gestisce l’accesso a un indirizzo di memoria in cui sono memorizzati i record
risultanti dall’esecuzione di un comando SQL e consente di manipolare singolarmente
ciascuna delle righe restituite da una SELECT.
Possono essere espliciti o impliciti.
CURSORI ESPLICITI: comandi SQL predefiniti che restituiscono più di una riga.
Vengono gestiti in modo esplicito usando i comandi OPEN, FETCH e CLOSE o usando i
cursor loops:
o OPEN: carica le righe identificate dalla query
o FETCH: restituisce una riga dall’insieme di righe selezionate e inserisce i valori
in un record o insieme di variabili specificate nella clausola INTO.
o CLOSE: chiude il cursore, rilasciando la memoria che gli era stata assegnata.
Un cursor loop controlla il cursore senza la necessità di usare OPEN, FETCH o CLOSE; ha il
formato:
FOR rec_id IN cursor_id LOOP
--- codice ---
END LOOP;
I cursori (espliciti e impliciti) hanno degli attributi che permettono di verificare il loro stato.
Per i cursori espliciti gli attributi sono:
cursor_name%FOUND – per un cursore aperto, vale NULL prima della fetch
iniziale. Diventa TRUE se l’ultima fetch è stata eseguita con successo.
cursor_name%ISOPEN – vale FALSE prima che il cursore venga aperto, TRUE se
è stato aperto ed è ancora aperto.
cursor_name%NOTFOUND – vale FALSE se l’ultima fetch fornisce una riga. Vale
TRUE se l’ultima fetch non è stata eseguita con successo.
cursor_name%ROWCOUNT – restituisce il numero di righe su cui si è effettuata
la fetch fino a quel momento. Vale NULL prima che il cursore venga aperto; zero
prima della fetch iniziale.
EX:
<<NomeEtichetta>>
loop
fetch tmpEle into tmpRec;
exit when tmpEle%NOTFOUND;
......
end if;
end loop NomeEtichetta;
L’uso corretto dei cursori prevede una serie di operazioni articolate in quattro fasi distinte:
dichiarazione del cursore;
apertura del cursore con l’istruzione OPEN in modo da consentire la preparazione
delle risorse associate al cursore e l’esecuzione della relativa istruzione SQL;
Manuale DB ORACLE - PLSQL
o %ROWCOUNT = 0.
DELETE: è possibile determinare lo stato di un’istruzione DELETE mediante gli attributi:
se la transazione ha successo (cioè vengono cancellate delle righe)
o %FOUND vale TRUE
o %NOTFOUND vale FALSE
o %ROWCOUNT = numero di righe cancellate;
se nessuna riga viene cancellata
o %FOUND vale FALSE
o %NOTFOUND vale TRUE
o %ROWCOUNT = 0.
DECLARE
………………
Nome_exception EXCEPTION;
PRAGMA EXCEPTION_INIT(Nome_exception, -NumeroErroreOracle);
BEGIN
…….
EXCEPTION
WHEN nome_exception THEN
istruzioni;
……
END;
7. Corso SQL
SQL (Structured Query Language)
Oracle aderisce allo standard ANSI/ISO SQL.
Lo scopo di SQL è quello di fornire un’interfaccia a un database relazionale.
Le caratteristiche di SQL sono:
• Elabora un gruppo di dati piuttosto che unità individuali
• I comandi per il controllo del flusso non fanno parte di SQL originale
(PL/SQL è un’estensione di SQL che consente la programmazione
procedurale)
SQL comprende comandi che consentono di:
• Interrogare i dati;
• Inserire, aggiornare e cancellare righe in una tabella;
• Creare, modificare e eliminare oggetti;
• Controllare l’accesso ai database e ai loro aggetti;
• Garantire la consistenza e l’integrità dei dati.
7.1. DDL
Data Definition Language (DDL) include tutti i comandi usati per creare, modificare
e cancellare gli oggetti di un database: tabelle, indici, clusters, sequences, triggers,
procedures, funzioni e packages (inclusi i package body).
CREATE: per creare gli oggetti del database
ALTER: per modificare gli oggetti esistenti
DROP: per cancellare oggetti esistenti
7.3. TABELLE
Le tabelle sono l’unita base di memorizzazione dei dati in un database Oracle.
I dati vengono memorizzati in righe (record) e colonne (campi).
Una tabella viene definita con un nome tabella e un insieme di colonne per ognuna
delle quali si specifica il nome colonna, il datatype con la relativa dimensione.
Per ciascuna colonna della tabella possono essere eventualmente specificate delle
regole chiamate INTEGRITY CONTRAINTS (es. NOT NULL).
Quando viene creata una tabella Oracle alloca automaticamente un segmento in
una tablespace per contenere i dati futuri della tabella.
Manuale DB ORACLE - PLSQL
7.4. VISTE
Le VISTE sono una presentazione dei dati contenute in una o più tabelle o altre
viste.
A differenza delle tabelle le viste non richiedono lo spazio per la memorizzazione dei
dati ma solo quello per la loro definizione; infatti una vista viene definita da una
query che estrae i dati da tabelle.
Le viste vengono usate soprattutto per nascondere la complessità dei dati.
7.5. INDICI
Gli indici sono strutture opzionali associate con tabelle o cluster.
Possono essere creati su una o più colonne di una tabella per velocizzare
l’esecuzione di un comando SQL su quella tabella.
Per una tabella il numero di indici è illimitato ed ognuno di essi si riferisce ad
una diversa combinazione di colonna.
Gli indici sono logicamente e fisicamente indipendenti dai dati nella tabella
associata.
Oracle gestisce gli indici in modo trasparente all’utente.
Gli indici possono essere UNIQUE o NON UNIQUE.
7.6. SINONIMI
I sinonimi sono alias per tabelle, viste, sequence, packages etc …
Non richiedono memoria se non per la loro definizione.
Sono spesso usati per nascondere il nome e lo SCHEMA di un oggetto.
Possono essere pubblici o privati:
pubblico: è di proprietà del gruppo di utenti PUBLIC e quindi ogni utente
del DB può accedere ad esso
privato: appartiene allo SCHEMA di un utente specifico che ha il
controllo sulla sua accessibilità da parte di altri utenti.
7.8. CREATE
Per poter eseguire il comando di CREATE DATABASE l’utente deve avere il ruolo
SYSDBA.
CREATE DATABASE;
Crea un database usando i valori di default per tutti gli argomenti.
LOGFILE
GROUP 1 (‘nome completo del file’, …) SIZE 50K,
GROUP 2 (‘nome completo del file’, …) SIZE 50K
MAXLOGFILES 5
DATAFILE ‘nome completo del file’ SIZE 2M
MAXINSTANCES 2
CHARACTER SET US7ASCII
DATAFILE
‘nome completo del file’ AUTOEXTEND ON
‘nome completo del file’ AUTOEXTEND ON NEXT 10M MAXSIZE UNLIMITED;
RETURN datatype
IS blocco PL/SQL;
7.9. ALTER
7.10. DROP
Il comando DROP viene usato per rimuovere tabelle, indici, cluster, tablespaces,
sequence, stored objects, e sinonimi …
Ogni comando che libera spazio, tipo DROP, TRUNCATE o ALTER con la clausola
DEALLOCATE, può provocare frammentazioni nelle tablespace!
DROP TABLE
7.12. DATATYPES
Ogni colonna di una tabella e ogni argomento di una STORED PROCEDURE manipolata da
ORACLE ha un suo Datatype che definisce il dominio possibile.
7.13. INSERT
Per fare INSERT in una tavola l’utente deve avere il privilegio INSERT sulla tavola o il
privilegio INSERT ANY TABLE.
Manuale DB ORACLE - PLSQL
Esempi:
Supponiamo di avere la seguente tabella test1:
1) INSERT INTO test1 [(lista colonne)] SELECT campo1, campo2 FROM tabella2;
Inserisce nella tabella test1 tutte le righe della vista o tabella tabella2, utilizzando una
subquery (SELECT …FROM): poiché manca l’elenco delle colonne di test1 in cui vanno
inseriti i valori, la subquery deve restituire ordinatamente un valore per ogni colonna della
tabella. I valori restituiti dalla subquery devono essere dello stesso tipo (o tipo convertibile)
dei corrispondenti campi di test1.
Inserisce nella tabella test1 una sola riga: poiché manca l’elenco delle colonne di test1 in
cui vanno inseriti i valori la clausola VALUES deve contenere ordinatamente un valore per
ogni colonna della tabella.
Inserisce nella tabella test1 un record con uno solo dei due campi valorizzato.
Usa la clausola RETURNING per aggiornare le variabili t1 e t2 ai valori dei campi del record
inserito.
7.14. UPDATE
Per fare UPDATE in una tavola l’utente deve avere il privilegio UPDATE sulla tavola o il
privilegio UPDATE ANY TABLE.
Il comando UPDATE non può creare nuovi record ma solo aggiornare quelli
esistenti
Viene aggiornato il valore del campo nome_colonna solo per i record che soddisfano la
clausola WHERE (che può essere riferita a tutti i campi della tabella).
Viene aggiornato il valore del campo nome_colonna per tutti i record della tabella.
Viene aggiornato il valore del campo nome_colonna1 su tutte le righe di tabella1 utilizzando
una subquery.
Manuale DB ORACLE - PLSQL
Quando si usa la clausola RETURNING i valori dei campi aggiornati vengono memorizzati
nelle variabili specificate con INTO.
Esempio 2)
DELETE nome_tabella WHERE nome_colonna=‘valore’
Cancella le righe della tabella che soddisfano la WHERE
Esempio 3)
DELETE nome_tabella t_alias1 WHERE t_alias1.nome_colonna=(SELECT
t_alias2.nome_colonna FROM nome_tabella t_alias2 WHERE
t_alias2.nome_colonna2=‘valore’)
Cancella le righe di una tabella utilizzando una subquery sulla stessa tabella.
TRUNCATE
E’ un altro modo per cancellare il contenuto di una tabella.
TRUNCATE TABLE nome_tabella
7.16. SELECT
Per fare SELECT in una tavola l’utente deve avere il privilegio SELECT sulla tavola o il
privilegio SELECT ANY TABLE.
• INTERSECT= mostra solo le righe comuni alle due SELECT scartando i duplicati
• MINUS= restituisce tutte le righe distinte della prima SELECT che non appartengono
all’insieme delle righe restituite dalla seconda SELECT
NOTA
Le colonne delle due SELECT devono avere lo stesso nome;
Se i nomi non coincidono occorre utilizzare degli alias.
Manuale DB ORACLE - PLSQL
OUTER JOIN= usata quando per la tabella tab1 che partecipa al join mancano record
correlati in tab2 e si vuole che la SELECT restituisca comunque tutti i record di tab2.
tab1.col1(+)=tab2.col2
7.20. SUBQUERY
Una subquery può essere inclusa in una clausola FROM o in una
clausola WHERE
Esempi:
1) SELECT COUNT(*), a.owner FROM dba_objects a
WHERE 100<(SELECT COUNT(*) FROM dba_objects b
WHERE a.owner=b.owner)
GROUP BY a.owner
ROWID
Per ogni riga nel database la pseudo colonna ROWID restituisce l’indirizzo che la identifica
univocamente.
ROWNUM
Per ogni riga restituita da una query, la pseudo colonna ROWNUM indica l’ordine con cui
Oracle seleziona le righe da una o più tabelle.
7.22. TRANSAZIONE
Una transazione è una unità logica di lavoro che comprende una o più istruzioni SQL
eseguite da un singolo utente.
In base allo standard SQL a cui Oracle aderisce, una transazione comincia con il primo
comando SQL eseguibile che modifica i dati e finisce quando è esplicitamente COMMITTED o
ROLLED BACK da quell’utente.
Le transazioni offrono all’utente del database la possibilità di garantire variazioni
consistenti dei dati.
Una transazione dovrebbe consistere di tutte le istruzioni che costituiscono una
unità logica di lavoro in modo che i dati coinvolti siano in uno stato consistente
prima dell’inizio della transazione e dopo la sua fine.
Comandi per il controllo della transazione
Consentono all’utente di raggruppare le modifiche sui dati effettuate con comandi DML in
TRANSAZIONI logiche:
COMMIT
ROLLBACK
SAVEPOINT
SET TRANSACTION
COMMIT
• Il comando COMMIT rende permanenti le variazioni effettuate durante una
transazione;
• Le variazioni fatte dai comandi SQL di una transazione diventano visibili alle sessioni
di altri utenti solo dopo il COMMIT della transazione; eventuali accessi in lettura da
parte di altri utenti ai dati coinvolti da una diversa transazione sono sempre possibili
e visibili in maniera consistente; se una transazione contiene comandi DML che
richiedono LOCK sulle righe riservate da una diversa transazione, allora il comando
DML rimane in attesa fino a quando le righe non vengono rilasciate.
Un SAVEPOINT è un’etichetta che consente di dividere una transazione che contiene molti
comandi SQL in parti più piccole; usando i SAVEPOINT è possibile eseguire il ROLLBACK
dal punto corrente nella transazione ad uno specifico SAVEPOINT al suo interno; è
possibile avere più SAVEPOINT; ogni statement ha un SAVEPOINT implicito tale per cui
se la singola istruzione fallisce, viene eseguito un ROLLBACK che non annulla il resto della
transazione.
SAVEPOINT name;
-- istruzioni –
Manuale DB ORACLE - PLSQL
SET TRANSACTION
• Il comando SET TRANSACTION stabilisce che la transazione corrente è READ
ONLY o READ WRITE, oppure assegna la transazione corrente ad uno specifico
ROLLBACK SEGMENT (nel caso in cui si vogliono assegnare transazioni di diverso
tipo a ROLLBACK SEGMENT di diverse dimensioni –Oracle invece assegna la
transazione corrente al primo ROLLBACK SEGMENT libero-).
Esempio:
7.23. OPERATORI
(+) e (-)
operatori unari che indicano il segno algebrico di un numero
(||)
operatore binario di concatenazione di stringhe
NOT, AND, OR
operatori logici
(=)
operatore di uguaglianza
(!=), (^=),(<>)
operatori di disuguaglianza
EXISTS
TRUE se la subquery restituisce almeno una riga
IS [NOT] NULL
Verifica se un valore è nullo. Il valore NULL è indefinito e come tale non è uguale a nessun
altro valore, neanche a un altro NULL.
(>),(>=),(<),(<=)
operatori di confronto
IN,(=ANY),(=SOME)
Manuale DB ORACLE - PLSQL
ANY,SOME
operatori di confronto con almeno un valore di una lista (devono essere preceduti da un
operatore di uguaglianza, disuguaglianza o confronto)
ALL
operatore di confronto con tutti i valori di una lista (deve essere preceduto da un operatore
di uguaglianza, disuguaglianza o confronto)
FLOOR(n)
Arrotonda n all’intero inferiore.
ROUND(n [,m])
Restituisce n arrotondato a m cifre decimali (m positivo o senza segno); se m è negativo,
l’arrotondamento viene effettuato alla posizione m della parte intera, dove la posizione 0
indica l’unità (come quando m viene omesso).
TRUNC(n [,m])
Restituisce n troncato a m cifre decimali. Se m è omesso tronca a 0 cifre decimali.
CHR(n)
Restituisce il carattere che ha il codice ASCII = n nel set di caratteri corrente per il
database.
CONCAT(char1,char2)
Restituisce char1 concatenato con char2
INITCAP(char)
Restituisce char con la prima lettera di ogni parola in maiuscolo
LOWER(char)
Restituisce char con tutti i caratteri minuscoli
LPAD(char1,n[,char2])
LTRIM(char[,set])
Rimuove i caratteri set sulla parte sinistra di char; il set di default è un singolo spazio.
RPAD (char1,n[,char2])
RTRIM (char,[set])
Rimuove i caratteri set sulla parte destra di char; il set di default è un singolo spazio
SUBSTR(char,m[,n])
Restituisce la sottostringa di char che inizia dalla posizione m ed è lunga n caratteri. Se m è
0 viene trattato come 1. Se m è positivo Oracle conta dall’inizio della stringa, altrimenti
dalla fine.
UPPER(char)
Restituisce char con tutte le lettere in maiuscolo
ASCII(char)
Restituisce la rappresentazione decimale del primo carattere di char; se il character set del
database è 7-bit ASCII la funzione restituisce un valore ASCII, se il character set del
database è EBCDIC Code Page 500 la funzione restituisce un valore EBCDIC.
INSTR(char1, char2[,n][,m])
Restituisce la posizione di char2 in char1; n indica la posizione da cui iniziare a considerare
le occorrenze di char2, m indica l’occorrenza di char2 in char1 da individuare. Il valore di
default per n ed m è 1.
LENGTH(char)
Restituisce la lunghezza di char, ossia di quanti caratteri è composto. Se char è una stringa
nulla la funzione restituisce null.
LAST_DAY(d)
Restituisce la data dell’ultimo giorno del mese contenuto nella data d.
MONTHS_BETWEEN(d1,d2)
Restituisce il numero di mesi compresi tra le date d1 e d2
NEXT_DAY(d, char)
Restituisce la prima data successiva a d a cui corrisponde il giorno indicato con char.
SYSDATE
Restituisce la data e l’ora corrente; non richiede argomenti.
TO_CHAR(d[,fmt])
Converte d (di tipo dato DATE) ad un valore di tipo VARCHAR2 nel formato eventualmente
specificato da fmt.
TO_CHAR(n[,fmt])
Converte n (di tipo dato NUMBER) ad un valore di tipo VARCHAR2 nel formato
eventualmente specificato da fmt.
Manuale DB ORACLE - PLSQL
TO_DATE(char,[,fmt])
Converte char (di tipo CHAR o VARCHAR2) ad un valore di tipo DATE. Fmt è un formato
data che specifica quello di char, se omesso allora char deve essere nel formato data di
default.
TO_NUMBER(char[,fmt])
Converte char (di tipo CHAR o VARCHAR2) ad un tipo di dato NUMBER
GREATEST(expr1,expr2,...])
Restituisce l’elemento della lista di valore maggiore; tutti gli expr successivi al primo sono
implicitamente convertiti al tipo di dato del primo.
MOD(m,n)
Restituisce il resto di m diviso n. Restituisce m se n è zero
NVL(expr1, expr2)
Se expr1 è nullo restituisce expr2, altrimenti restituisce expr1
USER
Restituisce l’utente Oracle corrente
MAX([distinct, all]expr)
Restituisce il valore massimo di expr. E’ una funzione di aggregazione.
MIN([distinct, all]expr)
Restituisce il valore minimo di expr. E’ una funzione di aggregazione.
SUM([distinct][all] n)
Restituisce la somma dei valori di n. E’ una funzione di aggregazione.
7.25. NULLS
• Se una colonna in una riga non ha valore, è NULL.
• Colonne di qualsiasi datatype possono contenere nulls a meno che non abbiano
constraint NOT NULL o PRIMARY KEY.
• NULL non è equivalente al valore zero.
• Ogni espressione aritmetica che contiene anche un solo null vale sempre null.
• Tutti gli operatori, eccetto la concatenazione (||), e tutte le funzioni scalari, eccetto
NVL e TRANSLATE restituiscono null se uno degli operandi/argomenti è null.
• Per testare un null usare solo gli operatori IS NULL e IS NOT NULL.
• Un non null è uguale a nessun altro valore nemmeno ad un altro null!
Manuale DB ORACLE - PLSQL
8. SQL*Plus
Programma che consente di:
• Scrivere, memorizzare, richiamare ed eseguire comandi SQL e blocchi PL/SQL;
• Impostare l’aspetto del risultato di una query, memorizzarlo e stamparlo in forma di
report.
• Elencare le colonne di ciascuna tabella e le loro definizioni;
• Accedere ai dati di diversi database SQL e copiarli;
• Eseguire comandi SQL e blocchi PL/SQL parametrizzati e di ricevere input da parte
dell’utente;
• Eseguire le operazioni di amministrazione del database.
Per eseguire SQL*Plus si può usare il comando SQLPLUS al prompt del sistema operativo
(in ambiente windows si può eseguire il programma SQLPLUSW.EXE):
SQLPLUS [ [-S[ILENT]] [logon] [start] ]
dove:
logon richiede la seguente sintassi:
username[/password][@net_service_name] |/NOLOG
start permette di inserire il nome di un file di
comandi e gli argomenti; richiede la seguente
sintassi:
@file_name[.ext] [arg ...]
/NOLOG – non stabilisce nessuna connessione iniziale ad Oracle. Prima di scrivere qualsiasi
comando SQL si deve eseguire il comando CONNECT per stabilire una connessione valida.
arg. – lista dei parametri da passare al file di comandi. Se ci sono uno o più argomenti,
SQL*Plus sostituisce ordinatamente i valori nei paramenti (&1, &2, …) all’interno del file. Il
primo argomento sostituisce ogni ricorrenza di &1 e così via.
Piccola nota: a volte i TAB possono dare problemi. Quindi in caso di situazioni anomale
verificare tutti i TAB presenti nello script SQL.
Manuale DB ORACLE - PLSQL
http://orafaq.cs.rmit.edu.au/ - Australia
http://www.doag.org/orafaq/ - Germany
http://www.orafaq.com/ - USA (St. Louis)
http://www.orafaq.net/ - USA (Texas)
http://www.orafaq.org/ - USA (Michigan)
Make sure you understand the Netiquette Guidelines before posting your message. See
www.faqs.org/rfcs/rfc1855.html for details.
When you receive your answer, it is recommended that you post a summary to the list/newsgroup. It
might also be nice to notify the ORACLE FAQ maintainers of the answer so that
they can update the Oracle FAQ accordingly (keep in mind that they do not always have the time to
scan the lists/ newsgroups for new information).
Sure, we are always looking for new content and authors. Design
your FAQ page(s) and send it to us for inclusion into the Oracle
FAQ. Try to stick to the look, feel and style used in the rest
of the FAQ.
There was a Japanese translation of the Oracle FAQ some time ago. Maybe it is still out there
(difficult to tell). If you want to translate one of the FAQs, or know about some cool translation
techniques, please let us know.
Manuale DB ORACLE - PLSQL
All information on the Oracle FAQ is offered in good faith and in the
hope that it may be of use, but is not guaranteed to be correct, up
to date or suitable for any particular purpose. The author (and
contributors) accepts no liability in respect of this information or
its use.
10. ESERCIZI
CREARE SULLO SCHEMA CORSO (già definito su tablespace USERS) DUE TABELLE SIA_AZIENDE E
SIA_IMPIEGATI SAPENDO CHE FANNO PARTE DEL PROGETTO SISTEMA INFORMATIVO AZIENDALE
E CHE IN UN’AZIENDA POSSONO LAVORARE MOLTI IMPIEGATI E CHE UN IMPIEGATO DEVE
LAVORARE IN UNA SOLA AZIENDA.
LE COLONNE CHE DEFINISCONO LA TABELLA SIA_AZIENDE SONO:
PASSI:
DESC SIA_AZIENDE
declare
cursor c_impiegati is select * from impiegati
FOR UPDATE OF quantomiseicostato;
stipendio number;
begin
for c_impiegati in imp loop
...
contingenza := ...;
extra := ...;
stipendio := imp.base + contingenza + extra;
insert into stipendi...
...
update impiegati set quantomiseicostato =
quantomiseicostato+stipendio
where CURRENT OF c_impiegati;
end loop;
...
EXCEPTION
WHEN no_data_found THEN
...
WHEN licenziato THEN
...
END;
Manuale DB ORACLE - PLSQL
185326 _______________________
10,58 _______________________
ALFASUD _______________________
26/10/1983 _______________________
k _______________________
1,3145E+12 _______________________
_______________________
Indicare il valore massimo che potrò registrare in una colonna con tale Datatype:
NUMBER(6) _______________________
CHAR(1) _______________________
VARCHAR2(1)_______________________
NUMBER(3,2) _______________________
Manuale DB ORACLE - PLSQL
NUMBER(4,2) _______________________
VARCHAR2(4)_______________________
NUMBER(1) _______________________
DATE _______________________
Manuale DB ORACLE - PLSQL
Quale istruzione risulta più pericolosa: DELETE, DROP o TRUNCATE? (sottolinea la risposta)
a) WHERE
b) FROM
c) column-list o lista delle colonne
d) tavola
e) condizione_2
f) AND/OR
g) ;
h) AND/OR
i) HAVING
j) condizione_1
k) ORDER BY colonna_x
l) GROUP BY colonna_y
m) condizione_3
n) DISTINCT
o) SELECT
__-__-__-__-__-__-__-__-__-__-__-__-__-__-__-
__-__-__-__-__-__-__-__-__-__-__-__-__-__-__-
a) VALUES
b) (val1, val2)
c) (col1, col2)
d) INTO
e) ;
f) INSERT
g) tavola
__-__-__-__-__-__-__-__-__-__-__-__-__-__-__-
h) SELECT
Manuale DB ORACLE - PLSQL
i) FROM...
j) val1, val2
k) (col1, col2)
l) INTO
m) ;
n) INSERT
o) tavola
__-__-__-__-__-__-__-__-__-__-__-__-__-__-__-
X uguale a Y ___________________
X maggiore di Y ___________________
X diverso da Y ___________________
x > 10 or y < 5 V F
h) 4 al cubo ________________
scrivere una select che fornisca contemporaneamente tutti i suddetti valori, ciascuno sotto un alias
che corrisponda al carattere di punto elenco (a-b-c-...)
Manuale DB ORACLE - PLSQL
a) 15 C V
b) ‘ciao’ C V
c) x12 C V
d) ‘x12’ C V
e) ‘15’ C V
f) N C V
funzioni di gruppo
________________________
________________________
________________________
________________________
________________________
________________________
________________________
12. DOCENTE
ancora da consultare:
www.techtutorials.com/Programming/SQL/ (SQL tutorial)
www.sqlteam.com/ (SQL FAQ's, forum, resources)
www.beginners.co.uk/view?cobrand=beginners&i=21 (tutorials, references)
www.i-converge.com/tutorial.html?^&category=17&cobrand=beginners (online course)
www.tutorials.it/search.php?categoria=sql (SQL tutorial e articoli - italiano)
www.sqlWire.com
www.dbaSupport.com
www.sqlConnection.com
lock impliciti
lock espliciti
mancano ANY e ALL per le subquery
connect internal finisce con 8.2
era un modo per entrare con privilegi DBA
rimane
CONNECT / AS SYSDBA
CONNECT leo/leo AS SYSDBA
idem... AS SYSOPER
Sql*Plus ora può fare reportistica HTML per consultare il risultato con web browser
reports on demands with CGI scripts
parlare sempre di AFIEDT.BUF (advanced friendly interface editor.buffer)
SQL*PLUS rimane l’unico tool di tipo ‘command line’ con Oracle DB
ora ci sarà Internet Enabled sql*plus
prima si doveva usare il package DMBS_SQL, che però richiedeva molto codice e
tecnologia di duplicazione dei dati
adesso c’è un linguaggio intuitivo
molto meno codice
molto più veloce, dal 30% fino al 400%
alcuni modi per stabilire i diritti dell’invocante piuttosto che quelli del proprietario di
istruzioni centralizzate con AUTHID CURRENT_USER...
VARRAY type
UROWID type
new date e time type
TRIM ??
CAST ??
quanto sopra non viene spiegato...
il terzo doc.PDF andrebbe conservato per scopiazzare le slide dei formati + esempi
Manuale DB ORACLE - PLSQL
The cost-based approach generally chooses an execution plan that is as good as or better than the
plan chosen by the rule-based approach, especially for large queries with multiple joins or multiple
indexes. The cost-based approach also improves productivity by eliminating the need for you to tune
your SQL statements yourself. Finally, many Oracle performance features are available only through
the cost-based approach.
Cost based optimization must be used to achieve efficient star query performance. Similarly, it must
be used with hash joins and histograms. Cost-based optimization is always used with parallel query
and with partition views. You must therefore perform ANALYZE at the partition level with partition
views.
To enable cost-based optimization for your session only, issue an ALTER SESSION statement
with an OPTIMIZER_GOAL option value of ALL_ROWS or FIRST_ROWS.
To enable cost-based optimization for an individual SQL statement, use any hint other than
RULE.
The plans generated by the cost-based optimizer depend on the sizes of the tables. When using the
cost-based optimizer with a small amount of data to prototype an application, do not assume that
the plan chosen for the full database will be the same as that chosen for the prototype.
The SIZE keyword states the maximum number of buckets for the histogram. You would create a
histogram on the SAL column if there were an unusual number of employees with the same salary
and few employees with other salaries.
If the number of frequently occurring distinct values in a column is relatively small, then it is useful
to set the number of buckets to be greater than the number of frequently occurring distinct values.
USER_HISTOGRAMS
ALL_HISTOGRAMS
DBA_HISTOGRAMS
USER_TAB_COLUMNS
ALL_TAB_COLUMNS
DBA_TAB_COLUMNS
Use estimation, rather than computation, unless you think you need exact values:
Computation always provides exact values, but can take longer than estimation. The time
necessary to compute statistics for a table is approximately the time required to perform a full
table scan and a sort of the rows of the table.
Estimation is often much faster than computation, especially for large tables, because
estimation never scans the entire table.
To perform a computation, Oracle requires enough space to perform a scan and sort of the table. If
there is not enough space in memory, temporary space may be required. For estimations, Oracle
requires enough space to perform a scan and sort of all of the rows in the requested sample of the
table.
Because of the time and space required for the computation of table statistics, it is usually best to
perform an estimation with a 20% sample size for tables and clusters. For indexes, computation does
not take up as much time or space, so it is best to perform a computation.
When you generate statistics for a table, column, or index, if the data dictionary already contains
statistics for the analyzed object, Oracle updates the existing statistics with the new ones. Oracle
invalidates any currently parsed SQL statements that access any of the analyzed objects. When such
a statement is next executed, the optimizer automatically chooses a new execution plan based on
the new statistics. Distributed statements issued on remote databases that access the analyzed
objects use the new statistics when they are next parsed.
Some statistics are always computed, regardless of whether you specify computation or estimation.
If you choose estimation and the time saved by estimating a statistic is negligible, Oracle computes
the statistic.
Example: This example generates statistics for the EMP table and its indexes:
Manuale DB ORACLE - PLSQL
For example, consider a join statement that can be executed with either a nested loops operation or
a sort-merge operation. The sort-merge operation may return the entire query result faster, while
the nested loops operation may return the first row faster. If the goal is best throughput, the
optimizer is more likely to choose a sort-merge join. If the goal is best response time, the optimizer
is more likely to choose a nested loops join.
Choose a goal for the optimizer based on the needs of your application:
For applications performed in batch, such as Oracle Reports applications, optimize for best
throughput. Throughput is usually more important in batch applications because the user
initiating the application is only concerned with the time necessary for the application to
complete. Response time is less important because the user does not examine the results of
individual statements while the application is running.
For interactive applications, such as Oracle Forms applications or SQL*Plus queries, optimize
for best response time. Response time is usually important in interactive applications because
the interactive user is waiting to see the first row accessed by the statement.
For queries that use ROWNUM to limit the number of rows, optimize for best response time.
Because of the semantics of ROWNUM queries, optimizing for response time provides the best
results.
By default, the cost-based approach optimizes for best throughput. You can change the goal of the
cost-based approach in these ways:
To change the goal of the cost-based approach for all SQL statements in your session, issue
an ALTER SESSION statement with the OPTIMIZER_GOAL option.
To specify the goal of the cost-based approach for an individual SQL statement, use the
ALL_ROWS or FIRST_ROWS hint.
Example: This statement changes the goal of the cost-based approach for your session to best
response time:
ALTER SESSION SET OPTIMIZER_GOAL = FIRST_ROWS;
Note that the following sort parameters can now be modified using ALTER SESSION SET ... or ALTER
SYSTEM SET ... DEFERRED:
SORT_AREA_SIZE
SORT_AREA_RETAINED_SIZE
SORT_DIRECT_WRITES
SORT_WRITE_BUFFERS
SORT_WRITE_BUFFER_SIZE
SORT_READ_FAC
See Also: Oracle7 Server Reference for complete information about each parameter.
Analyzing a table uses more system resources than analyzing an index. It may be helpful to analyze
the indexes for a table separately, with a higher sampling rate.
Use of access path and join method hints causes the cost-based optimization to be invoked. Since
cost-based optimization is dependent on statistics, it is important to analyze all tables referenced in a
query which has hints, even though rule-based optimization may have been selected as the system
default.
If you neither collect statistics nor add hints to your SQL statements, your statements will use rule-
based optimization. However, you should eventually migrate your existing applications to use the
cost-based approach, because the rule-based approach will not be available in future versions of
Oracle.
Manuale DB ORACLE - PLSQL
You can enable cost-based optimization on a trial basis simply by collecting statistics. You can then
return to rule-based optimization by deleting them or by setting either the value of the
OPTIMIZER_MODE initialization parameter or the OPTIMIZER_GOAL parameter of the ALTER
SESSION command to RULE. You can also use this value if you want to collect and examine statistics
for your data without using the cost-based approach.
15.Introduction to Hints
As an application designer, you may know information about your data that the optimizer cannot. For
example, you may know that a certain index is more selective for certain queries than the optimizer
can determine. Based on this information, you may be able to choose a more efficient execution plan
than the optimizer can. In such a case, you can use hints to force the optimizer to use your chosen
execution plan.
Hints are suggestions that you give the optimizer for optimizing a SQL statement. Hints allow you to
make decisions usually made by the optimizer. You can use hints to specify
For example, a compound query consisting of two component queries combined by the UNION
operator has two statement blocks, one for each component query. For this reason, hints in this first
component query apply only to its optimization, not to the optimization of the second component
query.
You can send hints for a SQL statement to the optimizer by enclosing them in a Comment within the
statement.
See Also: For more information on Comments, see Chapter 2, "Elements of SQL", of the Oracle7
Server SQL Reference.
A statement block can have only one Comment containing hints. This Comment can only follow the
SELECT, UPDATE, or DELETE keyword. The syntax diagrams show the syntax for hints contained in
both styles of Comments that Oracle supports within a statement block.
where:
DELETE SELECT Is a DELETE, SELECT, or UPDATE keyword that begins a statement block. Comments
UPDATE containing hints can only appear after these keywords.
Is a plus sign that causes Oracle to interpret the Comment as a list of hints. The plus
+
sign must follow immediately after the Comment delimiter (no space is permitted).
Manuale DB ORACLE - PLSQL
Is one of the hints discussed in this section. If the Comment contains multiple hints,
hint
each pair of hints must be separated by at least one space.
text Is other Commenting text that can be interspersed with the hints.
If you specify hints incorrectly, Oracle ignores them but does not return an error:
Oracle ignores hints if the Comment containing them does not follow a DELETE, SELECT, or
UPDATE keyword.
Oracle ignores hints containing syntax errors, but considers other correctly specified hints
within the same Comment.
Oracle ignores combinations of conflicting hints, but considers other hints within the same
Comment.
Oracle also ignores hints in all SQL statements in environments which use PL/SQL Version 1, such as
SQL*Forms Version 3 triggers.
The optimizer only recognizes hints when using the cost-based approach. If you include any hint
(except the RULE hint) in a statement block, the optimizer automatically uses the cost-based
approach.
If a SQL statement contains a hint that specifies an optimization approach and goal, the optimizer
uses the specified approach regardless of the presence or absence of statistics, the value of the
OPTIMIZER_MODE initialization parameter, and the OPTIMIZER_GOAL parameter of the ALTER
SESSION command.
Note: The optimizer goal applies only to queries submitted directly. Use hints to determine the
access path for any SQL statements submitted from within PL/SQL. The ALTER SESSION
OPTIMIZER_GOAL statement does not affect SQL that is run from within PL/SQL.
17.1. ALL_ROWS
The ALL_ROWS hint explicitly chooses the cost-based approach to optimize a statement block with a
goal of best throughput (that is, minimum total resource consumption). For example, the optimizer
uses the cost-based approach to optimize this statement for best throughput:
SELECT /*+ ALL_ROWS */ empno, ename, sal, job
FROM emp
WHERE empno = 7566;
17.2. FIRST_ROWS
The FIRST_ROWS hint explicitly chooses the cost-based approach to optimize a statement block with
a goal of best response time (minimum resource usage to return first row).
If an index scan is available, the optimizer may choose it over a full table scan.
If an index scan is available, the optimizer may choose a nested loops join over a sort-merge
join whenever the associated table is the potential inner table of the nested loops.
Manuale DB ORACLE - PLSQL
If an index scan is made available by an ORDER BY clause, the optimizer may choose it to
avoid a sort operation.
For example, the optimizer uses the cost-based approach to optimize this statement for best
response time:
SELECT /*+ FIRST_ROWS */ empno, ename, sal, job
FROM emp
WHERE empno = 7566;
The optimizer ignores this hint in DELETE and UPDATE statement blocks and in SELECT statement
blocks that contain any of the following syntax:
These statements cannot be optimized for best response time because Oracle must retrieve all rows
accessed by the statement before returning the first row. If you specify this hint in any of these
statements, the optimizer uses the cost-based approach and optimizes for best throughput.
If you specify either the ALL_ROWS or FIRST_ROWS hint in a SQL statement and the data dictionary
contains no statistics about any of the tables accessed by the statement, the optimizer uses default
statistical values (such as allocated storage for such tables) to estimate the missing statistics and
subsequently to choose an execution plan. Since these estimates may not be as accurate as those
generated by the ANALYZE command, you should use the ANALYZE command to generate statistics
for all tables accessed by statements that use cost-based optimization. If you specify hints for access
paths or join operations along with either the ALL_ROWS or FIRST_ROWS hint, the optimizer gives
precedence to the access paths and join operations specified by the hints.
17.3. CHOOSE
The CHOOSE hint causes the optimizer to choose between the rule-based approach and the cost-
based approach for a SQL statement based on the presence of statistics for the tables accessed by
the statement. If the data dictionary contains statistics for at least one of these tables, the optimizer
uses the cost-based approach and optimizes with the goal of best throughput. If the data dictionary
contains no statistics for any of these tables, the optimizer uses the rule-based approach.
SELECT /*+ CHOOSE */
empno, ename, sal, job
FROM emp
WHERE empno = 7566;
17.4. RULE
The RULE hint explicitly chooses rule-based optimization for a statement block. This hint also causes
the optimizer to ignore any other hints specified for the statement block. For example, the optimizer
uses the rule-based approach for this statement:
SELECT --+ RULE
empno, ename, sal, job
FROM emp
WHERE empno = 7566;
The RULE hint, along with the rule-based approach, will not be available in future versions of Oracle.
HASH_AJ
INDEX
INDEX_ASC
INDEX_COMBINE
INDEX_DESC
INDEX_FFS
MERGE_AJ
AND_EQUAL
USE_CONCAT
Specifying one of these hints causes the optimizer to choose the specified access path only if the
access path is available based on the existence of an index or cluster and the syntactic constructs of
the SQL statement. If a hint specifies an unavailable access path, the optimizer ignores it.
You must specify the table to be accessed exactly as it appears in the statement. If the statement
uses an alias for the table, you must use the alias, rather than the table name, in the hint. The table
name within the hint should not include the schema name, if the schema name is present in the
statement.
18.1. FULL
The FULL hint explicitly chooses a full table scan for the specified table. The syntax of the FULL hint
is
FULL(table)
where table specifies the name or alias of the table on which the full table scan is to be performed.
For example, Oracle performs a full table scan on the ACCOUNTS table to execute this statement,
even if there is an index on the ACCNO column that is made available by the condition in the WHERE
clause:
SELECT /*+ FULL(a) Don't use the index on ACCNO */ accno, bal
FROM accounts a
WHERE accno = 7086854;
Note: Because the ACCOUNTS table has an alias, A, the hint must refer to the table by its alias, rather than by its
name. Also, do not specify schema names in the hint, even if they are specified in the FROM clause.
The fast full scan was an operation that appeared in Oracle 7.3, although in that version of Oracle there was a time
when it had to be invoked explicitly by the hing /*+ index_ffs(alias index) */.
Under this operation, the index would not be treated like an index, it would be treated as if it were a narrow table,
holding just the columns defined as part of the index. Because of this, Oracle is able to read the index segment
using multiblock reads (discarding branch blocks as it goes), even using parallel query methods to read the
segment in the shortest possible time. Of course, the data coming out of an index fast full scan will not be sorted.
The full scan, however, simply means that Oracle walks the index from end to end, following leaf blocks in the right
order. This can be quite slow, as Oracle can only use single block reads to do this (although in fact 8.1.5ish
introduced the _non_contiguous_multiblock_read, and various readahead strategies). However the results do come
out in index order without the need for an sort. You might notice that Oracle tends to choose this option when there
is an index that happens to suit the order by clause of a query, even if it doesn't suit the where clause of the query
- this may also result in a SORT ORDER BY (NO SORT) line appearing in your execution plan.
18.2. ROWID
The ROWID hint explicitly chooses a table scan by ROWID for the specified table. The syntax of the
ROWID hint is
ROWID(table)
where table specifies the name or alias of the table on which the table access by ROWID is to be
performed.
Manuale DB ORACLE - PLSQL
18.3. CLUSTER
The CLUSTER hint explicitly chooses a cluster scan to access the specified table. The syntax of the
CLUSTER hint is
CLUSTER(table)
where table specifies the name or alias of the table to be accessed by a cluster scan.
18.4. HASH
The HASH hint explicitly chooses a hash scan to access the specified table. The syntax of the HASH
hint is
HASH(table)
where table specifies the name or alias of the table to be accessed by a hash scan.
18.5. HASH_AJ
The HASH_AJ hint transforms a NOT IN subquery into a hash anti-join to access the specified table.
The syntax of the HASH_AJ hint is
HASH_AJ(table)
18.6. INDEX
The INDEX hint explicitly chooses an index scan for the specified table. The syntax of the INDEX hint
is
where:
table Specifies the name or alias of the table associated with the index to be scanned.
index Specifies an index on which an index scan is to be performed.
If this hint specifies a single available index, the optimizer performs a scan on this index. The
optimizer does not consider a full table scan or a scan on another index on the table.
If this hint specifies a list of available indexes, the optimizer considers the cost of a scan on
each index in the list and then performs the index scan with the lowest cost. The optimizer
may also choose to scan multiple indexes from this list and merge the results, if such an
access path has the lowest cost. The optimizer does not consider a full table scan or a scan on
an index not listed in the hint.
If this hint specifies no indexes, the optimizer considers the cost of a scan on each available
index on the table and then performs the index scan with the lowest cost. The optimizer may
also choose to scan multiple indexes and merge the results, if such an access path has the
lowest cost. The optimizer does not consider a full table scan.
For example, consider this query, which selects the name, height, and weight of all male patients in
a hospital:
Manuale DB ORACLE - PLSQL
Assume that there is an index on the SEX column and that this column contains the values M and F.
If there are equal numbers of male and female patients in the hospital, the query returns a relatively
large percentage of the table's rows and a full table scan is likely to be faster than an index scan.
However, if a very small percentage of the hospital's patients are male, the query returns a relatively
small percentage of the table's rows and an index scan is likely to be faster than a full table scan.
The number of occurrences of each distinct column value is not available to the optimizer. The cost-
based approach assumes that each value has an equal probability of appearing in each row. For a
column having only two distinct values, the optimizer assumes each value appears in 50% of the
rows, so the cost-based approach is likely to choose a full table scan rather than an index scan.
If you know that the value in the WHERE clause of your query appears in a very small percentage of
the rows, you can use the INDEX hint to force the optimizer to choose an index scan. In this
statement, the INDEX hint explicitly chooses an index scan on the SEX_INDEX, the index on the SEX
column:
18.7. INDEX_ASC
The INDEX_ASC hint explicitly chooses an index scan for the specified table. If the statement uses an
index range scan, Oracle scans the index entries in ascending order of their indexed values. The
Because Oracle's default behavior for a range scan is to scan index entries in ascending order of their
indexed values, this hint does not currently specify anything more than the INDEX hint. However,
since Oracle Corporation does not guarantee that the default behavior for an index range scan will
remain the same in future versions of Oracle, you may want to use the INDEX_ASC hint to specify
ascending range scans explicitly, should the default behavior change.
18.8. INDEX_COMBINE
If no indexes are given as arguments for the INDEX_COMBINE hint, the optimizer will use on the
table whatever boolean combination of bitmap indexes has the best cost estimate. If certain indexes
are given as arguments, the optimizer will try to use some boolean combination of those particular
18.9. INDEX_DESC
The INDEX_DESC hint explicitly chooses an index scan for the specified table. If the statement uses
an index range scan, Oracle scans the index entries in descending order of their indexed values.
Each parameter serves the same purpose as in the INDEX hint. This hint has no effect on SQL
statements that access more than one table. Such statements always perform range scans in
ascending order of the indexed values. For example, consider this table, which contains the
temperature readings of a tank of water holding marine life:
Manuale DB ORACLE - PLSQL
Each of the table's rows stores a time and the temperature measured at that time. A UNIQUE
constraint on the TIME column ensures that the table does not contain more than one reading for the
same time.
Oracle enforces this constraint with an index on the TIME column. Consider this complex query,
which selects the most recent temperature reading taken as of a particular time T. The subquery
returns either T or the latest time before T at which a temperature reading was taken. The parent
query then finds the temperature taken at that time:
SELECT temperature
FROM tank_readings
WHERE time = (SELECT MAX(time)
FROM tank_readings
WHERE time <= TO_DATE(:t) );
The execution plan for this statement looks like the following figure:
In Step 4, Oracle scans the TIME values in the index in ascending order beginning with the smallest.
Oracle stops scanning at the first TIME value greater than T and then returns all the values less than
Manuale DB ORACLE - PLSQL
or equal to T to Step 3. Note that Step 3 needs only the greatest of these values. Using the
INDEX_DESC hint, you can write an equivalent query that reads only one TIME value from the index:
SELECT /*+ INDEX_DESC(tank_readings un_time) */ temperature
FROM tank_readings
WHERE time <= TO_DATE(:t)
AND ROWNUM = 1
ORDER BY time DESC;
The execution plan for this query looks like the following figure:
Because of the INDEX_DESC hint, Step 3 scans the TIME values in the index in descending order
beginning at T. The first TIME value scanned is either T (if the temperature was taken at T) or the
greatest TIME value less than T. Since Step 1 requests only one row, Step 3 scans no more index
entries after the first.Since the default behavior is an ascending index scan, issuing this query
without the INDEX_DESC hint would cause Oracle to begin scanning at the earliest time in the table,
rather than at the latest time less than or equal to T. Step 1 would then return the temperature at
the earliest time. You must use this hint to make this query return the same temperature as the
complex query described earlier in this section.
18.10. INDEX_FFS
This hint causes a fast full index scan to be performed rather than a full table scan. The syntax of
INDEX_FFS is
18.11. MERGE_AJ
The MERGE_AJ hint transforms a NOT IN subquery into a merge anti-join to access the specified
table. The syntax of the MERGE_AJ hint is
MERGE_AJ(table)
18.12. AND_EQUAL
The AND_EQUAL hint explicitly chooses an execution plan that uses an access path that merges the
scans on several single-column indexes. The syntax of the AND_EQUAL hint is:
where:
table Specifies the name or alias of the table associated with the indexes to be merged.
Specifies an index on which an index scan is to be performed. You must specify at least two
index
indexes. You cannot specify more than five.
18.13. USE_CONCAT
The USE_CONCAT hint forces combined OR conditions in the WHERE clause of a query to be
transformed into a compound query using the UNION ALL set operator. Normally, this transformation
occurs only if the cost of the query using the concatenations is cheaper than the cost without them.
19.1. ORDERED
The ORDERED hint causes Oracle to join tables in the order in which they appear in the FROM clause.
For example, this statement joins table TAB1 to table TAB2 and then joins the result to table TAB3:
SELECT /*+ ORDERED */ tab1.col1, tab2.col2, tab3.col3
FROM tab1, tab2, tab3
WHERE tab1.col1 = tab2.col1
AND tab2.col1 = tab3.col1;
If you omit the ORDERED hint from a SQL statement performing a join, the optimizer chooses the
order in which to join the tables.
You may want to use the ORDERED hint to specify a join order if you know something about the
number of rows selected from each table that the optimizer does not. Such information would allow
you to choose an inner and outer table better than the optimizer could.
19.2. STAR
The STAR hint forces the large table to be joined last using a nested loops join on the index. The
optimizer will consider different permutations of the small tables.
Usually, if you analyze the tables the optimizer will choose an efficient star plan. You can also use
hints to improve the plan. The most precise method is to order the tables in the FROM clause in the
order of the keys in the index, with the large table last. Then use the following hints:
A more general method is to use the STAR hint /*+ STAR */.
You must specify a table to be joined exactly as it appears in the statement. If the statement uses an
alias for the table, you must use the alias rather than the table name in the hint. The table name
within the hint should not include the schema name, if the schema name is present in the statement.
The USE_NL and USE_MERGE hints must be used with the ORDERED hint. Oracle uses these hints
when the referenced table is forced to be the inner table of a join, and they are ignored if the
referenced table is the outer table.
20.1. USE_NL
The USE_NL hint causes Oracle to join each specified table to another row source with a nested loops
join using the specified table as the inner table. The syntax of the USE_NL hint is
where table is the name or alias of a table to be used as the inner table of a nested loops join.
For example, consider this statement, which joins the ACCOUNTS and CUSTOMERS tables. Assume
that these tables are not stored together in a cluster:
SELECT accounts.balance,
customers.last_name,
customers.first_name
FROM accounts, customers
WHERE accounts.custno = customers.custno;
Since the default goal of the cost-based approach is best throughput, the optimizer will choose either
a nested loops operation or a sort-merge operation to join these tables, depending on which is likely
to return all the rows selected by the query more quickly.
However, you may want to optimize the statement for best response time, or the minimal elapsed
time necessary to return the first row selected by the query, rather than best throughput. If so, you
can force the optimizer to choose a nested loops join by using the USE_NL hint. In this statement,
the USE_NL hint explicitly chooses a nested loops join with the CUSTOMERS table as the inner table:
In many cases, a nested loops join returns the first row faster than a sort-merge join. A nested loops
join can return the first row after reading the first selected row from one table and the first matching
row from the other and combining them, while a sort-merge join cannot return the first row until
after reading and sorting all selected rows of both tables and then combining the first rows of each
sorted row source.
20.2. USE_MERGE
The USE_MERGE hint causes Oracle to join each specified table with another row source with a sort-
merge join. The syntax of the USE_MERGE hint is
where table is a table to be joined to the row source resulting from joining the previous tables in the
join order using a sort-merge join.
20.3. NO_MERGE
The NO_MERGE hint causes Oracle not to merge mergeable views. The syntax of the NO_MERGE hint
is:
Manuale DB ORACLE - PLSQL
This hint is most often used to reduce the number of possible permutations for a query and make
optimization faster. This hint has no arguments. For example,
SELECT *
FROM t1, (SELECT /*+ NO_MERGE */
*
FROM t2)v ...
20.4. USE_HASH
The USE_HASH hint causes Oracle to join each specified table with another row source with a hash
join. The syntax of the USE_HASH hint is
where table is a table to be joined to the row source resulting from joining the previous tables in the
join order using a hash join.
21.1. PARALLEL
The PARALLEL hint allows you to specify the desired number of concurrent query servers that can be
The PARALLEL hint must use the table alias if an alias is specified in the query. The PARALLEL hint
can then take two values separated by commas after the table name. The first value specifies the
degree of parallelism for the given table, the second value specifies how the table is to be split
among the instances of a parallel server. Specifying DEFAULT or no value signifies the query
coordinator should examine the settings of the initialization parameters (described in a later section)
to determine the default degree of parallelism.
In the following example, the PARALLEL hint overrides the degree of parallelism specified in the EMP
table definition:
In the next example, the PARALLEL hint overrides the degree of parallelism specified in the EMP table
definition and tells the optimizer to use the default degree of parallelism determined by the
initialization parameters. This hint also specifies that the table should be split among all of the
available instances, with the default degree of parallelism on each instance.
21.2. NOPARALLEL
The NOPARALLEL hint allows you to disable parallel scanning of a table, even if the table was created
with a PARALLEL clause. The following example illustrates the NOPARALLEL hint:
SELECT /*+ NOPARALLEL(scott_emp) */
ename
FROM scott.emp scott_emp;
Manuale DB ORACLE - PLSQL
22.Additional Hints
Three additional hints are included in this section:
CACHE
NOCACHE
PUSH_SUBQ
22.1. CACHE
The CACHE hint specifies that the blocks retrieved for the table in the hint are placed at the most
recently used end of the LRU list in the buffer cache when a full table scan is performed. This option
is useful for small lookup tables. In the following example, the CACHE hint overrides the table's
default caching specification:
SELECT /*+ FULL (scott_emp) CACHE(scott_emp) */
ename
FROM scott.emp scott_emp;
22.2. NOCACHE
The NOCACHE hint specifies that the blocks retrieved for this table are placed at the least recently
used end of the LRU list in the buffer cache when a full table scan is performed. This is the normal
behavior of blocks in the buffer cache. The following example illustrates the NOCACHE hint:
SELECT /*+ FULL(scott_emp) NOCACHE(scott_emp) */
ename
FROM scott.emp scott_emp;
22.3. PUSH_SUBQ
The PUSH_SUBQ hint causes nonmerged subqueries to be evaluated at the earliest possible place in
the execution plan. Normally, subqueries that are not merged are executed as the last step in the
execution plan. If the subquery is relatively inexpensive and reduces the number of rows
significantly, it will improve performance to evaluate the subquery earlier.
The hint will have no effect if the subquery is applied to a remote table or one that is joined using a
merge join.
This example shows the execution plans for two SQL statements that perform the same function.
Both statements return all the departments in the DEPT table that have no employees in the EMP
table. Each statement searches the EMP table with a subquery. Assume there is an index,
DEPTNO_INDEX, on the DEPTNO column of the EMP table.
However, this SQL statement selects the same rows by accessing the index:
If you have statements in your applications that use the NOT IN operator, as the first query in this
example does, you should consider rewriting them so that they use the NOT EXISTS operator. This
would allow such statements to use an index, if one exists.
2c) nelle insert dichiarare SEMPRE esplicitamente le colonne: INSERT INTO TABELLA (COLONNA1,
COLONNA2, ECC...) VALUES(1,2,ECC...)
2d) nelle CREATE VIEW scrivere SEMPRE ESPLICITAMENTE LE COLONNE: CREATE VIEW VISTA
(COLONNA1, COLONNA2, ECC...)
In merito a %TYPE, l'utilizzo di questa sintassi DEVE essere incentivato, infatti se il formato di una
colonna cambia, i programmi si riallineano automaticamente, basta ricompilarli, oltretutto la cosa
viene segnalata esplicitamente con l'errore di cui sopra, se non si facesse così, invece, avremmo un
generico "numeric or value error", con grandi malditesta per caprine la causa e sopratutto la
necessità di modificare il codice per riallinearlo al nuovo formato, con un potenziale impatto in
cascata.
24.2. EX3
SELECT s.ROWID,
s.ser_ute,
s.ser_puntopresa,
s.ser_codsersub,
l.let_matricola,
l.let_cod_fab
FROM serviz s, lettur l
WHERE s.ser_ute = 'BO'
AND l.let_ute = s.ser_ute
AND l.let_puntopresa = s.ser_puntopresa
AND s.ser_stato_cont = '5'
AND s.ser_codsersub IS NULL
AND l.let_dat_lettur =
(SELECT MAX (l2.let_dat_lettur)
FROM lettur l2
WHERE l2.let_ute = s.ser_ute
AND l2.let_puntopresa = s.ser_puntopresa
AND l2.let_tip_lettur != 'M')
AND 0 <
(SELECT COUNT (0)
FROM serviz s1, lettur l1
WHERE s1.ser_ute = 'BO'
AND s1.ser_statoserv = '1'
AND s1.ser_datainifor >= s.ser_datainifor
AND l1.let_ute = s1.ser_ute
AND l1.let_puntopresa = s1.ser_puntopresa
AND l.let_matricola = l1.let_matricola
AND l.let_cod_fab = l1.let_cod_fab
AND l1.let_dat_lettur > l.let_dat_lettur)
Di fronte ad una query del genere la prima cosa da fare è l’explan Plan (CTRL+E):
Bisogna verificare se gli indici che vengono usati automaticamente sono i più adeguati cioè quelli che
hanno una maggiore incidenza a livello di maggiore selezione.
L’indice I2 non è adeguato perché si basa su statoser e ute mentre sarebbe più adeguato usare I1
basato su puntopresa e ute. Si può forzare con: /* index(s1 I1_serviz)*/ però a causa del AND
s1.ser_statoserv = '1' c’è un ulteriore forzamento di I2 e non basta /* index(s1 I1_serviz)*/ . Bisogna usare lo
stratagemma di inserire una funzione superflua che permette di non forzare quell’indice a causa della
join che sembrerebbe più restrittiva perché agganciata ad una costante ('1') e cioè: AND
LTRIM(s1.ser_statoserv) = '1'
Inoltre si mettono in ordine prima i campi si I1 e poi quelli di s1 come stanno nel FROM.
Cercare più volte a cambiare l’ordine sia della join e sia dell’uguaglianza e verificando L’Explain Plan
ogni volta.
A livello pratico si è passati da un tempo di oltre 1 ora a circa 30 secondi!
Ottimizzata:
Manuale DB ORACLE - PLSQL
SELECT s.ROWID,
s.ser_ute,
s.ser_puntopresa,
s.ser_codsersub,
l.let_matricola,
l.let_cod_fab
FROM serviz s, lettur l
WHERE s.ser_ute = 'BO'
AND l.let_ute = s.ser_ute
AND l.let_puntopresa = s.ser_puntopresa --AND l.let_puntopresa = '3198700212137'
AND s.ser_stato_cont = '5'
AND s.ser_codsersub IS NULL
AND l.let_dat_lettur =
(SELECT MAX (l2.let_dat_lettur)
FROM lettur l2
WHERE l2.let_ute = s.ser_ute
AND l2.let_puntopresa = s.ser_puntopresa
AND l2.let_tip_lettur != 'M')
AND 0 <
(SELECT /*rule*/ /* index(s1 I1_serviz)*/ COUNT (0)
FROM lettur l1,serviz s1
WHERE
l1.let_ute = s.ser_ute
AND l1.let_matricola = l.let_matricola
AND l1.let_cod_fab = l.let_cod_fab
AND l1.let_puntopresa != s.ser_puntopresa
AND l1.let_dat_lettur > l.let_dat_lettur
AND s1.ser_puntopresa=l1.let_puntopresa
AND s1.ser_ute= l1.let_ute
AND s1.ser_datainifor >= s.ser_datainifor
AND LTRIM(s1.ser_statoserv) = '1'
select field
into var
from table
where ....
es:
begin
select field
into var
from table
where ...;
exception
when TOO_MANY_ROWS then
null;
Manuale DB ORACLE - PLSQL
end;
--> qui var è valorizzata con il primo valore estratto dalla select!
24.4.
Interi, Decimali
MAX (LENGTH (TRUNC (let_lettura)))
25. TIPS
/*
PROMPT
PROMPT
PROMPT
select /*+ index(ana i1_ana)
use_nl(ana) */
1
from anacon
where a_ute = m_ute and
a_codser = m_codser and
a_matcon = m_matcon and
nvl(aco_sigcon,'ç') = nvl(m_sigcon,'ç') and
a_codfab = m_codfab and
a_anno_fab = m_anno_fab)
*/
Manuale DB ORACLE - PLSQL
Stesso procedimento di prima….in questo caso però i dati sono salvati sul db locale
e quindi non c’è il rischio di modificare i dati sul DB Oracle.
v$session.audsid=sys_context('userenv','sessionid');
mod: module name
mh: module hash
act: ah
len Length of SQL statement.
dep Recursive depth of the cursor.
uid Schema user id of parsing user.
oct Oracle command type.
lid Privilege user id.
ela Elapsed time. 8i: in 1/1000th of a second, 9i: 1/1'000'000th of a second
tim Timestamp. Pre-Oracle9i, the times recorded by Oracle only have a resolution of 1/100th of a
second (10mS). As of Oracle9i some times are available to microsecond accuracy (1/1,000,000th
of a second).
hv Hash id.
ad SQLTEXT address (see v$sqlarea and v$sqltext).
3. introdurre HINT per il Query Optimizer onde evitare full scan ecc.
4. togliere inizializzazioni o calcoli dai loop
5. evitare dichiarazione di variabili non utilizzate
6. evitare passaggio di dati non necessari alle funzioni
7. se si devono utilizzare numeri interi, evitare Number e Integer, usare piuttosto
PLS_INTEGER che è nativo
8. evitare le conversioni implicite: es con Number è meglio sommare 15,0 che 15 (poichè
essendo intero deve prima essre convertito in Number e poi sommato...)
9. evitare variabili definite con constraint, es. not null, poichè richiedono variabili temporanee
di appoggio; è meglio togliere il constraint e poi fare un test con raise di errore
10. se una condizione multipla prevede la OR, mettere per prima quella più frequente: se risulta
verificata la seconda non viene neppure valutata
11. se una condizione multipla prevede la AND, mettere per seconda eventuali funzioni booleane,
ecc. in modo che siano eseguite solo le prima è verificata
12. la Shared Pool Memory deve essere sufficientemente ampia da contenere i package usati
più di frequente, altrimenti fa dentro e fuori di continuo
13. altra possibilità per il punto sopra è usare i package PINNED per non fargli usare FIFO-LRU
14. si può usare il nuovo tool Profiler per trovare le aree problematiche
15. Verificare anche con SPOT-Light della QUEST i problemi del server
DECLARE
type myRecord is RECORD
(
c1 number,
c2 varchar2(45)
);
demoArray myArray;
Begin
for i in 1..5 loop
demoArray(i).c1 := i;
demoArray(i).c2 := 'Col2: ' || i;
end loop;
end;
-- Count(*) : 9175
http://www.akadia.com/html/publications.html#Oracle%20Tips%20of%20the%20Week
Il linguaggio SQL e' apparentemente molto semplice. Tuttavia per sfruttare appieno le possibilita' che offre e'
necessario conoscerne profondamente le particolarita' e gli elementi specifici che ogni diversa implementazione
presenta.
Oracle in particolare offre diverse estensioni del linguaggio SQL che comprendono nuove clausole e funzioni di
utilita'. Anche dal punto di vista del miglioramento delle prestazioni gli ottimizzatori presenti (RULE BASED e COST
BASED che utilizzano diversi parametri di controllo) offrono parecchie funzionalita'.
E' opportuno evitare statement generici quali "SELECT * FROM ..." poiche' Oracle necessita di scansioni
ulteriori delle tabelle del data-dictionary (per altro tali statement non sono indipendenti da eventuali
modifiche della base dati).
E' necessario controllare se e' presente un indice Oracle per ogni condizione significativa negli statement
SQL che coinvolga una notevole quantita' di dati (tra le condizioni di maggior rilievo vanno ricordati i joins).
E' necessario controllare che gli indici utili non siano disattivati (vedere piu' avanti come e' possibile
disattivare un indice).
Le condizioni vanno poste in ordine di selettivita' (RULE BASED). Tra le condizioni di maggior selettivita' vi
sono i join.
Evitare operazioni SQL su grandi quantita' di dati e senza condizioni. Non basare la selettivita' delle
operazioni sulle sole scelte utente se non in casi particolari. Condizioni come between, like, .. non sono
generalmente sufficientemente selettive.
E' opportuno disattivare tutti gli indici non opportuni (RULE BASED)! Per disattivare un indice e' sufficiente
applicare una funzione di qualsiasi tipo o effettuare una qualsiasi operazione (come trucco si utilizza una
operazione invariante quale +0 o ||'') sul campo dell'indice. Per l'individuazione degli indici non opportuni e'
possibile adottare regole empiriche (regola del 10%) o effettuare test sull'accesso ai dati.
E' necessario effettuare con frequenza l'ANALYZE delle tabelle (ogni volta che avvengono cambiamenti
significative sulle dimensioni delle tabelle) (COST BASED).
Non cercare di effettuare join con loop annidati ma utilizzare le specifiche condizioni.
Non effettuare elaborazioni statistiche con cicli su tutti i dati ma sfruttare le funzioni di gruppo offerte
(peraltro standard).
Non e' obbligatorio utilizzare la tabella DUAL per determinare l'ora di sistema ma e' possibile utilizzare una
selezione differente e gia' richiamata.
Manuale DB ORACLE - PLSQL
Non e' necessario passare sempre dati su host variables ma e' possibile utilizzare le funzioni offerte
dall'RDBMS per le necessarie elaborazioni o conversioni dei dati.
E' necessario porre attenzione alle clausole not in quanto Oracle ritiene che una condizione in not sia
poco selettiva. E' spesso opportuno valutare selezioni alternative.
I valori posti a null richiedono un corretto trattamento sia per la semantica dello statement SQL che per la
sua ottimizzazione. Se ben definiti i valori a null consentono risparmi nella scrittura di codice ed efficienza
nell'esecuzione. Vi sono specifiche funzioni per il trattamento dei valori a null (nvl()).
Le operazioni di outer join sono relativamente complesse e trattate con modalita' necessariamente
differenti dai join comuni. E' in genere sconsigliato l'utilizzo di outer joins sia per motivi di portabilita' che di
efficienza.
E' spesso possibile utilizzare alcune delle potenti funzioni Oracle (decode, conversioni, ..) per ottenere
risposte altrimenti complesse.
Debbono essere attentamente valutate le selezioni annidate; in alcuni casi la forma di selezione annidata
e' maggiormente performante, in altri casi e' opportuno effettuare trasformazioni. E' importante notare che
tutte le selezioni possono essere trasformate in selezioni annidate (in genere meno efficienti).
In alcuni casi puo' essere utile sfruttare l'istruzione di union (per formare l'unione insiemistica dei risultati di
due differenti selezioni).
Gli indici composti (costruiti su piu' colonne) vengono usati solo se le colonne che li compongono sono
richiamate nello statement SQL in un certo modo: solo la prima, la prima + la seconda, la prima + la
seconda + la terza, ecc. Se e' richiamata solo la seconda colonna e non la prima, l'indice composto non
viene utilizzato. La corretta definizione di indici composti puo' portare ad una notevole efficienza nelle
ricerche.
Evitare operazioni che richiedano ingenti spazi temporanei per l'esecuzione (ordinamenti di tabelle molto
grandi, ..). Le clausole di DISTINCT e di GROUP BY sono analoghe (da punto di vista computazionale) alla
clausola di ORDER BY. Lo stesso tipo di problema puo' presentarsi alla creazione di indici.
Controllare la gestione dei lock per evitare blocchi ai dati su accessi in contemporanea.
Possono essere costruite condizioni di selezione molto complesse ed efficienti per gli statement di
DELETE, INSERT ed UPDATE utilizzando le selezioni annidate.
Gli statement SQL hanno un costo (tale costo e' evidente nelle operazioni molto frequenti e di veloce
esecuzione). Tale aspetto deve essere tenuto in conto. In generale e' opportuno limitare il numero di
statement SQL.
Per la cancellazione di tutti i record di una tabella e' opportuno l'utilizzo del comando TRUNCATE
(versione 7).
Per elementi di maggior dettaglio sui punti presentati e' necessario fare riferimento alla specifica manualistica.
Explain Plan
Il comando EXPLAIN PLAN (CTRL+E in TOAD) mostra l'esatto percorso compiuto dall'ottimizzatore ORACLE per
eseguire uno statement SQL: e' cosi' possibile verificare se vengono adeguatamente sfruttati gli indici presenti.
Il comando EXPLAIN PLAN (applicato a un determinato statement SQL) popola una tavola di servizio da cui e'
possibile estrarre tutte le informazioni sull'esecuzione dello statement.
Manuale DB ORACLE - PLSQL
http://213.92.21.88/meo/white/varie/sql_tune.htm
sintassi:
COPY FROM <db_orig> [TO <db_dest>] <opt> <table> [(<cols>)] USING <select>
<db_orig> <db_dest> : stringa di connessione completa (utente/passw@db_sid) al database origine e
opzionalmente di destinazione se già la connessione nel db destinazione è stata effettuata in sqlplus; per il db
origine va ovviamente individuata la stringa esatta di connessione
<opt> : una delle keywords: APPEND, CREATE, INSERT, REPLACE
<table>: tabella di destinazione (anche diversa da quella origine)
<cols> : opzionale lista di colonne in tabella destinazione separata da virgola
<select>: condizione di select valida relativa alla tabella del db origine
esempio:
> sqlplus test4/test4
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.2.0 - 64bit Production
With the Partitioning, OLAP and Data Mining options
ESEMPIO:
ESEMPIO:
SELECT REGEXP_REPLACE ('TOGLIAMO TUTTI GLI SPAZI DOPPI E CI METTIAMO UNA
CHIOCCIOLA',
'( ){2,}',
'@'
) rx_replace
FROM DUAL