uzdevuma nostādne: - datubaze.files.wordpress.com€¦ · web viewtālāk izveidosim tabulas...
TRANSCRIPT
Objektu sasaiste
Uzdevuma nostādne: ........................................................................................................................ 2 Objektu tipu definēšana ................................................................................................................... 3 Kolekcijas tipa izveidošana ............................................................................................................. 6 Objektu tabulas izveidošana .......................................................................................................... 11 Datu ievade .................................................................................................................................... 13 Saites izveidošana .......................................................................................................................... 17 Vaicājumi....................................................................................................................................... 21
- 1 -
Uzdevuma nostādne:
1. Izveidot datu bāzi, kas satur 5 objektus.2. Izveidot saites (relations) starp objektiem, lai izveidotu šādu struktūru:
3. Uzrakstīt vaicājumus un PL\SQL procedūras datu ievadei un saites izveidošanai.4. Uzraksit vaicājumus, lai dabūtu datus no visas objekta hierarhijas līmeņiem, lietojot
saites starp objektiem.
- 2 -
1. hierarhijas līmenis
2. hierarhijas līmenis
3. hierarhijas līmenis
- 3 -
Objektu tipu definēšana
Vispirms izveidosim tipus Stradnieks un Kontakttalrunis, jo tie ir zemākā līmeņa objekti (nesatur
atsauces (references) uz citus objektus – nav atkarīgi no tiem).
1) Objekta tipa „Stradnieks” izveidošana:
CREATE OR REPLACE TYPE Stradnieks AS OBJECT( Vards VARCHAR2(20), Uzvards VARCHAR2(20), Pers_Kods VARCHAR2(12), Amats VARCHAR2(20), Alga NUMBER);
Rezultāts:
zim. 1 Izveidots objektu tips "Stradnieki"
- 4 -
2) Objekta tipa „Kontakttalrunis” izveidošana:
CREATE OR REPLACETYPE Kontakttalrunis AS OBJECT ( Numurs NUMBER(12), Tips Varchar2(20));
Rezultāts:
zim. 1 Izveidots objektu tips "Kontakttalrunis"
Tālāk izveidosim tabulas (kolekcijas) tipus REF_KontaktTalrunis un REF_Stradnieks. Šī tipi būs
lietoti attiecīgi Galvenais_arsts un Nodalas objektos, lai glabāt atsauces uz attiecīga tipa
objektiem (Kontakttalrunis un Stradnieks, respektīvi ). Tas ir nepieciešams, lai realizēt 1:N
relāciju starp objektiem Galvenais_arsts -> Kontakttalrunis un Nodala -> Stradnieks. Šo
struktūru varam attēlot sekojoši:
zim. 1 1:N relācijas shēma
- 5 -
Kolekcijas tipa izveidošana
1) Izveidosim kolekcijas tipu REF_KontaktTalrunis:
CREATE OR REPLACETYPE REF_KONTAKTTALRUNIS AS TABLE OF REF KontaktTalrunis; /
2) Izveidosim kolekcijas tipu REF_Stradnieks:
CREATE OR REPLACETYPE REF_STRADNIEKS AS TABLE OF REF Stradnieks; /
Rezultāts:
zim. 1 Izveidotie kolekcijas tipi
- 6 -
Tagad ir iespējams izveidot objektu tipus no 2 hierarhijas līmeņa (Nodala un Galvenais_arsts).
1) Objekta tipa „Nodala” izveidošana:CREATE OR REPLACETYPE OBJRELUZDUSER.NODALA AS OBJECT( Nosaukums VARCHAR2(20), Max_Ietilipba NUMBER, Personals REF_Stradnieks);
Varam redzēt, ka šīs objektu tips satur sev iekšā kolekciju REF_Stradnieki, kur tiek glabāti
atsauces uz Stradnieks tipa objektiem.
Rezultāts:
zim. 1 Izveidotais objektu tips "Nodala"
- 7 -
2) Objekta tipa „Galvenais_arsts” izveidošana:
CREATE OR REPLACETYPE Galvenais_arsts AS OBJECT( Vards VARCHAR2(20), Uzvards VARCHAR2(20), Pers_Kods NUMBER(12), Adrese VARCHAR2(20), Izglitba VARCHAR2(20), Kontakttalruni REF_Kontakttalrunis);
Rezultāts:
zim. 1 Izveidotais objektu tips "Galvenais_arsts"
- 8 -
Tā kā starp objektiem Slimnīca un Galvenais_ārsts ir saite 1:1, nav nepieciešams izvedot jaunu
kolekcijas tipu. Bet starp objektiem Slimnica un Nodala eksistē 1:N saite. Tāpēc vajag izveidot
vēl vienu kolekcijas tipu – REF_Nodala.
1) Kolekcijas tipa REF_Nodala izveidošana:
CREATE OR REPLACETYPE REF_NODALA AS TABLE OF REF Nodala; /
Rezultāts:
zim. 1 Izveidots kolekcijas tips "REF_Nodala"
- 9 -
Tagad ir iespējams izveidot objekta tipu „Slimnica”:
1) Objekta tipa „Slimnica” izveidošana:
CREATE OR REPLACETYPE Slimnica AS OBJECT( Nosaukums VARCHAR2(20), Pilseta VARCHAR2(20), Adrese VARCHAR(20), G_Arsts REF Galvenais_Arsts, Nodalas REF_Nodala); /
Rezultāts:
zim. 1 Izveidots objektu tips "Slimnica"
- 10 -
Objektu tabulas izveidošana
Tabulas ir nepieciešamas, lai glabāt objektu tipa eksemplārus (objektus). Katrai rindai tabulā
atbilst viens objekta eksemplārs. Tabulas, kuri satur atsauces (references) kolekcijas būs realizēti
kā iekļautas tabulas (Nested tabeles).
1) Izveidosim tabulas Tab_Strad un Tab_Talr kuri satur attiecīgu objektus „Stradnieks” un
„Kontaktalrunis”
CREATE TABLE Tab_Strad of Stradnieks;
CREATE TABLE Tab_Talr of Kontakttalrunis;
2) Izveidosim tabulas Tab_Nodala un Tab_GalvArsts. Tā kā starp objektiem Nodala ->
Stradnieks un Galvenais_Arsts -> Kontakttalrunius ir saite 1:N, tabulām, kuri satur šos
objektus vajag to korekti attēlot. Mūsu gadījumā lietosim iekļautas tabulas (nested
tables).
CREATE TABLE Tab_Nodala OF Nodala NESTED TABLE PERSONALS STORE AS REFSTR;
CREATE TABLE Tab_GalvArsts OF Galvenais_ArstsNESTED TABLE KONTAKTTALRUNI STORE AS REFKT;
Ar rindu NSETED TABLE mēs nosākam, ka tabulas Tab_Nodala/Tab_GalvArsts lauks
Personals/KontaktTalrunis ir iekļauta tabula un glabāta datubāzē ar nosaukumu
REFSTR/REFKT.
- 11 -
3) Izveidosim tābulu Tab_Slim, kura glabās Slimnuca objektu eksemplārus.
CREATE TABLE Tab_Slimnica OF Slimnica NESTED TABLE Nodalas STORE AS REFNOD;
Rezultāts:
zim. 1 Izveidotas objektu tabulas
- 12 -
Datu ievade
1) Datu ievade tabulā Tab_Strad:
BEGININSERT INTO TAB_STRADVALUES (STRADNIEKS('Ilja','Korneckis','040988-10615', 'Nodalas vaditajs', 500 )); INSERT INTO TAB_STRADVALUES (STRADNIEKS('Mihails','Pudzhs','150186-10573', 'Dakteris', 350 ));
INSERT INTO TAB_STRADVALUES (STRADNIEKS('Dmitrijs','Osipovs','051085-10415', 'Dakteris', 350 ));
INSERT INTO TAB_STRADVALUES (STRADNIEKS('Kirills','Dzhuvaga','230786-10560', 'Nodalas vaditajs', 550 ));
END;/
Rezultāts:
zim. 1 Tabulas "Tab_Strad" saturs
2) Datu ievade tabulā Tab_Talr:
BEGININSERT INTO TAB_TALR VALUES (KONTAKTTALRUNIS(7675060,'Majas'));INSERT INTO TAB_TALR VALUES (KONTAKTTALRUNIS(7603457,'Darba'));INSERT INTO TAB_TALR VALUES (KONTAKTTALRUNIS(29656101,'Mobilais')); INSERT INTO TAB_TALR VALUES (KONTAKTTALRUNIS(7622536,'Majas'));INSERT INTO TAB_TALR VALUES (KONTAKTTALRUNIS(7388543,'Darba'));INSERT INTO TAB_TALR VALUES (KONTAKTTALRUNIS(29915692,'Mobilais'));END;/
Rezultāts:
- 13 -
zim. 1 Tabulas "Tab_Talr" saturs
- 14 -
3) Datu ievade tabulā Tab_GalvArsts:
BEGIN INSERT INTO TAB_GALVARSTS VALUES (GALVENAIS_ARSTS('Vasilijs', 'Petrovichs', 5085410100,'Ozolciema 30/5 301','Pabeigta augstaka',REF_KontaktTalrunis(NULL))); INSERT INTO TAB_GALVARSTS VALUES (GALVENAIS_ARSTS('Janis', 'Ozols', 05184714120,'Graudu 10','Pabeigta augstaka',REF_KontaktTalrunis(NULL))); END;/
Saites starp „Galvenais_Arsts” un „KontaktTalrunis”, ka arī citas saites, būs izveidoti pēc visas
citas datu ievadīšanas. Pagaidām, atsauces kolekcija KontaktTalruni ir tukša (NULL).
Rezultāts:
zim. 1 Tabulas "Tab_GalvArsts" saturs
4) Datu ievade tabulā Tab_Nodala:
BEGIN INSERT INTO TAB_NODALA VALUES (NODALA('Kardiologija', 100, REF_STRADNIEKS(NULL))); INSERT INTO TAB_NODALA VALUES (NODALA('Neurologija', 50, REF_STRADNIEKS(NULL)));
END;/
Rezultāts:
zim. 1 Tabulas "Tab_Nodala" saturs
- 15 -
5) Datu ievade tabulā Tab_Slimnica
BEGININSERT INTO TAB_SLIMNICAVALUES (SLIMNICA('Stradina slimnica', 'Riga', 'Marupes iela 32',NULL, REF_NODALA(NULL) ) );
INSERT INTO TAB_SLIMNICAVALUES (SLIMNICA('Bernu slimnica', 'Riga', 'Vienibas gatve 25',NULL, REF_NODALA(NULL) ) );
END;/
Rezultāts:
zim. 1 Tabula "Tab_Slimnica" saturs
- 16 -
Saites izveidošana
1) „Galvenais_arsts” -> „KontaktTalrunis” saites izveidošana. Lai izveidot atsauces
kolekciju (REF_KontaktTalrunis tipa kolekcija) lietosim funkciju REF(), lai dabūt
atsauci uz KontaktTalrunis tipa objektu(no tabulas Tab_Talr) un kolekcijas
REF_KontaktTalrunis metodi EXTEND, kas pievieno kolekcijai vienu tukšu (Null)
elementu.
DECLARE ref1 REF KontaktTalrunis; col1 REF_KontaktTalrunis := REF_KontaktTalrunis(); col2 REF_KontaktTalrunis := REF_KontaktTalrunis();BEGIN SELECT REF(t) INTO ref1 FROM TAB_Talr t WHERE t.NUMURS = 7675060; col1.EXTEND; col1(1) := ref1; SELECT REF(t) INTO ref1 FROM TAB_Talr t WHERE t.NUMURS = 7603457; col1.EXTEND; col1(2) := ref1; SELECT REF(t) INTO ref1 FROM TAB_Talr t WHERE t.NUMURS = 29656101; col1.EXTEND; col1(3) := ref1; SELECT REF(t) INTO ref1 FROM TAB_Talr t WHERE t.NUMURS = 7622536; col2.EXTEND; col2(1) := ref1; SELECT REF(t) INTO ref1 FROM TAB_Talr t WHERE t.NUMURS = 7388543; col2.EXTEND; col2(2) := ref1; SELECT REF(t) INTO ref1 FROM TAB_Talr t WHERE t.NUMURS = 29915692; col2.EXTEND; col2(3) := ref1; UPDATE Tab_GalvArsts t SET t.KONTAKTTALRUNI = col1 WHERE t.PERS_KODS = 5085410100; UPDATE Tab_GalvArsts t SET t.KONTAKTTALRUNI = col2 WHERE t.PERS_KODS = 5184714120;
END;
- 17 -
/
- 18 -
2) „Nodala” -> „Stradnieks” saites izveidošana:
DECLARE ref1 REF Stradnieks; col1 REF_Stradnieks := REF_Stradnieks(); col2 REF_Stradnieks := REF_Stradnieks();BEGIN SELECT REF(t) INTO ref1 FROM TAB_Strad t WHERE t.PERS_KODS = '040988-10615'; col1.EXTEND; col1(1) := ref1; SELECT REF(t) INTO ref1 FROM TAB_Strad t WHERE t.PERS_KODS = '150186-10573'; col1.EXTEND; col1(2) := ref1; SELECT REF(t) INTO ref1 FROM TAB_Strad t WHERE t.PERS_KODS = '230786-10560'; col2.EXTEND; col2(1) := ref1; SELECT REF(t) INTO ref1 FROM TAB_Strad t WHERE t.PERS_KODS = '051085-10415'; col2.EXTEND; col2(2) := ref1; UPDATE Tab_Nodala t SET t.PERSONALS = col1 WHERE t.NOSAUKUMS = 'Kardiologija'; UPDATE Tab_Nodala t SET t.PERSONALS = col2 WHERE t.NOSAUKUMS = 'Neurologija';
END;/
- 19 -
3) Saites “Slimnica” -> “Nodala” izveidošana:
DECLARE ref1 REF Nodala; col1 REF_Nodala := REF_Nodala(); col2 REF_Nodala := REF_Nodala();
BEGIN SELECT REF(t) INTO ref1 FROM TAB_Nodala t WHERE t.NOSAUKUMS = 'Kardiologija'; col1.EXTEND; col1(1) := ref1; SELECT REF(t) INTO ref1 FROM TAB_Nodala t WHERE t.NOSAUKUMS = 'Neurologija'; col2.EXTEND; col2(1) := ref1; UPDATE Tab_Slimnica t SET t.NODALAS = col1 WHERE t.NOSAUKUMS = 'Stradina slimnica'; UPDATE Tab_Slimnica t SET t.NODALAS = col2 WHERE t.NOSAUKUMS = 'Bernu slimnica';
END;/
4) Saites „Slimnica” -> „Galvenais_Arsts” izveidošana. Šī saite ir 1:1, tāpēc nav
nepieciešams izveidot iekļautas tabulas ar atsaucam. Vajag vienkārši dabūt atsauci uz
objektu (ar REF() funkcijas palīdzības) un piešķirt to Slimnicas objekta G_Arsts laukam.
DECLARE ref1 REF Galvenais_Arsts;BEGIN SELECT REF(t) INTO ref1 FROM Tab_GalvArsts t WHERE t.PERS_KODS = 5085410100; UPDATE Tab_Slimnica t SET t.G_ARSTS = ref1 WHERE t.NOSAUKUMS = 'Stradina slimnica'; SELECT REF(t) INTO ref1 FROM Tab_GalvArsts t WHERE t.PERS_KODS = 5184714120; UPDATE Tab_Slimnica t SET t.G_ARSTS = ref1 WHERE t.NOSAUKUMS = 'Bernu slimnica'; END;
/
Visas saites ir izveidotas. Ir iespējams taisīt vaicājumus.
- 20 -
Vaicājumi
1) Bet, lai lietot izveidotus objektu saites, vajag pielietot dažus funkcijas. Izveidosim
vaicājumu, lai dabūt Stradiņa slimnīcas galvenā ārsta vārdu un uzvārdu (lietosim 1:1 saiti
starp objektiem Slimnica un Galvenais_Arsts):
SELECT DEREF(t.G_ARSTS).Vards ref_vards, DEREF(t.G_ARSTS).Uzvards ref_uzvards
FROM Tab_Slimnica tWHERE t.NOSAUKUMS = 'Stradina slimnica';
Rezultāts:
Tā kā tabulas Tab_Slimnica lauks G_ARSTS satur atsauci uz objektu ar tipu
Galvenais_Arsts nav iespējas tieši saņemt informāciju par galveņu ārsti. Tāpēc mēs
lietojam funkciju DEREF(). Funkcija DEREF saņem, ka parametru, lauku nosaukumu,
kur glabās atsauce un atgriež pašu objektu, uz kuru norāda atsauce.
2) 1:N saitēs gadījumā, atsauces glābās kolekcijas. Izveidosim vaicājumu, kura atgriež Jāņa
Ozola mobilo kontaktu tālruņi (lietosim saiti 1:N starp objektam Galvenais_Arsts un
KontaktTalrunis):
SELECT DEREF(VALUE(p)).NUMURS FROM Tab_GalvArsts a, TABLE(a.KONTAKTTALRUNI) pWHERE a.VARDS = 'Janis' AND a.UZVARDS = 'Ozols' AND DEREF(VALUE(p)).TIPS = 'Mobilais';
Rezultāts:
Funkcija TABLE() saņem, ka parametru, lauka nosaukumu, kur glabās kolekcija
(atsauces kolekcija mūsu gadījumā) un atgriež to tabulas veidā (tas nozīme, ka ar
rezultātu var strādāt, ka ar parastu tabulu).
Funkcija VALUE() saņem objekta tabulas nosaukumu (kolekcijas neder, tāpēc mēs arī
lietojam TABLE() funkciju) un atgriež objektu eksemplārus, atbilstoši tabulas rindām.
Tāpēc kopēja secība ir šāda: Funkcija TABLE izveido tabulu no kolekcijas ar atsaucam,
funkcija VALUE atgriež atsauces atbilstoši izveidotas tabulas rindām un funkcija
DEREF, lietojot šos atsauces, atgriež attiecīgus objektus.
- 21 -
3) Izveidosim vaicājumu, lai dabūt visus strādnieku vārdus, uzvārdus un pers. kodus no
Stradiņa slimnīcas kardioloģijas nodaļas:
SELECT DEREF(VALUE(t2)).VARDS Vards, DEREF(VALUE(t2)).UZVARDS Uzvards, DEREF(VALUE(t2)).PERS_KODS Pers_KodsFROM TABLE (SELECT DEREF(VALUE(t1)).PERSONALS FROM Tab_Slimnica t, TABLE(t.NODALAS) t1 WHERE t.NOSAUKUMS = 'Stradina slimnica' AND DEREF(VALUE(t1)).NOSAUKUMS = 'Kardiologija') t2;
Rezultāts:
Šis vaicājums ar apakš vaicājumu FROM vietā lieto visus iepriekšminētos funkcijas, lai
paradīt, ka var dabūt datus no tabulas, sekojot līdz atsaucam. Ka varam redzēt, šajā
vaicājuma ir minēts tikai viens tabula nosaukums (Tab_Slimnica), bet dati tiek paņemti
no tabulas Tab_Stradnieki (1. un 3. hierarhijas līmeni attiecīgi).
4) Atsauces neseko objekta stavokļam. Tas nozīme, ja objekts, uz kuru norāde atsauce, ir
izdzēsts, atsauce turpinās noradīt uz to objektu. Tas var izsaukt daudz kļūdas. Tāpēc
eksistē funkcija DANGLING, kura pārbaude atsaucēs pareizību. Uzrakstīsim UPDATE
tipa vaicājumu, kas aizvieto visus atsauces Slimnica tabula G_Arsts kolonnā ar NULL:
UPDATE Tab_Slimnica SET G_ARSTS = NULL WHERE G_ARSTS IS DANGLING;
Tālāk izveidosim vaicājumu, kura atgriež galvenā ārsta (no visas slimnīcas) vardu un
uzvārdu ar viņam attiecīgu mobila tālruņa numuru. Atsauces uz KontaktTalruņa tipa
objektiem tiek pārbaudītu ar funkciju NOT DANGLING:
SELECT t1.vards, t1.uzvards, DEREF(VALUE(t2)).NumursFROM TAB_GalvArsts t1, TABLE(t1.KONTAKTTALRUNI) t2WHERE VALUE(t2) IS NOT DANGLING AND DEREF(VALUE(t2)).Tips = 'Mobilais';
Rezultāts:
- 22 -
- 23 -
5) Izveidosim vaicājumu, lai dabūt visus strādniekus, kuriem galvenais ārsts ir Janis Ozols:
SELECT DEREF(VALUE(Nod)).VardsFROM TABLE ( (SELECT DEREF(VALUE(t2)).Personals FROM TAB_Slimnica t1, TABLE(t1.Nodalas) t2 WHERE t1.NOSAUKUMS = (SELECT t3.Nosaukums FROM TAB_Slimnica t3 WHERE DEREF(t3.G_Arsts).Vards = 'Janis' AND DEREF(t3.G_Arsts).Uzvards = 'Ozols' )
))Nod;
Rezultāts:
6) Lai uzzināt, cik daudz cilvēkus strādā Kardioloģijas nodaļā (jebkurā slimnīcā), izveidosim vaicājumu:
SELECT t1.Nosaukums, count(DEREF(VALUE(t2))) FROM Tab_Nodala t1, TABLE(t1.PERSONALS) t2 WHERE t1.NOSAUKUMS = 'Kardiologija'
GROUP BY t1.Nosaukums; Rezultāts:
7) Nākošais vaicājums izvada Slimnīcas nosaukumu, kur strādā Iļja Korņeckis:
SELECT t4.NosaukumsFROM TAB_Slimnica t4, TABLE(t4.Nodalas) t5WHERE DEREF(VALUE(t5)).Nosaukums = (SELECT t2.Nosaukums FROM TAB_Nodala t2, TABLE (t2.PERSONALS) t3 WHERE DEREF(VALUE(t3)).Uzvards =
(SELECT t1.Uzvards FROM TAB_Strad t1 WHERE t1.Uzvards = 'Korneckis' )
);Rezultāts:
- 24 -