Oracle PL/SQL-objektityypit: CREATE TYPE esimerkkeineen
โก รlykรคs yhteenveto
PL/SQL:n objektityypit tuovat olio-ohjelmoinnin Oracle, joiden avulla voit mallintaa reaalimaailman entiteettejรค attribuuttien ja metodien avulla. Ne tukevat konstruktoreita, periytymistรค ja yhtรคlรคisyysvertailua, joten yksi skeematason tyyppi voi tallentaa ja kรคsitellรค strukturoitua dataa.

Mikรค on objektityyppi PL/SQL:ssรค?
Olio-ohjelmointi sopii erityisesti uudelleenkรคytettรคvien komponenttien ja monimutkaisten sovellusten rakentamiseen. Ohjelmat on jรคrjestetty "objektien" eikรค "toimintojen" ympรคrille; toisin sanoen ne on suunniteltu toimimaan ja olemaan vuorovaikutuksessa koko objektin kanssa yksittรคisen toiminnon sijaan. Tรคmรค lรคhestymistapa antaa ohjelmoijan tรคyttรครค ja kรคsitellรค tietoja objekti-yksikkรถtasolla.
Alla oleva kuva esittรครค esimerkkiรค objektityypistรค, jossa pankkitiliรค kรคsitellรครคn objektiyksikkรถnรค. Objektin attribuutit sisรคltรคvรคt arvoja โ pankkitilin tapauksessa nรคitรค ovat tilinumero, pankkisaldo ja niin edelleen โ kun taas objektin metodit kuvaavat toimintoja, kuten koron laskemista tai tiliotteen luomista, joista jokainen vaatii prosessin suorittamisen.
In PL / SQLOlio-ohjelmointi perustuu oliotyyppeihin. Oliotyyppi voi edustaa mitรค tahansa reaalimaailman oliota. Seuraavissa osioissa tarkastellaan oliotyyppejรค, niiden komponentteja sekรค niiden luomista ja kรคyttรถรค.
Objektityyppien komponentit
PL/SQL-objektityyppi sisรคltรครค pรครคasiassa kaksi komponenttia.
- Ominaisuudet
- Jรคsenet/menetelmรคt
Ominaisuudet
Mรครคritteet ovat sarakkeita tai kenttiรค, joihin tiedot tallennetaan. Jokainen mรครคrite on yhdistetty tietotyyppiin, joka mรครคrittรครค kyseisen mรครคritteen kรคsittely- ja tallennustyypin. Mรครคrite voi olla mikรค tahansa kelvollinen PL/SQL-tietotyyppi, tai se voi olla jotain muuta objektityyppiรค.
Jรคsenet/menetelmรคt
Jรคsenet eli metodit ovat aliohjelmia mรครคritelty objektityypin sisรคllรค. Niitรค ei kรคytetรค datan tallentamiseen; sen sijaan ne mรครคrittelevรคt objektityypin sisรคllรค suoritettavan prosessoinnin โ esimerkiksi datan validoinnin ennen objektin tรคyttรคmistรค. Ne esitellรครคn objektityypin mรครคrityksessรค ja mรครคritellรครคn objektityypin rungossa. Runko on valinnainen: jos jรคseniรค ei ole, objektityypillรค ei ole runko-osaa.
Luo objekti sisรครคn Oracle
Objektityyppiรค ei voida luoda aliohjelmatasolla; se voidaan luoda vain skeematasolla. Kun objektityyppi on mรครคritelty skeemassa, sitรค voidaan kรคyttรครค aliohjelmissa. Objektityyppi luodaan kรคyttรคmรคllรค "CREATE TYPE" -lauseketta, ja tyypin runko voidaan luoda vasta, kun sen objektityyppi on olemassa.
Alla olevat kuvakaappaukset nรคyttรคvรคt objektimรครคrityksen CREATE TYPE -syntaksin ja sen metodit mรครคrittelevรคn CREATE TYPE BODY -syntaksin.
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; . . ); /
Syntaksiselitys:
- Yllรค oleva syntaksi nรคyttรครค OBJECT-objektin luomisen attribuuteilla ja OBJECT BODY -objektin luomisen metodeilla.
- Menetelmรคt voivat myรถs ylikuormittua objektirungossa.
Ilmoitus objektityypin alustus
Kuten muutkin PL/SQL-komponentit, objektityypit on mรครคriteltรคvรค ennen kuin niitรค voidaan kรคyttรครค ohjelmassa. Kun objektityyppi on luotu, sitรค voidaan kรคyttรครค aliohjelman deklaratiivisessa osassa kyseisen objektityypin muuttujan mรครคrittรคmiseen.
Aina kun muuttuja deklaroidaan objektityypiksi, suorituksen aikana luodaan uusi objektityypin instanssi, ja tรคhรคn uuteen instanssiin viitataan muuttujan nimellรค. Tรคllรค tavoin yksi objektityyppi voi tallentaa useita arvoja eri instansseihin.
Alla olevassa kuvakaappauksessa nรคkyy muuttujan deklarointi objektityyppinรค objektin sisรคllรค. PL/SQL-lohko.
DECLARE <variable_name> <object_type_name>; BEGIN . . END; /
Syntaksiselitys:
- Yllรค oleva syntaksi nรคyttรครค a:n deklaroinnin muuttuja objektityyppinรค deklaratiivisessa osiossa.
Kun muuttuja on ilmoitettu oliotyypiksi aliohjelmassa, se on atomaarisesti null โ koko olio itsessรครคn on null. Se on alustettava arvoilla ennen kuin sitรค voidaan kรคyttรครค ohjelmassa. Oliot alustetaan konstruktorien avulla.
Konstruktorit ovat objektin implisiittisiรค metodeja, joihin voidaan viitata samalla nimellรค kuin objektityyppiin. Alla oleva kuvakaappaus nรคyttรครค objektityyppi-instanssin alustuksen.
DECLARE <variable_name> <object_type_name>; BEGIN <variable_name>:=<object_type_name>(); END; /
Syntaksiselitys:
- Yllรค oleva syntaksi nรคyttรครค objektityypin instanssin alustuksen null-arvolla.
- Itse objekti ei ole enรครค null alustuksen jรคlkeen, mutta objektin sisรคllรค olevat attribuutit pysyvรคt nullina, kunnes niille annetaan arvot.
Rakentajat
Konstruktorit ovat objektin implisiittisiรค metodeja, joihin voidaan viitata samalla nimellรค kuin objektityyppiin. Aina kun objektiin viitataan ensimmรคistรค kertaa, tรคtรค konstruktoria kutsutaan implisiittisesti.
Voit myรถs alustaa objekteja nรคiden konstruktorien avulla. Konstruktori voidaan mรครคritellรค eksplisiittisesti mรครคrittelemรคllรค objektityypin rungossa jรคsen, jolla on sama nimi kuin objektityypillรค.
Esimerkki 1: Seuraavassa esimerkissรค kรคytรคmme objektityyppistรค jรคsentรค lisรคtรคksemme emp-taulukkoon tietueita arvoilla ('RRR', 1005, 20000, 1000) ja ('PPP', 1006, 20000, 1001). Kun tiedot on lisรคtty, nรคytรคmme ne objektityyppisen jรคsenen avulla. Kรคytรคmme myรถs eksplisiittistรค konstruktoria tรคyttรครคksemme manageri-tunnuksen oletusarvolla 1001 toiselle tietueelle.
Toteutamme sen seuraavissa vaiheissa.
- Vaihe 1: Luo objektityyppi ja objektityypin runko.
- Vaihe 2: Luo anonyymi lohko kutsuaksesi objektityyppiรค implisiittisen konstruktorin kautta emp_no 1005:lle.
- Vaihe 3: Luo anonyymi lohko kutsuaksesi objektityyppiรค emp_no 1006:n eksplisiittisen konstruktorin kautta.
Vaihe 1) Luo objektityyppi ja objektityypin runko.
Alla olevassa kuvakaappauksessa nรคkyy emp_object-objektityypin mรครคrityksen luonti attribuuteineen ja jรคsenineen.
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); /
Alla olevassa kuvakaappauksessa nรคkyy emp_object-tyypin rungon luonti eksplisiittisellรค konstruktorilla ja jรคsenproseduureilla.
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 Selitys
- Code rivi 1โ9: Luodaan 'emp_object'-objektityyppi, jossa on neljรค attribuuttia ja kolme jรคsentรค. Se sisรคltรครค mรครคritelmรคn konstruktorista, jossa on vain kolme parametria. (Varsinainen implisiittinen konstruktori sisรคltรครค yhtรค monta parametria kuin objektityypissรค on attribuutteja.)
- Code rivi 10: Tyyppirungon luominen.
- Code rivi 11โ21: Eksplisiittisen konstruktorin mรครคrittely. Parametriarvojen mรครคritys attribuuteille ja oletusarvon '1001' mรครคritys attribuutille 'manager'.
- Code rivi 22โ26: Jรคsenen 'insert_records' mรครคrittely, jonka avulla attribuutin arvot lisรคtรครคn 'emp'-taulukkoon.
- Code rivi 27โ34: Jรคsenen 'display_records' mรครคrittely, joka nรคyttรครค objektityypin attribuuttien arvot.
lรคhtรถ:
Tyyppi luotu
Tyyppi runko luotu
Vaihe 2) Luodaan anonyymi lohko kutsumaan luotua objektityyppiรค implisiittisen konstruktorin kautta emp_no 1005:lle.
Alla olevassa kuvakaappauksessa nรคkyy anonyymi lohko, joka kutsuu emp_object-funktiota implisiittisen konstruktorin kautta.
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 Selitys
- Code rivi 37โ45: Tietueiden lisรครคminen implisiittistรค konstruktoria kรคyttรคen. Konstruktorin kutsu sisรคltรครค attribuuttiarvojen todellisen lukumรครคrรคn.
- Code rivi 38: Mรครคrittelee 'guru_emp_det':n objektityypiksi 'emp_object'.
- Code rivi 41: Lause 'guru_emp_det.display_records' kutsuu 'display_records'-jรคsentรค ja attribuutin arvot nรคytetรครคn.
- Code rivi 42: Lause 'guru_emp_det.insert_records' kutsuu 'insert_records'-jรคsentรค ja attribuutin arvot lisรคtรครคn taulukkoon. Lohko tekee sitten commitin kauppa.
lรคhtรถ:
Tyรถntekijรคn nimi: RRR
Tyรถntekijรคmรครคrรค: 1005
Palkka: 20000
Johtaja: 1000
Vaihe 3) Luodaan anonyymi lohko kutsumaan luotua objektityyppiรค eksplisiittisen konstruktorin kautta emp_no 1006:lle.
Alla olevassa kuvakaappauksessa nรคkyy anonyymi lohko, joka kutsuu emp_object-funktiota eksplisiittisen konstruktorin kautta kolmella argumentilla.
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; /
ulostulo
Employee Name:PPP Employee Number:1006 Salary:20000 Manager:1001
Code Selitys:
- Code rivi 46โ53: Tietueen lisรครคminen eksplisiittistรค konstruktoria kรคyttรคen.
- Code rivi 46: Mรครคrittelee 'guru_emp_det':n objektityypiksi 'emp_object'.
- Code rivi 50: Lause 'guru_emp_det.display_records' kutsuu 'display_records'-jรคsentรค ja attribuutin arvot nรคytetรครคn.
- Code rivi 51: Lause 'guru_emp_det.insert_records' kutsuu 'insert_records'-jรคsentรค ja attribuutin arvot lisรคtรครคn tauluun. Koska argumentteja annetaan vain kolme, eksplisiittinen konstruktori asettaa managerin tunnukseksi oletusarvon 1001.
Objektityypin periytyminen
Perintรคominaisuus sallii aliobjektityypin kรคyttรครค kaikkia pรครคobjektityypin tai pรครคobjektityypin attribuutteja ja jรคseniรค.
Aliobjektityyppiรค kutsutaan periytyneeksi objektityypiksi ja superobjektityyppiรค pรครคobjektityypiksi. Alla oleva syntaksi nรคyttรครค, kuinka pรครค- ja perityt objektityypit luodaan. Alla oleva kuvakaappaus nรคyttรครค pรครคtyypin (SUPER) syntaksin, joka on merkitty NOT FINAL -merkinnรคllรค.
CREATE TYPE <object_type_name_parent> AS OBJECT ( <attribute_l><datatype>, . . )NOT FINAL; /
Syntaksiselitys:
- Yllรค oleva syntaksi nรคyttรครค SUPER-tyypin luomisen. NOT FINAL -lause mahdollistaa tyypin periytymisen.
Alla olevassa kuvakaappauksessa nรคkyy UNDER-avainsanalla luotu peritty (SUB) -tyypin syntaksi.
CREATE TYPE<object_type_name_sub>UNDER<object_type_name_parent> ( <attribute_l><datatype>, . ); /
Syntaksiselitys:
- Yllรค oleva syntaksi nรคyttรครค SUB-tyypin luomisen. Se sisรคltรครค kaikki pรครคobjektityypin jรคsenet ja attribuutit.
Esimerkki 1: Alla olevassa esimerkissรค kรคytรคmme periytymisominaisuutta lisรคtรคksemme tietueen, jonka hallinnoijan tunnus on '1002', tietueelle ('RRR', 1007, 20000). Suoritamme ohjelman seuraavissa vaiheissa.
- Vaihe 1: Luo SUPER-tyyppi.
- Vaihe 2: Luo SUB-tyyppi ja runko.
- Vaihe 3: Luo anonyymi lohko SUB-tyypin kutsumiseksi.
Vaihe 1) Luo SUPER-tyyppi tai Parent-tyyppi.
Alla olevassa kuvakaappauksessa nรคkyy emp_object-supertyypin luonti NOT FINAL -lausekkeella.
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 Selitys:
- Code rivi 1โ9: Luodaan 'emp_object'-objektityyppi, jossa on neljรค attribuuttia ja kolme jรคsentรค. Se sisรคltรครค mรครคritelmรคn konstruktorista, jossa on vain kolme parametria. Se on deklaroitu muodossa 'NOT FINAL', joten se on pรครคtyyppi.
Vaihe 2) Luo SUB-tyyppi SUPER-tyypin alle.
Alla olevassa kuvakaappauksessa nรคkyy peritty sub_emp_object-tyyppi ja sen luotava runko.
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 Selitys:
- Code rivi 10โ13: Luodaan peritty tyyppi 'sub_emp_object' yhdellรค lisรคattribuutilla 'default_manager' ja jรคsenproseduurin mรครคrittelyllรค.
- Code rivi 14: Perityn objektityypin rungon luominen.
- Code rivi 16โ21: Mรครคritellรครคn jรคsenproseduuri, joka lisรครค tietueita 'emp'-taulukkoon SUPER-objektityypin arvoilla, lukuun ottamatta manager-arvoa. Manager-arvolle se kรคyttรครค SUB-tyypin 'default_manager'-arvoa.
Vaihe 3) Luodaan anonyymi lohko SUB-tyypin kutsumiseksi.
Alla olevassa kuvakaappauksessa nรคkyy anonyymi lohko, joka kutsuu SUB-tyyppiรค ja lisรครค oletusarvoisen manageri-tunnuksen.
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 Selitys:
- Code rivi 25: Mรครคritellรครคn 'guru_emp_det' tyypiksi 'sub_emp_object'.
- Code rivi 27: Objektin alustaminen implisiittisellรค konstruktorilla. Konstruktorilla on 5 parametria (4 PARENT-tyypin attribuuttia ja 1 SUB-tyypin attribuutti). Viimeinen parametri (1002) mรครคrittรครค default_manager-attribuutin arvon.
- Code rivi 28: Kutsutaan jรคsentรค 'insert_default_mgr' lisรครคmรครคn tietue, jonka konstruktorissa on annettu oletusarvoinen hallinnoijan tunnus.
PL/SQL-objektien tasa-arvo
Samaan objektityyppiin kuuluvia objekti-instansseja voidaan verrata yhtรคlรคisyyden varmistamiseksi. Tรคtรค varten objektityypille tarvitaan erityinen ORDER-metodi.
Tรคmรคn ORDER-metodin tulisi olla funktio, joka palauttaa numeerisen tyypin. Se ottaa syรถtteeksi kaksi parametria (ensimmรคinen parametri: itseobjekti-instanssin tunniste; toinen parametri: toisen objekti-instanssin tunniste).
Kahden objekti-instanssin tunnisteita verrataan ja tulos palautetaan numerona.
- Positiivinen arvo osoittaa, ettรค SELF-objekti-instanssi on suurempi kuin toinen instanssi.
- Negatiivinen arvo osoittaa, ettรค SELF-objekti-instanssi on pienempi kuin toinen instanssi.
- Nolla osoittaa, ettรค SELF-objekti-instanssi on yhtรค suuri kuin toinen instanssi.
- Jos jompikumpi instanssi on null, funktio palauttaa null-arvon.
Alla olevassa kuvakaappauksessa nรคkyy ORDER-jรคsenfunktion syntaksi, joka on sisรคllytettรคvรค tyyppirunkoon yhtรคsuuruustarkistusta varten.
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; . . ); /
Syntaksiselitys:
- Yllรค oleva syntaksi nรคyttรครค ORDER-funktion, joka on sisรคllytettรคvรค tyyppirunkoon yhtรคsuuruustarkistusta varten.
- Tรคmรคn funktion parametrin tulee olla saman objektityypin esiintymรค.
- Funktiota voidaan kutsua muodossa โobj_instance_1.match(obj_instance_2)โ, ja tรคmรค lauseke palauttaa nรคytetyn numeerisen arvon, jossa obj_instance_1 ja obj_instance_2 ovat objektityypin instansseja.
Esimerkki 1: Seuraavassa esimerkissรค vertaamme kahta oliota. Luomme kaksi instanssia ja vertaamme niiden 'salary'-attribuuttia. Teemme tรคmรคn kahdessa vaiheessa.
- Vaihe 1: Luo objektityyppi ja runko.
- Vaihe 2: Luo anonyymi lohko objekti-instanssien vertailemiseksi.
Vaihe 1) Objektityypin ja rungon luominen.
Alla olevat kuvakaappaukset nรคyttรคvรคt emp_object_equality-mรครคrityksen ja sen rungon, joka mรครคrittelee ORDER-funktion, joka vertailee salary-attribuuttia.
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 Selitys:
- Code rivi 1โ4: Luodaan 'emp_object_equality'-objektityyppi yhdellรค attribuutilla ja yhdellรค jรคsenellรค.
- Code rivi 6โ16: Mรครคritellรครคn ORDER-funktio, joka vertaa SELF-instanssin ja parametri-instanssin 'salary'-attribuuttia. Se palauttaa negatiivisen arvon, jos SELF-palkka on pienempi, positiivisen arvon, jos SELF-palkka on suurempi, ja 0, jos palkat ovat yhtรค suuret.
Code lรคhtรถ:
Tyyppi luotu
Vaihe 2) Anonyymin lohkon luominen objekti-instanssien vertailemiseksi.
Alla olevassa kuvakaappauksessa nรคkyy anonyymi lohko, joka vertaa kahta emp_object_equality-instanssia palkan mukaan.
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; /
ulostulo
Salary of second instance is greater
Code Selitys:
- Code rivi 20: Mรครคritellรครคn 'l_obj_1', jonka tyyppi on 'emp_object_equality'.
- Code rivi 21: Mรครคritellรครคn 'l_obj_2', jonka tyyppi on 'emp_object_equality'.
- Code rivi 23: Alustataan 'l_obj_1' palkka-arvolla '15000'.
- Code rivi 24: Alustataan 'l_obj_2' palkka-arvolla '17000'.
- Code rivi 25โ33: Viestin tulostaminen ORDER-funktion palauttaman luvun perusteella.


















