datubaze.files.wordpress.com  · web viewkursora izteiksme. kursora izteiksme, ko norāda cursor...

22
1 Kursora izteiksme Kursora izteiksme, ko norāda CURSOR operators, atgriež ligzdotu (nested) kursoru no vaicājuma. Katra rinda ligzdota kursora rezultātu kopā var saturēt parasto vērtību diapazonu, kas atļauts SQL vaicājumā. var saturēt arī citus kursorus, kas izveidoti ar apakšvaicājumiem. Kursora izteiksmes izmanto, lai atgrieztu lielu un sarežģītu saistīto vērtību kopu, kas izgūta no vienas vai vairākām tabulām. Pēc tam var apstrādāt kursora izteiksmes rezultātu kopu, izmantojot ligzdotās cilpas (nested loops), kas tiek ienestas no rezultātu kopas rindām, un pēc tam papildu rindas no visiem ligzdotajiem kursoriem šajās rindās. Kursora izteiksmes var būt sarežģītas, ņemot vērā, cik sarežģītas var būt vaicājumu un rezultātu kopas. Tomēr ir labi zināt visus iespējamos veidus, kā izgūt datus no Oracle datu bāzes. Kursora izteiksmes var izmantot jebkurā no šīm darbībām: 1) tiešās (explicit) kursora deklarācijās; 2) dinamiskos SQL vaicājumos; 3) REF CURSOR deklarācijās un mainīgajos. Nedrīkst izmantot kursora izteiksmi netiešā vaicājumā. Kursora izteiksmes sintakse ir ļoti vienkārša:

Upload: others

Post on 19-Jul-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: datubaze.files.wordpress.com  · Web viewKursora izteiksme. Kursora izteiksme, ko norāda CURSOR operators, atgriež. ligzdotu (nested) kursoru. no. vaicājuma. Katra rinda ligzdota

1

Kursora izteiksme

Kursora izteiksme, ko norāda CURSOR operators, atgriež ligzdotu (nested) kursoru no vaicājuma. Katra rinda ligzdota kursora rezultātu kopā var saturēt parasto vērtību diapazonu, kas atļauts SQL vaicājumā. Tā var saturēt arī citus kursorus, kas izveidoti ar apakšvaicājumiem.

Kursora izteiksmes izmanto, lai atgrieztu lielu un sarežģītu saistīto vērtību kopu, kas izgūta no vienas vai vairākām tabulām. Pēc tam var apstrādāt kursora izteiksmes rezultātu kopu, izmantojot ligzdotās cilpas (nested loops), kas tiek ienestas no rezultātu kopas rindām, un pēc tam papildu rindas no visiem ligzdotajiem kursoriem šajās rindās. Kursora izteiksmes var būt sarežģītas, ņemot vērā, cik sarežģītas var būt vaicājumu un rezultātu kopas. Tomēr ir labi zināt visus iespējamos veidus, kā izgūt datus no Oracle datu bāzes. Kursora izteiksmes var izmantot jebkurā no šīm darbībām:

1) tiešās (explicit) kursora deklarācijās;2) dinamiskos SQL vaicājumos;3) REF CURSOR deklarācijās un mainīgajos.

Nedrīkst izmantot kursora izteiksmi netiešā vaicājumā. Kursora izteiksmes sintakse ir ļoti vienkārša:

CURSOR (apakšvaicājums)

Datu bāze atver ligzdotu kursoru, kas definēts ar kursora izteiksmi, tiklīdz tas no vecākobjekta vai ārējā kursora izgūst rindu, kurā ir kursora izteiksme. Šis ligzdotais kursors ir aizvērts, ja:

1) jūs tieši aizverat kursoru;2) ārējais (augstākstāvošais) kursors tiek izpildīts vēlreiz, aizvērts vai

atcelts;3) ievešanas laikā no vecākkursora tiek pacelts izņēmums. Ligzdotais

kursors tiek aizvērts kopā ar augstākstāvošo kursoru.

Page 2: datubaze.files.wordpress.com  · Web viewKursora izteiksme. Kursora izteiksme, ko norāda CURSOR operators, atgriež. ligzdotu (nested) kursoru. no. vaicājuma. Katra rinda ligzdota

2

Tabulu FAKULTATES un STUDENTI izveidošana

create table FAKULTATES (F_NUM number Primary key,F_NOS varchar2(20));

begininsert into FAKULTATES values (1, 'Datorzinības');insert into FAKULTATES values (2, 'Elektronika');end;

create table STUDENTI (S_NUM number Primary key,UZV varchar2(20),KURSS number,NUM_F number);

begininsert into STUDENTI values (1001, 'Koks', 3, 1 );insert into STUDENTI values (1002, 'Celms', 2, 1 );insert into STUDENTI values (1003, 'Sakne', 1, 2 );insert into STUDENTI values (1004, 'Lapa', 3, 2 );end;

select F_NUM, F_NOS, S_NUM, UZV from FAKULTATES, STUDENTIwhere NUM_F = F_NUM;

Page 3: datubaze.files.wordpress.com  · Web viewKursora izteiksme. Kursora izteiksme, ko norāda CURSOR operators, atgriež. ligzdotu (nested) kursoru. no. vaicājuma. Katra rinda ligzdota

3

Apakšvaicājuma veidošana ar kursora izteiksmi

Kursora izteiksmes lietošana ir atļauta tikai augšējā SELECT līmenī!

select F_NUM, F_NOS, CURSOR (select S_NUM, UZV from STUDENTI where NUM_F = F_NUM) STUD_KURSORSfrom FAKULTATES;

select CURSOR(select S_NUM, UZV from STUDENTI where F_NUM =NUM_F) FAK_STUDfrom FAKULTATES;

Page 4: datubaze.files.wordpress.com  · Web viewKursora izteiksme. Kursora izteiksme, ko norāda CURSOR operators, atgriež. ligzdotu (nested) kursoru. no. vaicājuma. Katra rinda ligzdota

4

Kursorā iekļauta kursora izteiksme CURSOR() un tabulas kolona

Tiek izmantots kursors ar kursora izteiksmi un kursora mainīgais. Izgūšanā tiek izmantoti divi cikli:1) kursora datu izgūšana (F_NOS). Tiek izmantots kursora mehānisms.2) kursora izteiksmes datu izgūšana (UZV). Dati tiek izgūti kursora manīgajā.declare type KURS_MAIN_TIPS is REF CURSOR; kurs_main KURS_MAIN_TIPS; --Kursora mainīgā definēšana fak_nos FAKULTATES.F_NOS%type; stud_uzv STUDENTI. UZV%type;-- Kursora ar kursora izteiksmi definēšana cursor KURSORS is select F_NOS, CURSOR ( select UZV from STUDENTI where NUM_F = F_NUM order by UZV ) stud from FAKULTATES;beginopen KURSORS;-- Kursora buferī esošo datu izgūšana (F_NOS + CURSOR())loop fetch KURSORS into fak_nos, kurs_main; exit when KURSORS%NOTFOUND; DBMS_OUTPUT.PUT_LINE('Fakultāte: ' || fak_nos);-- Datu uz ko norāda kursora mainīgais izgūšana loop fetch kurs_main into stud_uzv; exit when kurs_main%NOTFOUND; DBMS_OUTPUT.PUT_LINE('Studenti: ' || stud_uzv); end loop;end loop;close KURSORS; end;

Page 5: datubaze.files.wordpress.com  · Web viewKursora izteiksme. Kursora izteiksme, ko norāda CURSOR operators, atgriež. ligzdotu (nested) kursoru. no. vaicājuma. Katra rinda ligzdota

5

Kursora izteiksme atgriež vairākas vērtības rindā

declaretype KURS_MAIN_TIPS is REF CURSOR;kurs_main KURS_MAIN_TIPS; --Kursora mainīgā definēšana fak_nos FAKULTATES.F_NOS%type; stud_num STUDENTI.S_NUM%type; stud_uzv STUDENTI. UZV%type;-- Kursora ar kursora izteiksmi definēšana cursor KURSORS is select F_NOS, CURSOR ( select S_NUM, UZV from STUDENTI where NUM_F = F_NUM order by UZV ) stud from FAKULTATES;beginopen KURSORS;-- Kursora buferī esošo datu izgūšana (F_NOS + CURSOR())loop fetch KURSORS into fak_nos, kurs_main; exit when KURSORS%NOTFOUND; DBMS_OUTPUT.PUT_LINE('Fakultāte: ' || fak_nos);-- Datu uz ko norāda kursora mainīgais izgūšana loop fetch kurs_main into stud_num, stud_uzv; exit when kurs_main%NOTFOUND; DBMS_OUTPUT.PUT_LINE('Studenti: ' || stud_num || ' ' || stud_uzv); end loop;end loop;close KURSORS; end;

Page 6: datubaze.files.wordpress.com  · Web viewKursora izteiksme. Kursora izteiksme, ko norāda CURSOR operators, atgriež. ligzdotu (nested) kursoru. no. vaicājuma. Katra rinda ligzdota

6

Tikai kursora izteiksmes CURSOR() iekļaušana kursorā

Tiek izmantots kursors ar kursora izteiksmi un kursora mainīgais.declare type KURS_MAIN_TIPS is REF CURSOR; kurs_main KURS_MAIN_TIPS; --Kursora mainīgā definēšana fak_nos FAKULTATES.F_NOS%type; stud_uzv STUDENTI. UZV%type;-- Kursora ar kursora izteiksmi definēšana cursor KURSORS is select CURSOR ( select UZV from STUDENTI where NUM_F = F_NUM order by UZV ) stud from FAKULTATES;beginopen kursors;-- Kursora buferī esošo datu izgūšana (CURSOR()loop fetch KURSORS into kurs_main; exit when kursors%NOTFOUND;-- DBMS_OUTPUT.PUT_LINE('Fakultāte: ' || fak_nos);-- Datu uz ko norāda kursora mainīgais izgūšana loop fetch kurs_main into stud_uzv; exit when kurs_main%NOTFOUND; DBMS_OUTPUT.PUT_LINE('Studenti: ' || stud_uzv); end loop;end loop;close KURSORS;end;

Page 7: datubaze.files.wordpress.com  · Web viewKursora izteiksme. Kursora izteiksme, ko norāda CURSOR operators, atgriež. ligzdotu (nested) kursoru. no. vaicājuma. Katra rinda ligzdota

7

Kursora izteiksmes izmantošanas veidi

Kursa izteiksmi var izmantot divos dažādos, bet ļoti noderīgos veidos: 1) apakšvaicājuma izgūšanai kā kolonnu ārējā vaicājumā;2) lai pārvērstu vaicājumu par rezultātu kopu, ko var nodot kā

argumentu straumēšanas vai transformācijas funkcijai.

Page 8: datubaze.files.wordpress.com  · Web viewKursora izteiksme. Kursora izteiksme, ko norāda CURSOR operators, atgriež. ligzdotu (nested) kursoru. no. vaicājuma. Katra rinda ligzdota

8

Apakšvaicājuma izgūšana kā kolonna

Šī procedūra parāda ligzdotu CURSOR izteiksmju izmantošanu, lai izgūtu apakšvaicājumu kā kolonnu ārējā vaicājumā. Augšējā līmeņa vaicājums ienes tikai divus datus: pilsētas atrašanās vietu un ligzdotu kursoru, kurā ir šīs pilsētas nodaļas. Šis ligzdotais kursors savukārt ienes ligzdotu kursoru ar CURSOR izteiksmi - šajā gadījumā ar visu nodaļu darbinieku vārdiem. Es būtu varējis veikt šo pašu izguvi ar atsevišķiem tiešiem kursoriem, atvērt un apstrādāt ligzdotā veidā. CURSOR izteiksme sniedz mums iespēju izmantot atšķirīgu pieeju, kas var būt daudz kodolīgāka un efektīvāka, ņemot vērā, ka visa apstrāde notiek SQL priekšraksta izpildītājā (kas samazina konteksta pārslēgšanos).

Page 9: datubaze.files.wordpress.com  · Web viewKursora izteiksme. Kursora izteiksme, ko norāda CURSOR operators, atgriež. ligzdotu (nested) kursoru. no. vaicājuma. Katra rinda ligzdota

9

PROCEDURE emp_report (p_locid NUMBER) IS TYPE refcursor IS REF CURSOR; -- The query returns only 2 columns, but the second column is -- a cursor that lets us traverse a set of related information. CURSOR all_in_one_cur is SELECT l.city, CURSOR (SELECT d.department_name, CURSOR(SELECT e.last_name FROM employees e WHERE e.department_id = d.department_id) AS ename FROM departments d WHERE l.location_id = d.location_id) AS dname FROM locations l WHERE l.location_id = p_locid;departments_cur refcursor; employees_cur refcursor; v_city locations.city%TYPE; v_dname departments.department_name%TYPE; v_ename employees.last_name%TYPE; BEGIN OPEN all_in_one_cur; LOOP FETCH all_in_one_cur INTO v_city, departments_cur; EXIT WHEN all_in_one_cur%NOTFOUND; -- Now I can loop through departments and I do NOT need to -- explicitly open that cursor. Oracle did it for me. LOOP FETCH departments_cur INTO v_dname, employees_cur; EXIT WHEN departments_cur%NOTFOUND;-- Now I can loop through employees for that department. -- Again, I do not need to open the cursor explicitly. LOOP FETCH employees_cur INTO v_ename; EXIT WHEN employees_cur%NOTFOUND; DBMS_OUTPUT.put_line (v_city || ' ' || v_dname || ' ' || v_ename ); END LOOP; END LOOP; END LOOP; CLOSE all_in_one_cur; END;

Page 10: datubaze.files.wordpress.com  · Web viewKursora izteiksme. Kursora izteiksme, ko norāda CURSOR operators, atgriež. ligzdotu (nested) kursoru. no. vaicājuma. Katra rinda ligzdota

10

Straumēšanas (straming) funkcijas ieviešana ar KURSORA izteiksmēm

Straumēšanas funkcijām, ko sauc arī par transformējošām funkcijām, ļauj pārveidot datus no viena stāvokļa uz citu, neizmantojot lokālās datu struktūras kā starppieturvietas. Pieņemsim, ka, piemēram, man ir jāņem dati StockTable un jāpārvieto tie TickerTable, StockTable pārgriežot vienu rindu uz divām TickerTable rindām. Izmantojot CURSOR izteiksmi un galda funkcijas, šo risinājumu varu ieviest šādi:

Izplatīts tabulu funkciju lietojums ir datu straumēšana tieši no viena procesa vai transformācijas uz nākamo procesu, bez starpposma. Šādā veidā izmantotā tabulas funkcija tiek saukta par straumēšanas tabulas funkciju.

insert into MERKA_TABULA   SELECT *     from TABLE (TRANFORM_FUNKCIJAt (CURSOR (SELECT *                                       from AVOTA_TABULA)))

1. Paņem visus datus no stocktable....2. Pārvērst to par kursora mainīgo ar CURSOR izteiksmi...3. Nodot šo kursora mainīgo stockpivot tabulas funkcijai...4. Funkcija atgriež ligzdtabulu ar objekta tipa instancēm...5. TABLE operators konvertē šo kolekciju relāciju tabulas formātā...6. SELECT visas rindas no pseidotabulas...7. INSERT tās jaunajā tabulā.Un, kā norāda attēls, var veikt vairākas transformācijas, kā parādīts:

Page 11: datubaze.files.wordpress.com  · Web viewKursora izteiksme. Kursora izteiksme, ko norāda CURSOR operators, atgriež. ligzdotu (nested) kursoru. no. vaicājuma. Katra rinda ligzdota

11

And as the image indicates, you can perform multiple transformations, as in:

INSERT INTO ticker tableSELECT *  FROM TABLE (ticker pivot (                CURSOR (SELECT *                          FROM TABLE(stockpivot (                                  CURSOR (SELECT *                                             FROM stocktable))))))

Page 12: datubaze.files.wordpress.com  · Web viewKursora izteiksme. Kursora izteiksme, ko norāda CURSOR operators, atgriež. ligzdotu (nested) kursoru. no. vaicājuma. Katra rinda ligzdota

12

Kursora izteiksmes ierobežojumi

Ir virkne ierobežojumu, kas ierobežo kursora izteiksmju izmantošanu:1) nedrīkst izmantot kursora izteiksmi ar netiešu kursoru, jo nav

pieejams mehānisms, lai ienestu ligzdotu kursoru PL/SQL datu struktūrā;

2) kursa izteiksmes var parādīties tikai vaicājuma SELECT specifikācijas tālākajā atlases sarakstā;

3) kursa izteiksmes var novietot tikai SELECT priekšrakstā, kas nav ligzdots nevienā citā vaicājuma izteiksmē, izņemot gadījumus, kad tā IR definēta kā rokraksta izteiksme, kad jūs nevarat izpildīt kursora izteiksmes apakšvaicājumu.

4) veidojot skatu, nevar izmantot kursora izteiksmes;5) izmantojot kursora izteiksmi dināmiskajā SQL, nevar veikt

BINDun EXECUTE operācijas ar CURSOR izteiksmēm

Page 13: datubaze.files.wordpress.com  · Web viewKursora izteiksme. Kursora izteiksme, ko norāda CURSOR operators, atgriež. ligzdotu (nested) kursoru. no. vaicājuma. Katra rinda ligzdota

13

Cursor Variables as Subprogram Parameters

You can use a cursor variable as a subprogram parameter, which makes it useful for passing query results between subprograms.For example: You can open a cursor variable in one subprogram and process it in a different subprogram. In a multilanguage application, a PL/SQL subprogram can use a cursor variable to return a result set to a subprogram written in a different language.Note:The invoking and invoked subprograms must be in the same database instance. You cannot pass or return cursor variables to subprograms invoked through database links.Caution:Because cursor variables are pointers, using them as subprogram parameters increases the likelihood of subprogram parameter aliasing, which can have unintended results. When declaring a cursor variable as the formal parameter of a subprogram: If the subprogram opens or assigns a value to the cursor variable, then the parameter mode must be IN OUT. If the subprogram only fetches from, or closes, the cursor variable, then the parameter mode can be either IN or IN OUT. Corresponding formal and actual cursor variable parameters must have compatible return types. Otherwise, PL/SQL raises the predefined exception ROWTYPE_MISMATCH. To pass a cursor variable parameter between subprograms in different PL/SQL units, define the REF CURSOR type of the parameter in a package. When the type is in a package, multiple subprograms can use it. One subprogram can declare a formal parameter of that type, and other subprograms can declare variables of that type and pass them to the first subprogram.

Page 14: datubaze.files.wordpress.com  · Web viewKursora izteiksme. Kursora izteiksme, ko norāda CURSOR operators, atgriež. ligzdotu (nested) kursoru. no. vaicājuma. Katra rinda ligzdota

14

Apakšprogrammas parametru pieņemtie vārdi (aliasing) ar kursora mainīgajiem parametriem

Kursora mainīgie parametri ir rādītāji (pointers). Tāpēc, ja apakšprogramma piešķir vienu kursora mainīgā parametru citam, tie attiecas uz to pašu atmiņas atrašanās vietu. Šai aliasing var būt neparedzēti rezultāti.Piemērā procedūrai ir divi kursora mainīgie parametri - emp_cv1 un emp_cv2. Procedūra atver emp_cv1 un piešķir emp_cv2 tās vērtību (kas ir rādītājs). Tagad emp_cv1 un emp_cv2 attiecas uz vienu un to pašu vietu atmiņā. Kad procedūra aizver emp_cv1, tā aizver arī emp_cv2. Tāpēc, mēģinot veikt procedūru no emp_cv2, PL/SQL rada īpašo situāciju.

DECLARE TYPE EmpCurTyp IS REF CURSOR; c1 EmpCurTyp; c2 EmpCurTyp;PROCEDURE get_emp_data (emp_cv1 IN OUT EmpCurTyp,emp_cv2 IN OUT EmpCurTyp ) IS emp_recemployees%ROWTYPE; BEGIN OPEN emp_cv1 FOR SELECT * FROM employees; emp_cv2 := emp_cv1; -- now both variables refer to same location FETCH emp_cv1 INTO emp_rec; -- fetches first row of employees FETCH emp_cv1 INTO emp_rec; -- fetches second row of employees FETCH emp_cv2 INTO emp_rec; -- fetches third row of employees CLOSE emp_cv1; -- closes both variables FETCH emp_cv2 INTO emp_rec; -- causes error when get_emp_data is invoked END;

BEGIN

Page 15: datubaze.files.wordpress.com  · Web viewKursora izteiksme. Kursora izteiksme, ko norāda CURSOR operators, atgriež. ligzdotu (nested) kursoru. no. vaicājuma. Katra rinda ligzdota

15

get_emp_data(c1, c2);END;Result:DECLARE*ERROR at line 1:ORA-01001: invalid cursorORA-06512: at line 19ORA-06512: at line 22