Oracle Tipi di oggetti PL/SQL: CREATE TYPE con esempi
⚡ Riepilogo intelligente
I tipi di oggetto in PL/SQL portano la programmazione orientata agli oggetti a Oracle, consentendo di modellare entità del mondo reale con attributi e metodi. Supportano costruttori, ereditarietà e confronto di uguaglianza, in modo che un singolo tipo a livello di schema possa memorizzare ed elaborare dati strutturati.
Cos'è il tipo di oggetto in PL/SQL?
La programmazione orientata agli oggetti è particolarmente adatta alla creazione di componenti riutilizzabili e applicazioni complesse. I programmi sono organizzati attorno a "oggetti" anziché ad "azioni"; in altre parole, sono progettati per lavorare e interagire con un oggetto intero piuttosto che con una singola azione. Questo approccio consente al programmatore di inserire e manipolare i dettagli a livello di oggetto-entità.
L'immagine sottostante illustra un esempio di tipo di oggetto in cui un conto bancario viene trattato come un'entità oggetto. Gli attributi dell'oggetto contengono valori (per un conto bancario si tratta del numero di conto, del saldo e così via), mentre i metodi dell'oggetto descrivono azioni come il calcolo del tasso di interesse o la generazione di un estratto conto, ognuna delle quali richiede il completamento di un processo.
In PL / SQLLa programmazione orientata agli oggetti si basa sui tipi di oggetto. Un tipo di oggetto può rappresentare qualsiasi entità del mondo reale. Le sezioni seguenti esplorano i tipi di oggetto, i loro componenti e come crearli e utilizzarli.
Componenti dei tipi di oggetto
Un tipo di oggetto PL/SQL contiene principalmente due componenti.
- Attributi
- Membri/Metodi
Attributi
Gli attributi sono le colonne o i campi in cui vengono memorizzati i dati. Ogni attributo è mappato al tipo di dati che definisce il tipo di elaborazione e di archiviazione per tale attributo. Un attributo può essere di qualsiasi tipo valido. Tipo di dati PL/SQLoppure può essere di un altro tipo di oggetto.
Membri/Metodi
I membri, o i metodi, sono sottoprogrammi Definiti all'interno del tipo di oggetto. Non vengono utilizzati per memorizzare dati; definiscono invece l'elaborazione eseguita all'interno del tipo di oggetto, ad esempio la convalida dei dati prima di popolare l'oggetto. Sono dichiarati nella specifica del tipo di oggetto e definiti nel corpo del tipo di oggetto. Il corpo è facoltativo: se non sono presenti membri, un tipo di oggetto non ha una parte del corpo.
Crea oggetto in Oracle
Un tipo di oggetto non può essere creato a livello di sottoprogramma; può essere creato solo a livello di schema. Una volta definito nello schema, il tipo di oggetto può essere utilizzato nei sottoprogrammi. Il tipo di oggetto viene creato tramite l'istruzione "CREATE TYPE" e il corpo del tipo può essere creato solo dopo che il tipo di oggetto esiste.
Le schermate seguenti mostrano la sintassi CREATE TYPE per la specifica dell'oggetto e la sintassi CREATE TYPE BODY che ne definisce i metodi.
CREATE TYPE<object_type_name> AS OBJECT ( <attribute_l><datatype>, . . ); / CREATE TYPE BODY<object_type_name> AS OBJECT ( MEMBER[PROCEDURE|FUNCTION]<member_name> IS <declarative section> BEGIN <execution part> END; . . ); /
Spiegazione della sintassi:
- La sintassi sopra riportata mostra la creazione di un OGGETTO con attributi e di un CORPO DELL'OGGETTO con metodi.
- I metodi possono anche essere sovraccaricati nel corpo dell'oggetto.
Inizializzazione della dichiarazione del tipo di oggetto
Come altri componenti in PL/SQL, i tipi di oggetto devono essere dichiarati prima di essere utilizzati in un programma. Una volta creato il tipo di oggetto, può essere utilizzato nella sezione dichiarativa di una sottoprogramma per dichiarare una variabile di quel tipo di oggetto.
Ogni volta che una variabile viene dichiarata come tipo oggetto, in fase di esecuzione viene creata una nuova istanza di tale tipo oggetto, a cui si fa riferimento tramite il nome della variabile. In questo modo, un singolo tipo oggetto può memorizzare più valori in istanze diverse.
Lo screenshot qui sotto mostra una variabile dichiarata come tipo oggetto all'interno di un Blocco PL/SQL.
DECLARE <variable_name> <object_type_name>; BEGIN . . END; /
Spiegazione della sintassi:
- La sintassi sopra riportata mostra la dichiarazione di un variabile come tipo di oggetto nella sezione dichiarativa.
Una volta che una variabile viene dichiarata come tipo oggetto in una sottoprogramma, è atomicamente nulla: l'intero oggetto stesso è nullo. Deve essere inizializzata con dei valori prima di poter essere utilizzata nel programma. Gli oggetti vengono inizializzati tramite i costruttori.
I costruttori sono metodi impliciti di un oggetto a cui si può fare riferimento con lo stesso nome del tipo di oggetto. Lo screenshot seguente mostra l'inizializzazione di un'istanza di un tipo di oggetto.
DECLARE <variable_name> <object_type_name>; BEGIN <variable_name>:=<object_type_name>(); END; /
Spiegazione della sintassi:
- La sintassi sopra riportata mostra l'inizializzazione dell'istanza del tipo di oggetto con un valore nullo.
- Una volta inizializzato, l'oggetto stesso non è più nullo, ma gli attributi al suo interno rimangono nulli finché non vengono loro assegnati dei valori.
Costruttori
I costruttori sono metodi impliciti di un oggetto a cui si può fare riferimento con lo stesso nome del tipo di oggetto. Ogni volta che si fa riferimento all'oggetto per la prima volta, questo costruttore viene chiamato implicitamente.
È possibile inizializzare gli oggetti anche tramite questi costruttori. Un costruttore può essere definito esplicitamente definendo un membro nel corpo del tipo di oggetto con lo stesso nome del tipo di oggetto.
Esempio 1: Nell'esempio seguente, utilizziamo il membro di tipo oggetto per inserire record nella tabella emp con i valori ('RRR', 1005, 20000, 1000) e ('PPP', 1006, 20000, 1001). Una volta inseriti i dati, li visualizziamo utilizzando il membro di tipo oggetto. Utilizziamo anche un costruttore esplicito per popolare l'ID del manager con il valore predefinito 1001 per il secondo record.
Lo eseguiamo seguendo questi passaggi.
- Passaggio 1: Creare il tipo di oggetto e il corpo del tipo di oggetto.
- Passaggio 2: Creare un blocco anonimo per richiamare il tipo di oggetto tramite il costruttore implicito per emp_no 1005.
- Passaggio 3: Creare un blocco anonimo per richiamare il tipo di oggetto tramite il costruttore esplicito per emp_no 1006.
Passaggio 1) Creare il tipo di oggetto e il corpo del tipo di oggetto.
Lo screenshot qui sotto mostra la specifica del tipo di oggetto emp_object in fase di creazione, con i relativi attributi e membri.
CREATE TYPE emp_object AS OBJECT( emp_no NUMBER, emp_name VARCHAR2(50), salary NUMBER, manager NUMBER, CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER, p_emp_name VARCHAR2, p_salary NUMBER) RETURN SELF AS RESULT), MEMBER PROCEDURE insert_records, MEMBER PROCEDURE display_records); /
Lo screenshot qui sotto mostra la creazione del corpo del tipo emp_object con il costruttore esplicito e le procedure membro.
CREATE OR REPLACE TYPE BODY emp_object AS CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER,p_emp_name VARCHAR2, p_salary NUMBER) RETURN SELF AS RESULT IS BEGIN Dbms_output.put_line('Constructor fired..'); SELF.emp_no:=p_emp_no; SELF.emp_name:=p_emp_name; SELF.salary:=p_salary; SELF.manager:=1001; RETURN; END; MEMBER PROCEDURE insert_records IS BEGIN INSERT INTO emp VALUES(emp_no,emp_name,salary,manager); END; MEMBER PROCEDURE display_records IS BEGIN Dbms_output.put_line('Employee Name:'||emp_name); Dbms_output.put_line('Employee Number:'||emp_no); Dbms_output.put_line('Salary:'||salary); Dbms_output.put_line('Manager:'||manager); END; END; /
Code Spiegazione
- Code righe 1-9: Creazione dell'oggetto di tipo 'emp_object' con 4 attributi e 3 membri. Contiene la definizione di un costruttore con soli 3 parametri. (Il costruttore implicito effettivo contiene un numero di parametri pari al numero di attributi presenti nell'oggetto di tipo.)
- Code riga 10: Creazione del corpo del tipo.
- Code righe 11-21: Definizione del costruttore esplicito. Assegnazione dei valori dei parametri agli attributi e assegnazione del valore predefinito '1001' all'attributo 'manager'.
- Code righe 22-26: Definizione del membro 'insert_records', in cui i valori degli attributi vengono inseriti nella tabella 'emp'.
- Code righe 27-34: Definizione del membro 'display_records', che visualizza i valori degli attributi del tipo di oggetto.
Produzione:
Tipo creato
Corpo del tipo creato
Passo 2) Creazione di un blocco anonimo per richiamare il tipo di oggetto creato tramite il costruttore implicito per emp_no 1005.
Lo screenshot qui sotto mostra il blocco anonimo che chiama emp_object tramite il costruttore implicito.
DECLARE guru_emp_det emp_object; BEGIN guru_emp_det:=emp_object(1005,'RRR',20000,1000); guru_emp_det.display_records; guru_emp_det.insert_records; COMMIT; END;
Code Spiegazione
- Code righe 37-45: Inserimento dei record tramite il costruttore implicito. La chiamata al costruttore contiene il numero effettivo di valori degli attributi.
- Code riga 38: Dichiara 'guru_emp_det' come oggetto di tipo 'emp_object'.
- Code riga 41: L'istruzione 'guru_emp_det.display_records' richiama il membro 'display_records' e visualizza i valori degli attributi.
- Code riga 42: L'istruzione 'guru_emp_det.insert_records' chiama il membro 'insert_records' e i valori degli attributi vengono inseriti nella tabella. Il blocco quindi esegue il commit delle transazioni.
Produzione:
Nome del dipendente: RRR
Numero dipendenti: 1005
Stipendio: 20000
Gestore: 1000
Passo 3) Creazione di un blocco anonimo per richiamare il tipo di oggetto creato tramite il costruttore esplicito per emp_no 1006.
Lo screenshot qui sotto mostra il blocco anonimo che chiama emp_object tramite il costruttore esplicito con tre argomenti.
DECLARE guru_emp_det emp_object; BEGIN guru_emp_det:=emp_object(1006,'PPP',20000); guru_emp_det.display_records; guru_emp_det.insert_records; COMMIT; END; /
Uscita
Employee Name:PPP Employee Number:1006 Salary:20000 Manager:1001
Code Spiegazione:
- Code righe 46-53: Inserimento del record tramite il costruttore esplicito.
- Code riga 46: Dichiara 'guru_emp_det' come oggetto di tipo 'emp_object'.
- Code riga 50: L'istruzione 'guru_emp_det.display_records' richiama il membro 'display_records' e visualizza i valori degli attributi.
- Code riga 51: L'istruzione 'guru_emp_det.insert_records' richiama il membro 'insert_records' e i valori degli attributi vengono inseriti nella tabella. Poiché vengono passati solo tre argomenti, il costruttore esplicito imposta l'ID del manager al suo valore predefinito 1001.
Ereditarietà nel tipo di oggetto
La proprietà di ereditarietà consente a un tipo di sotto-oggetto di accedere a tutti gli attributi e i membri del tipo di oggetto super, o tipo di oggetto padre.
Il tipo di sotto-oggetto è chiamato tipo di oggetto ereditato, mentre il tipo di oggetto super è chiamato tipo di oggetto padre. La sintassi seguente mostra come creare tipi di oggetto padre ed ereditati. Lo screenshot seguente mostra la sintassi del tipo padre (SUPER) contrassegnata come NON DEFINITIVA.
CREATE TYPE <object_type_name_parent> AS OBJECT ( <attribute_l><datatype>, . . )NOT FINAL; /
Spiegazione della sintassi:
- La sintassi sopra riportata mostra la creazione del tipo SUPER. La clausola NOT FINAL consente l'ereditarietà del tipo.
Lo screenshot qui sotto mostra la sintassi del tipo ereditato (SUB) creato con la parola chiave UNDER.
CREATE TYPE<object_type_name_sub>UNDER<object_type_name_parent> ( <attribute_l><datatype>, . ); /
Spiegazione della sintassi:
- La sintassi sopra riportata mostra la creazione del tipo SUB. Esso contiene tutti i membri e gli attributi del tipo di oggetto padre.
Esempio 1: Nell'esempio seguente, utilizziamo la proprietà di ereditarietà per inserire un record con ID manager '1002' per il record ('RRR', 1007, 20000). Eseguiamo il programma nei seguenti passaggi.
- Passaggio 1: Creare il tipo SUPER.
- Passaggio 2: Creare il sottotipo e il corpo.
- Passaggio 3: Creare un blocco anonimo per richiamare il tipo SUB.
Passaggio 1) Creare un tipo SUPER o un tipo genitore.
Lo screenshot qui sotto mostra la creazione del supertipo emp_object con la clausola NOT FINAL.
CREATE TYPE emp_object AS OBJECT( emp_no NUMBER, emp_name VARCHAR2(50), salary NUMBER, manager NUMBER, CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER,p_emp_name VARCHAR2(50), p_salary NUMBER)RETURN SELF AS RESULT), MEMBER PROCEDURE insert_records, MEMBER PROCEDURE display_records)NOT FINAL; /
Code Spiegazione:
- Code righe 1-9: Creazione dell'oggetto di tipo 'emp_object' con 4 attributi e 3 membri. Contiene la definizione di un costruttore con soli 3 parametri. È stato dichiarato come 'NOT FINAL', quindi è un tipo padre.
Passaggio 2) Creare un SOTTOtipo sotto il SUPERtipo.
Lo screenshot qui sotto mostra il tipo ereditato sub_emp_object e la creazione del suo corpo.
CREATE OR REPLACE TYPE sub_emp_object UNDER emp_object (default_manager NUMBER,MEMBER PROCEDURE insert_default_mgr); / CREATE OR REPLACE TYPE BODY sub_emp_object AS MEMBER PROCEDURE insert_default_mgr IS BEGIN INSERT INTO emp VALUES(emp_no,emp_name,salary,manager); END; END; /
Code Spiegazione:
- Code righe 10-13: Creazione di 'sub_emp_object' come tipo ereditato con un attributo aggiuntivo 'default_manager' e dichiarazione di una procedura membro.
- Code riga 14: Creazione del corpo per il tipo di oggetto ereditato.
- Code righe 16-21: Definizione della procedura membro che inserisce record nella tabella 'emp' con i valori del tipo di oggetto SUPER, ad eccezione del valore manager. Per il valore manager, viene utilizzato 'default_manager' dal tipo SUB.
Passaggio 3) Creazione del blocco anonimo per richiamare il tipo SUB.
Lo screenshot qui sotto mostra il blocco anonimo che richiama il tipo SUB e inserisce l'ID del gestore predefinito.
DECLARE guru_emp_det sub_emp_object; BEGIN guru_emp_det:= sub_emp_object(1007,'RRR',20000,1000,1002); guru_emp_det.insert_default_mgr; COMMIT; END; /
Code Spiegazione:
- Code riga 25: Dichiarazione di 'guru_emp_det' come tipo 'sub_emp_object'.
- Code riga 27: Inizializzazione dell'oggetto con il costruttore implicito. Il costruttore ha 5 parametri (4 attributi dal tipo PARENT e 1 attributo dal tipo SUB). L'ultimo parametro (1002) definisce il valore per l'attributo default_manager.
- Code riga 28: Chiamata al membro 'insert_default_mgr' per inserire il record con l'ID del responsabile predefinito passato nel costruttore.
Uguaglianza di oggetti PL/SQL
Le istanze di oggetti appartenenti allo stesso tipo di oggetto possono essere confrontate per verificarne l'uguaglianza. A tale scopo, il tipo di oggetto necessita di un metodo speciale chiamato metodo ORDER.
Questo metodo ORDER dovrebbe essere una funzione che restituisce un tipo numerico. Accetta due parametri in input (primo parametro: l'ID dell'istanza dell'oggetto stesso; secondo parametro: l'ID di un'altra istanza di oggetto).
Gli ID delle due istanze di oggetto vengono confrontati e il risultato viene restituito come un numero.
- Un valore positivo indica che l'istanza dell'oggetto SELF è maggiore dell'altra istanza.
- Un valore negativo indica che l'istanza dell'oggetto SELF è minore dell'altra istanza.
- Il valore zero indica che l'istanza dell'oggetto SELF è uguale all'altra istanza.
- Se una delle due istanze è null, la funzione restituisce null.
Lo screenshot qui sotto mostra la sintassi della funzione membro ORDER che deve essere inclusa nel corpo del tipo per il controllo di uguaglianza.
CREATE TYPE BODY<object_type_name_ 1>AS OBJECT ( ORDER MEMBER FUNCTION match(<parameter> object_type_name_ 1) RETURN INTEGER IS BEGIN IF <attribute_name>parameter <attribute_name>THEN RETURN -1; --any negative number will do ELSIF id>c.id THEN RETURN 1; --any positive number will do ELSE RETURN 0; END IF; END; . . ); /
Spiegazione della sintassi:
- La sintassi sopra riportata mostra la funzione ORDER che deve essere inclusa nel corpo del tipo per il controllo di uguaglianza.
- Il parametro per questa funzione dovrebbe essere un'istanza dello stesso tipo di oggetto.
- La funzione può essere chiamata come “obj_instance_1.match(obj_instance_2)”, e questa espressione restituisce il valore numerico mostrato, dove obj_instance_1 e obj_instance_2 sono istanze del tipo di oggetto.
Esempio 1: Nell'esempio seguente, confrontiamo due oggetti. Creiamo due istanze e confrontiamo l'attributo 'salario' tra di esse. Lo facciamo in due passaggi.
- Passaggio 1: Creare il tipo di oggetto e il corpo.
- Passaggio 2: Creare il blocco anonimo per confrontare le istanze degli oggetti.
Passaggio 1) Creazione del tipo di oggetto e del corpo.
Gli screenshot seguenti mostrano la specifica emp_object_equality e il suo corpo, che definisce la funzione ORDER che confronta l'attributo salary.
CREATE TYPE emp_object_equality AS OBJECT( salary NUMBER, ORDER MEMBER FUNCTION equals(c emp_object_equality)RETURN INTEGER); /
CREATE TYPE BODY emp_object_equality AS ORDER MEMBER FUNCTION equals(c emp_object_equality)RETURN INTEGER IS BEGIN IF salary<c.salary THEN RETURN -1; ELSIF salary>c.salary THEN RETURN 1; ELSE RETURN 0; END IF; END; END; /
Code Spiegazione:
- Code righe 1-4: Creazione dell'oggetto di tipo 'emp_object_equality' con 1 attributo e 1 membro.
- Code righe 6-16: Definizione della funzione ORDER che confronta l'attributo 'salary' dell'istanza SELF e dell'istanza del parametro. Restituisce un valore negativo se lo stipendio di SELF è inferiore, un valore positivo se lo stipendio di SELF è superiore e 0 se gli stipendi sono uguali.
Code Produzione:
Tipo creato
Passaggio 2) Creazione del blocco anonimo per confrontare le istanze degli oggetti.
Lo screenshot qui sotto mostra il blocco anonimo che confronta due istanze di emp_object_equality in base allo stipendio.
DECLARE l_obj_1 emp_object_equality; l_obj_2 emp_object_equality; BEGIN l_obj_1:=emp_object_equality(15000); l_obj_2:=emp_object_equality(17000); IF l_obj_1.equals(l_obj_2)>0 THEN Dbms_output.put_line('Salary of first instance is greater'); ELSIF l_obj_1.equals(l_obj_2)<0 THEN Dbms_output.put_line('Salary of second instance is greater'); ELSE Dbms_output.put_line('Salaries are equal'); END IF; END; /
Uscita
Salary of second instance is greater
Code Spiegazione:
- Code riga 20: Dichiarazione di 'l_obj_1' di tipo 'emp_object_equality'.
- Code riga 21: Dichiarazione di 'l_obj_2' di tipo 'emp_object_equality'.
- Code riga 23: Inizializzazione di 'l_obj_1' con il valore salariale '15000'.
- Code riga 24: Inizializzazione di 'l_obj_2' con il valore salariale '17000'.
- Code righe 25-33: Stampa del messaggio in base al numero restituito dalla funzione ORDINE.



















