Può essere di grande aiuto in alcune operazioni SQL avere a disposizione tabelle intermedie su cui salvare dei risultati per una successiva elaborazione. Quando lavoriamo con database Oracle abbiamo a diposizione due soluzioni.
Possiamo creare delle tabelle temporanee globali direttamente con un CREATE TABLE, oppure ricorrere a variabili di tipo tabella. La prima soluzione è utile nel caso di manipolazione di grandi quantità di dati e ci permette di decidere se lasciare o meno i dati in tabella conclusa la sessione. Vediamo la sintassi PL/SQL:

CREATE GLOBAL TEMPORARY TABLE tempPhoneBookTable
(
   name VARCHAR2(40),
   surname VARCHAR2(60),
   phoneNumber VARCHAR2(15)
) ON COMMIT PRESERVE ROWS; --preserve data after commit

Per approfondire l’argomento sulle tabelle temporanee globali vi consiglio l’ottimo articolo di Don Burleson su come utilizzare le tabelle temporanee per aumentare le performance di una query.

La seconda soluzione consente di definire variabili di tipo tabella direttamente all’interno dello statement o della procedura e di utilizzare metodi specifici per manipolare i dati della collezione. In Oracle le variabili di tipo tabella possono essere paragonate a tabelle di database ad una sola colonna. Nella dichiarazione della variabile devo quindi indicare il tipo di dato da memorizzare. In alcuni casi, come nell’esempio seguente, avrò bisogno di più colonne, devo ricorrere quindi all’utilizzo dei record:

SET serveroutput ON
DECLARE
--define a record
TYPE contact IS RECORD (
    name VARCHAR2(40),
    surname VARCHAR2(60),
    phoneNumber VARCHAR2(15)
    );
--define a table composed of records
TYPE phoneBook IS TABLE OF contact
   INDEX BY BINARY_INTEGER;

--declare a TABLE variable of this type
myPhoneBook phoneBook;
counter INTEGER :=1;

BEGIN
    myPhoneBook(1).name := 'Manuel';
    myPhoneBook(1).surname := 'Scapolan';
    myPhoneBook(1).phoneNumber := '555-5555';

    myPhoneBook(2).name := 'Mario';
    myPhoneBook(2).surname := 'Rossi';
    myPhoneBook(2).phoneNumber := '666-66666';

    WHILE myPhoneBook.EXISTS(counter) LOOP
    dbms_output.put_line(myPhoneBook(counter).surname || ' ' 
        || myPhoneBook(counter).name || ' tel. ' 
        || myPhoneBook(counter).phoneNumber);
    counter := counter+1;
    END LOOP;
END;
/