Download as doc, pdf, or txt
Download as doc, pdf, or txt
You are on page 1of 8

Hoofdstuk 4: Collections vervolg

TI2 Stored Procedures

Hoofdstuk 4 (vervolg Collections):


nested tables en varrays
1 Samenvatting boek
Nested tables en varrays
Tot de collections behoren naast de associatieve arrays ook nog nested tables en varrays.
Nested tables en varrays kunnen in tegenstelling tot associatieve arrays als objecten in de
database gedefinieerd worden. Daarna kan men in eender welk programma variabelen
declareren met als datatype de structuur van de nested tabel of varray.
Men kan bij nested tables en varrays als zelfstandige objecten de structuur van de nested table
of varray ook gebruiken als datatype bij het definiren van kolommen in database tabellen.
Nested tables en varrays kunnen net als associatieve arrays via een SELECT BULK
COLLECT INTO gevuld worden met waarden.
Het opvullen met waarden via het toekenningsteken (:=) verloopt bij nested tables en varrays op
een complexere manier dan bij associatieve arrays.
Nested table (declaratie in een PL/SQL programma):
(in dat geval verschilt de nested table niet van de associatieve array)
TYPE naam_type
IS TABLE OF datatype;
Nested table als zelfstandig object in de database:
CREATE TYPE naam_type
AS TABLE OF datatype;
Een nested table kan een onbeperkt aantal elementen bevatten
Varray (declaratie in een PL/SQL programma):
TYPE naam_type
IS VARRAY (n) OF datatype;
Varray als zelfstandig object in de database:
CREATE TYPE naam_type
IS VARRAY (n) OF datatype;
Een varray kan slechts een beperkt aantal (=n) elementen bevatten.
(reden: ongebreidelde groei bij collections vermijden)
Datatype kan enkelvoudig of samengesteld zijn. Het kan ook een collection zijn.
Stored Procedures

Hoofdstuk 4: Collections vervolg

57

Vb1:
CREATE TYPE type_nested_mnr
IS TABLE OF NUMBER;
CREATE OR REPLACE PROCEDURE vb_nested_table
IS
t_med
type_nested_mnr;
BEGIN
SELECT mnr BULK COLLECT INTO t_med
FROM medewerkers
WHERE afd=10
ORDER BY gbdatum ASC;
FOR i IN 1..t_med.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE(t_med(i));
END LOOP;
END vb_nested_table;
Vb2
CREATE TYPE type_varray_mnr
IS VARRAY (3) OF NUMBER;
CREATE OR REPLACE PROCEDURE vb_varray
AS
t_med type_varray_mnr;
BEGIN
SELECT mnr BULK COLLECT INTO t_med
FROM medewerkers
WHERE afd=30
ORDER BY gbdatum DESC;
FOR i IN 1..t_med.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE (t_med(i));
END LOOP;
END vb_varray;
geeft een ERROR omdat de varray slechts 3 elementen kan bevatten en er meer dan 3
medewerkers in afdeling 30 zitten
Het initialiseren van een varray of een nested tabel via het toekenningsteken is complexer dan bij
associatieve arrays.
Vb 3

Stored Procedures

Hoofdstuk 4: Collections vervolg

58

CREATE OR REPLACE PROCEDURE toekennen_waarden


AS
TYPE type_coll_procent
IS VARRAY (4) OF NUMBER;
t_procent
type_coll_procent;
BEGIN
t_procent:=type_coll_procent(); een constructor (*)
t_procent.extend(4); er moet ruimte gecreerd worden voor de 4 elementen
t_procent(1):= 5;
t_procent(2):=10;
t_procent(3):=15;
t_procent(4):=20;
END toekennen_waarden;
(*) een constructor is een functie die de naam krijgt van het datatype van de variabele
waarop hij wordt toegepast.

Collections en DML
Hoe kunnen collections ingezet worden bij het doorvoeren van wijzigingen in de tabellen van de
database?
En van de beperkingen van SQL is dat rijen uit een tabel door een SELECT of een
DML instructie steeds in willekeurige volgorde zullen uitgevoerd worden.
De vraag, geef de 10 oudste medewerkers een loonsverhoging van 10% kan binnen
SQL niet opgelost worden omdat bij deze update de volgorde van de rijen een rol speelt.
We lossen dit probleem op gebruik makend van collections (of cursors zie verder).
CREATE OR REPLACE PROCEDURE vb_rij_per_rij_verwerking
AS
TYPE type_coll_med
IS TABLE OF medewerkers.mnr%TYPE;
t_med type_coll_med;
BEGIN
SELECT mnr BULK COLLECT INTO t_med
FROM medewerkers
ORDER BY gbdatum ASC
we sorteren van oud naar jong
FOR UPDATE;
FOR i IN 1..10
we nemen er de 10 eersten uit
LOOP
UPDATE medewerkers
SET maandsal=maandsal*1.1
WHERE mnr=t_med(i);
END LOOP;
COMMIT;
END vb_rij_per_rij_verwerking;
Bemerking: we veronderstellen hierbij dat alle medewerkers een verschillende leeftijd hebben.
Als er medewerkers zijn met eenzelfde leeftijd, wordt de oplossing complexer!
Stored Procedures

Hoofdstuk 4: Collections vervolg

59

Probleem:
Een PL/SQL programma bevat PL statements en SQL statements. Om deze statements te kunnen
verwerken zijn er 2 soorten ENGINES nodig (n voor de PL statements en n voor de SQL
statements). Omdat in een PL/SQL programma beide soorten statements aanwezig zijn moet er
regelmatig van engine gewisseld worden.
Dit noemt men contextswitches. Ze wegen op de performantie.
Om het aantal contextswitches drastisch te verlagen kan gebruik gemaakt worden van het BULK
DML mechanisme.

FORALL index IN INDICES OF collectionvariabele


[BETWEEN ondergrens AND bovengrens]
dml statement
Via een select ..bulk collect into worden de aan te passen rijen in een collection geplaatst.
De wijzigingen gebeuren in de collection.
Daarna worden de gewijzigde rijen via bulk DML (FORALL ..) in 1 update op de tabel
doorgevoerd.
We herschrijven nu voorgaande procedure gebruik makend van bulk DML:
CREATE OR REPLACE PROCEDURE vb_rij_per_rij_verwerking
AS
TYPE type_coll_med
IS TABLE OF medewerkers%ROWTYPE;
t_med type_coll_med;
BEGIN
SELECT * BULK COLLECT INTO t_med
FROM medewerkers
ORDER BY gbdatum ASC
FOR UPDATE;
FOR i IN 1..10
LOOP
we voeren de wijziging door in de
t_med(i).maandsal:=t_med(i).maandsal*1.10;
collection zelf!
END LOOP;
FORALL i IN INDICES OF t_med
BETWEEN 1 AND 10
UPDATE medewerkers
SET maandsal= t_med(i).maandsal
WHERE mnr=t_med(i).mnr;
COMMIT;
END vb_rij_per_rij_verwerking;

in 1 bulk operatie worden alle rijen


aangepast in de tabel MEDEWERKERS
=> er is slechts 1 contextswitch

Het cursorattribuut %BULK_ROWCOUNT(parameter)


Gewone DML opdrachten kunnen we gebruik maken van de cursorattributen SQL
%ROWCOUNT, SQL%FOUND en SQL%NOTFOUND.
Om te weten te komen hoeveel rijen er bij elke record uit de collection in tabellen aangepast zijn
ten gevolge van BULK DML kunnen we gebruik maken van het cursorattribuut
%BULK_ROWCOUNT.
Stored Procedures

Hoofdstuk 4: Collections vervolg

60

Voorbeeld:
Medewerkers die als chef 7566,7698,of 1 hebben krijgen een salarisverhoging.
CREATE OR REPLACE PROCEDURE salarisverhoging
AS
TYPE type_tab_chef IS TABLE OF medewerkers.chef%TYPE
INDEX BY PLS_INTEGER;
t_chef type_tab_chef;
BEGIN
t_chef(1):=7566;
t_chef(2):=7698;
t_chef(3):=1;
FORALL i IN INDICES OF t_chef
UPDATE medewerkers
SET maandsal=maandsal*1.05
WHERE chef=t_chef(i);
FOR i IN 1..t_chef.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE('aantal verwerkte rijen voor '||t_chef(i)||' '||SQL
%BULK_ROWCOUNT(i));
END LOOP;
END;
Programma geeft hier als output:
aantal verwerkte rijen voor 7566 2
aantal verwerkte rijen voor 7698 5
aantal verwerkte rijen voor 1 0

2. Oefeningen op de cursussendatabase
Probeer eerst alle voorbeelden van de samenvatting uit !
Vraag 1
Maak een kopie van de tabel CURSUSSEN en noem deze tabel CURSUSSEN_BU.
De tabel CURSUSSEN_BU moet leeg zijn!
Schrijf nu een procedure die de inhoud van de tabel CURSUSSEN met een bulk operatie in een
collection variabele plaatst en daarna de inhoud van de collection variabele via bulk DML naar
de tabel CURSUSSEN_BU schrijft.
Vraag 2
Plaats cursus en begindatum van uitvoeringen waarvoor meer dan 4 inschrijvingen zijn in een
collection variabele. Gebruik deze lijst om in de tabel UITVOERINGEN de LOCATIE voor deze
cursusuitvoeringen te wijzigen in ANTWERPEN. Gebruik het bulk DML mechanisme.
Stored Procedures

Hoofdstuk 4: Collections vervolg

61

Stored Procedures

Hoofdstuk 4: Collections vervolg

62

3 Theorievragen
1.
2.
3.
4.

Welke essentile verschillen bestaan er tussen associatieve arrays, nested tables en varrays?
Waarom gebruik je voor collections die genitialiseerd moeten worden via het
toekenningsteken (:=) best een associatieve array?
Wat is het voordeel van een SELECT BULK COLLECT INTO?
Leg uit waarom BULK DML leidt tot performantieverbetering!

4 Projectopgaven
Zie BB stored procedures Lesmateriaal Lesweek1 Project 2

Stored Procedures

Hoofdstuk 4: Collections vervolg

63

You might also like