Oracle PL/SQL-objekttyper: CREATE TYPE med exempel

⚡ Smart sammanfattning

Objekttyper i PL/SQL gör objektorienterad programmering möjlig Oracle, vilket låter dig modellera verkliga entiteter med attribut och metoder. De stöder konstruktorer, arv och likhetsjämförelse, så en enda schemanivåtyp kan lagra och bearbeta strukturerad data.

  • 🧱 Objekttypkomponenter: En objekttyp kombinerar attribut som lagrar data och medlemmar, eller metoder, som definierar dess bearbetningslogik.
  • 🏗️ Skapa objekt: Objekttyper skapas på schemanivå med CREATE TYPE, och deras metoder definieras i en separat CREATE TYPE BODY.
  • 🔧 Konstruktörer: Varje objekttyp har en implicit konstruktor som är uppkallad efter typen, och du kan definiera en explicit konstruktor för att ange standardvärden.
  • 🧬 Arv: En NOT FINAL föräldertyp utökas med UNDER, så en undertyp ärver alla förälderattribut och medlemmar.
  • ⚖️ Jämlikhet: En ORDER-medlemsfunktion jämför två objektinstanser och returnerar ett negativt, noll eller positivt tal.
  • 🤖 AI-hjälp: AI-assistenter som GitHub Copilot utarbetar CREATE TYPE-definitioner, konstruktorer och ORDER-metoder från en kommentar.

Oracle PL/SQL-objekttyper som visar CREATE TYPE med attribut och metoder

Vad är objekttyp i PL/SQL?

Objektorienterad programmering är särskilt lämpad för att bygga återanvändbara komponenter och komplexa applikationer. Program är organiserade kring "objekt" snarare än "åtgärder"; det vill säga de är utformade för att arbeta med och interagera med ett helt objekt snarare än en enda åtgärd. Denna metod låter programmeraren fylla i och manipulera detaljer på objekt-entitetsnivå.

Bilden nedan visar ett exempel på en objekttyp där ett bankkonto behandlas som en objektenhet. Objektattributen innehåller värden – för ett bankkonto är dessa kontonummer, banksaldo och så vidare – medan objektmetoderna beskriver åtgärder som att beräkna räntan eller generera ett bankutdrag, vilka var och en kräver att en process slutförs.

Bankkonto modellerat som en objekttyp med attribut och metoder i PL/SQL

In PL / SQL, objektorienterad programmering är baserad på objekttyper. En objekttyp kan representera vilken verklig enhet som helst. Avsnitten nedan utforskar objekttyper, deras komponenter och hur man skapar och använder dem.

Komponenter av objekttyper

En PL/SQL-objekttyp innehåller huvudsakligen två komponenter.

  1. attribut
  2. Medlemmar/Metoder

attribut

Attribut är de kolumner eller fält där data lagras. Varje attribut mappas till den datatyp som definierar bearbetnings- och lagringstypen för det attributet. Ett attribut kan vara av vilket giltigt PL/SQL-datatyp, eller det kan vara av en annan objekttyp.

Medlemmar/Metoder

Medlemmarna, eller metoderna, är underprogram definierade inuti objekttypen. De används inte för att lagra data; istället definierar de den bearbetning som utförs inuti objekttypen – till exempel validering av data innan objektet fylls i. De deklareras i objekttypspecifikationen och definieras i objekttypens brödtext. Brödtexten är valfri: om inga medlemmar finns har en objekttyp ingen brödtextdel.

Skapa objekt i Oracle

En objekttyp kan inte skapas på delprogramnivå; den kan bara skapas på schemanivå. När objekttypen har definierats i schemat kan den användas i delprogram. Objekttypen skapas med hjälp av kommandot "CREATE TYPE", och typtexten kan bara skapas efter att dess objekttyp finns.

Skärmbilderna nedan visar CREATE TYPE-syntaxen för objektspecifikationen och CREATE TYPE BODY-syntaxen som definierar dess metoder.

CREATE TYPE-syntax som definierar en objektspecifikation med attribut i Oracle CREATE TYPE BODY-syntax som definierar metoderna för en PL/SQL-objekttyp

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;
.
.
);
/

Syntaxförklaring:

  • Syntaxen ovan visar skapandet av ett OBJECT med attribut och en OBJECT BODY med metoder.
  • Metoderna kan också överbelastas i objektkroppen.

Deklarationsinitiering av objekttyp

Liksom andra komponenter i PL/SQL måste objekttyper deklareras innan de används i ett program. När objekttypen har skapats kan den användas i ett delprograms deklarativa sektion för att deklarera en variabel av den objekttypen.

När en variabel deklareras som en objekttyp skapas en ny instans av objekttypen vid körning, och denna nyskapade instans refereras till med variabelnamnet. På så sätt kan en enda objekttyp lagra flera värden under olika instanser.

Skärmdumpen nedan visar en variabel som deklareras som en objekttyp inuti en PL/SQL-block.

Deklarera en variabel av en objekttyp i en deklarativ sektion för PL/SQL-block

DECLARE
<variable_name> <object_type_name>;
BEGIN
.
.
END;
/

Syntaxförklaring:

  • Syntaxen ovan visar deklarationen av en variabel som en objekttyp i den deklarativa sektionen.

När variabeln har deklarerats som en objekttyp i ett delprogram är den atomiskt null – hela objektet i sig är null. Den måste initieras med värden innan den kan användas i programmet. Objekt initieras med hjälp av konstruktorer.

Konstruktorer är den implicita metoden för ett objekt som kan refereras till med samma namn som objekttypen. Skärmdumpen nedan visar initialiseringen av en objekttypinstans.

Initiera en objekttypinstans till null med hjälp av dess konstruktor

DECLARE
<variable_name> <object_type_name>; 
BEGIN
<variable_name>:=<object_type_name>();
END;
/

Syntaxförklaring:

  • Syntaxen ovan visar initialiseringen av objekttypinstansen med ett nullvärde.
  • Själva objektet är inte längre null när det har initialiserats, men attributen inuti objektet förblir null tills värden tilldelas dem.

konstruktörer

Konstruktorer är den implicita metoden för ett objekt som kan refereras till med samma namn som objekttypen. Närhelst objektet refereras till för första gången anropas denna konstruktor implicit.

Du kan också initiera objekt med hjälp av dessa konstruktorer. En konstruktor kan definieras explicit genom att definiera en medlem i objekttypens brödtext med samma namn som objekttypen.

Exempel 1: I följande exempel använder vi objekttypmedlemmen för att infoga poster i emp-tabellen med värdena ('RRR', 1005, 20000, 1000) och ('PPP', 1006, 20000, 1001). När data har infogats visar vi dem med hjälp av objekttypmedlemmen. Vi använder också en explicit konstruktor för att fylla i manager-ID:t med standardvärdet 1001 för den andra posten.

Vi utför det i följande steg.

  • Steg 1: Skapa objekttypen och objekttypens brödtext.
  • Steg 2: Skapa ett anonymt block för att anropa objekttypen via den implicita konstruktorn för emp_no 1005.
  • Steg 3: Skapa ett anonymt block för att anropa objekttypen via den explicita konstruktorn för emp_no 1006.

Steg 1) Skapa objekttyp och objekttypstext.

Skärmdumpen nedan visar objekttypsspecifikationen emp_object som skapas med dess attribut och medlemmar.

Skapa objekttypspecifikationen emp_object med attribut och medlemmar

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);
/

Skärmdumpen nedan visar hur emp_object-typen av kroppen skapas med den explicita konstruktorn och medlemsprocedurerna.

Definiera emp_object-typens brödtext med en explicit konstruktor och medlemsprocedurer

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 Förklaring

  • Code rad 1-9: Skapar objekttypen 'emp_object' med 4 attribut och 3 medlemmar. Den innehåller definitionen av en konstruktor med endast 3 parametrar. (Den faktiska implicita konstruktorn innehåller antalet parametrar som motsvarar antalet attribut som finns i objekttypen.)
  • Code rad 10: Skapar typkroppen.
  • Code rad 11-21: Definiera den explicita konstruktorn. Tilldela parametervärdena till attributen och ge attributet 'manager' standardvärdet '1001'.
  • Code rad 22-26: Definierar medlemmen 'insert_records', där attributvärdena infogas i tabellen 'emp'.
  • Code rad 27-34: Definierar medlemmen 'display_records', som visar värdena för objekttypattributen.

Produktion:

Typ skapad

Skriv texten skapad

Steg 2) Skapar ett anonymt block för att anropa den skapade objekttypen genom den implicita konstruktorn för emp_no 1005.

Skärmdumpen nedan visar det anonyma blocket som anropar emp_object genom den implicita konstruktorn.

Anonymt blockanrop av emp_object genom den implicita konstruktorn för emp_no 1005

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 Förklaring

  • Code rad 37-45: Infogar posterna med hjälp av den implicita konstruktorn. Anropet till konstruktorn innehåller det faktiska antalet attributvärden.
  • Code rad 38: Deklarerar 'guru_emp_det' som objekttypen 'emp_object'.
  • Code rad 41: Satsen 'guru_emp_det.display_records' anropar medlemmen 'display_records' och attributvärdena visas.
  • Code rad 42: Satsen 'guru_emp_det.insert_records' anropar medlemmen 'insert_records' och attributvärdena infogas i tabellen. Blocket bekräftar sedan transaktion.

Produktion:

Anställds namn: RRR

Antal anställda: 1005

Lön: 20000 XNUMX

Chef: 1000

Steg 3) Skapar ett anonymt block för att anropa den skapade objekttypen genom den explicita konstruktorn för emp_no 1006.

Skärmdumpen nedan visar det anonyma blocket som anropar emp_object genom den explicita konstruktorn med tre argument.

Anonymt blockanrop av emp_object genom den explicita konstruktorn för emp_no 1006

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;
/

Produktion

Employee Name:PPP 
Employee Number:1006 
Salary:20000 
Manager:1001

Code Förklaring:

  • Code rad 46-53: Infoga posten med hjälp av den explicita konstruktorn.
  • Code rad 46: Deklarerar 'guru_emp_det' som objekttypen 'emp_object'.
  • Code rad 50: Satsen 'guru_emp_det.display_records' anropar medlemmen 'display_records' och attributvärdena visas.
  • Code rad 51: Satsen 'guru_emp_det.insert_records' anropar medlemmen 'insert_records' och attributvärdena infogas i tabellen. Eftersom endast tre argument skickas, sätter den explicita konstruktorn manager-ID:t till standardvärdet 1001.

Arv i objekttyp

Arvsegenskapen tillåter en underobjekttyp att komma åt alla attribut och medlemmar i superobjekttypen, eller överordnad objekttyp.

Underobjekttypen kallas ärvd objekttyp och superobjekttypen kallas förälderobjekttyp. Syntaxen nedan visar hur man skapar förälder- och ärvda objekttyper. Skärmdumpen nedan visar föräldertypens syntax (SUPER) markerad som INTE SLUTGILTIG.

CREATE TYPE-syntax för en NOT FINAL förälderobjekttyp som används i arv

CREATE TYPE <object_type_name_parent> AS OBJECT
(
<attribute_l><datatype>,
.
.
)NOT FINAL;
/

Syntaxförklaring:

  • Syntaxen ovan visar hur SUPER-typen skapas. NOT FINAL-klausulen gör att typen kan ärvas.

Skärmdumpen nedan visar den ärvda (SUB) typsyntaxen som skapats med nyckelordet UNDER.

CREATE TYPE UNDER-syntax för en underobjekttyp som ärver från en förälderobjekttyp

CREATE TYPE<object_type_name_sub>UNDER<object_type_name_parent>
(
<attribute_l><datatype>,
.
);
/

Syntaxförklaring:

  • Syntaxen ovan visar hur SUB-typen skapas. Den innehåller alla medlemmar och attribut från den överordnade objekttypen.

Exempel 1: I exemplet nedan använder vi arvsegenskapen för att infoga en post med hanterar-ID:t '1002' för posten ('RRR', 1007, 20000). Vi kör programmet i följande steg.

  • Steg 1: Skapa SUPER-typen.
  • Steg 2: Skapa SUB-typen och brödtexten.
  • Steg 3: Skapa ett anonymt block för att anropa SUB-typen.

Steg 1) Skapa SUPER-typ eller föräldertyp.

Skärmdumpen nedan visar supertypen emp_object som skapas med NOT FINAL-klausulen.

Skapa supertypen emp_object NOT FINAL för arvsexemplet

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 Förklaring:

  • Code rad 1-9: Skapar objekttypen 'emp_object' med 4 attribut och 3 medlemmar. Den innehåller definitionen av en konstruktor med endast 3 parametrar. Den har deklarerats som 'NOT FINAL', så det är en föräldertyp.

Steg 2) Skapa SUB-typen under SUPER-typen.

Skärmdumpen nedan visar den ärvda typen sub_emp_object och dess brödtext som skapas.

Skapa den ärvda typen sub_emp_object och dess brödtext med insert_default_mgr

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 Förklaring:

  • Code rad 10-13: Skapar 'sub_emp_object' som den ärvda typen med ytterligare attributet 'default_manager' och en medlemsproceduredeklaration.
  • Code rad 14: Skapar brödtexten för den ärvda objekttypen.
  • Code rad 16-21: Definierar medlemsproceduren som infogar poster i tabellen 'emp' med värdena från SUPER-objekttypen, förutom värdet manager. För värdet manager används 'default_manager' från SUB-typen.

Steg 3) Skapa anonymt block för att anropa SUB-typen.

Skärmdumpen nedan visar det anonyma blocket som anropar SUB-typen och infogar standardhanterar-ID:t.

Anonymt block som anropar typen sub_emp_object för att infoga ett standard-ID för chefer

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 Förklaring:

  • Code rad 25: Deklarerar 'guru_emp_det' som typen 'sub_emp_object'.
  • Code rad 27: Initierar objektet med den implicita konstruktorn. Konstruktorn har 5 parametrar (4 attribut från PARENT-typen och 1 attribut från SUB-typen). Den sista parametern (1002) definierar värdet för default_manager-attributet.
  • Code rad 28: Anropar medlemmen 'insert_default_mgr' för att infoga posten med standardhanterar-ID:t som angetts i konstruktorn.

Likhet mellan PL/SQL-objekt

Objektinstanser som tillhör samma objekttyp kan jämföras för att säkerställa likhet. För att göra detta behöver objekttypen en speciell metod som kallas ORDER-metoden.

Denna ORDER-metod ska vara en funktion som returnerar en numerisk typ. Den tar två parametrar som indata (första parametern: id:t för self-object-instansen; andra parametern: id:t för en annan objektinstans).

ID:n för de två objektinstanserna jämförs och resultatet returneras som ett tal.

  • Ett positivt värde indikerar att SELF-objektinstansen är större än den andra instansen.
  • Ett negativt värde indikerar att SELF-objektinstansen är mindre än den andra instansen.
  • Noll indikerar att SELF-objektinstansen är lika med den andra instansen.
  • Om någon av instanserna är null returnerar funktionen null.

Skärmdumpen nedan visar syntaxen för ORDER-medlemsfunktionen som måste inkluderas i typtexten för likhetskontrollen.

ORDER medlemsfunktionssyntax som används för att jämföra objektinstanser för likhet

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;
  .
  .
);
/

Syntaxförklaring:

  • Syntaxen ovan visar ORDER-funktionen som måste inkluderas i typtexten för likhetskontrollen.
  • Parametern för denna funktion bör vara en instans av samma objekttyp.
  • Funktionen kan anropas som "obj_instance_1.match(obj_instance_2)", och detta uttryck returnerar det visade numeriska värdet, där obj_instance_1 och obj_instance_2 är instanser av objekttypen.

Exempel 1: I följande exempel jämför vi två objekt. Vi skapar två instanser och jämför attributet 'salary' mellan dem. Vi gör detta i två steg.

  • Steg 1: Skapa objekttypen och brödtexten.
  • Steg 2: Skapa det anonyma blocket för att jämföra objektinstanserna.

Steg 1) Skapa objekttypen och brödtexten.

Skärmbilderna nedan visar specifikationen emp_object_equality och dess brödtext, som definierar ORDER-funktionen som jämför attributet salary.

Skapa objekttypspecifikationen emp_object_equality med en ORDER-funktion Definiera typen emp_object_equality som jämför attributet 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 Förklaring:

  • Code rad 1-4: Skapar objekttypen 'emp_object_equality' med 1 attribut och 1 medlem.
  • Code rad 6-16: Definierar ORDER-funktionen som jämför attributet 'salary' för SELF-instansen och parameterinstansen. Den returnerar ett negativt värde om SELF-lönen är lägre, ett positivt värde om SELF-lönen är högre och 0 om lönerna är lika.

Code Produktion:

Typ skapad

Steg 2) Skapa det anonyma blocket för att jämföra objektinstanserna.

Skärmdumpen nedan visar det anonyma blocket som jämför två emp_object_equality-instanser efter lön.

Anonymt block som jämför två emp_object_equality-instanser efter lön

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;
/

Produktion

Salary of second instance is greater

Code Förklaring:

  • Code rad 20: Deklarerar 'l_obj_1' av typen 'emp_object_equality'.
  • Code rad 21: Deklarerar 'l_obj_2' av typen 'emp_object_equality'.
  • Code rad 23: Initierar 'l_obj_1' med lönevärdet '15000'.
  • Code rad 24: Initierar 'l_obj_2' med lönevärdet '17000'.
  • Code rad 25-33: Skriver ut meddelandet baserat på numret som returneras av ORDER-funktionen.

Vanliga frågor

En objekttyp modellerar en enda verklig enhet med attribut och metoder. samling — en VARRAY, kapslad tabell eller associativ array — innehåller många element av en datatyp. Objekttyper beskriver struktur och beteende, medan samlingar lagrar flera värden.

Båda jämför objektinstanser. En MAP-metod returnerar ett enda skalärt värde som Oracle använder för att sortera eller jämföra objekt, medan en ORDER-metod jämför två instanser direkt och returnerar ett negativt, noll eller positivt tal. En typ kan definiera det ena eller det andra, inte båda.

Ja. Du kan skapa en objekttabell där varje rad är en objektinstans, eller använda en objekttyp som datatyp för en tabellkolumn. Detta gör det möjligt Oracle spara strukturerade objekt direkt i databasen snarare än bara i minnet.

En INTE-INSTANTIERBAR typ kan inte skapa objekt direkt; den fungerar som en abstracbas som andra typer utökar. Kombinerat med NOT FINAL definierar den en supertyp vars subtyper tillhandahåller den konkreta implementeringen av dess deklarerade metoder.

Använd ALTER TYPE för att lägga till eller ta bort attribut och metoder, lägg till CASCADE för att uppdatera beroende objekt och använd DROP TYPE för att ta bort typen. En typ som fortfarande används av tabeller eller andra typer kan inte tas bort förrän dessa beroenden har hanterats först.

Fråga datalexikonvyerna USER_TYPES och ALL_TYPES efter typnamn, och USER_TYPE_ATTRS och USER_TYPE_METHODS efter deras attribut och metoder. Med dessa vyer kan du granska en befintlig objektmodell utan att läsa källkoden.

Ja. GitHub Copilot utkast CREATE TYPE-specifikationer, TYPE BODY-metoder, konstruktorer och ORDER-funktioner från en kommentar. RevVisa attributdatatyperna, konstruktorparametrarna och arvsklausulerna innan du distribuerar den genererade typen.

AI-assistenter analyserar dina tabeller och föreslår objekttyper och attributmappningpings och arvshierarkier. Denna granskning av maskininlärning flaggar redundanta attribut, saknade konstruktorer och alltför djupt arv innan objektmodellen når produktion, vilket förbättrar underhållsvänligheten.

Sammanfatta detta inlägg med: