12. Коллекциялар


Коллекция дегеніміз бір типті элементтердің жөнге келтірілген тобын айтады. PL/SQL тілінде колоекцияның үш түрі бар:

  • Енгізілген кестелер (nested tables);
  • индекстелген кестелер;
  • varray-массивтер (variable-size arrays).

Енгізілген кестенің немесе varray-массив элементерін қол жетімділік оның индексі арқылы жүзеге асырылады. Ол айнымалы коллекция типінің атынан кейні жақшаның ішінде көрсетіледі. Коллекция параметр ретінде беріле алады. Коллекцию келесілер үшін қолдануға болады:

  • Деректер базасаның кестелерімен және мәліметтер қатарымен алмасу үшін;
  • Клиент қосымшасынан мәліметтер қатарын сақталынатын процедураға немесе керісінше беру үшін.

Коллекцияларды құру үшін коллекция типін анықтау қажет - TABLE немесе VARRAY – және осы типтің айнымалысын жариялау. Типті жариялау PL/SQL блогының жариялау секциясында, ішкі программасында немесе пакетінде жүзеге асады.

Енгізілген кестелер

Енгізілген кестелердің типін анықтау келесі формальды бейнеленулерден тұра алады:

TYPE type_name IS TABLE OF

element_type [NOT NULL];

type_name параметрі анықталатын типтің атын көрсетеді, ал element_type - PL/SQL мәліметтерінің кез келген мүмкін болатын типі, оының ішіне VARRAY, TABLE, BOOLEAN, LONG, REF CURSOR и және т.б. кірмейді.

Енгізілген кестені 1 ден 2147483647 диапазондағы мәндер индекс ретінде қолданыла алатын бір өлшемді массив ретінде қарастыруға болады. Енгізілген кесте бос лементтерлен тұра алады, олар берілген DELETE процедурасы жоюды жасағаннан кейін пайда болады. Енгізілген кестелер динамикалық түрде ұлғая алады.

Индекстелген кестелер

Индекстелген кестелер қатарлармен бір ғана айнымалысы бар массив ретінде жұмыс істеуге береді.

Индекстелген кестені (index-by tables) анықтау келесі формальды бейнеленулерден тұра алады:

TYPE type_name IS TABLE

OF element_type [NOT NULL]

INDEX BY BINARY_INTEGER;

Индекстелген кестелер – бұл элементтер туынды бүтін санды индекстер мәніне ие бола алатын енгізілген кестелердің нұсқасы. Мәліметтердің мұндай типтері индектің орнына бірінші реттік кілттің мәнін қолданатын жағдайда қте ыңғайлы болып келеді.

VARRAY-массивтер

Varray-массивтерді анықтау келесі формальды бейнеленулерден тұра алады:

TYPE type_name IS

{VARRAY | VARYING ARRAY} (size_limit)

OF element_type [NOT NULL];

type_name параметрі анықталатын типтің атын көрсетеді, size_limit – элементтердің максималды саны, ал element_type - PL/SQL мәліметтеріндегі кез келген мүмкін болатын тип, бірақ оның ішіне VARRAY, TABLE, BOOLEAN, LONG, REF CURSOR және т.б. кірмейді.

Егер элементтің типі ретінде "жазба" типі қолданылса, онда әрбір жазба аймағы скалярлы немесе объектілік тип болуы қажет.

Varray-массивте элементтердің максималды саны типті анықтау барысында анықталынады және динамикалық түрде өзгеріле алады. Varray-массивінің әрбір элементіне қол жетімділік оның индексі арқылы жүзеге асады. Varray-массивтерді параметр ретінде беруге болады. Varray-массивтер бос орынды қабылдай алмайды, себебі олар үшін туынды массив элементінің жою операциясы жоқ.

Мысалы:

DECLARE

TYPE d1 IS VARRAY(365) OF DATE;

TYPE rec1 IS

RECORD (v1 VARCHAR2(10),

v2 VARCHAR2(10));

- Массив записей

TYPE arr_rec IS VARRAY(250) OF rec1;

- Вложенная таблица

TYPE F1T1 IS TABLE OF tbl1.f1%TYPE;

CURSOR c1 IS SELECT * FROM tbl1;

- Массив записей,

- основанный на курсоре

TYPE t1 IS VARRAY(50) OF c1%ROWTYPE;

TYPE t2 IS TABLE OF tbl1%ROWTYPE

- Индексированная таблица

INDEX BY BINARY_INTEGER;

- Объявление переменной

rec_t2 t2;

BEGIN

/* Использование переменной

типа "индексированная таблица" */

SELECT * INTO rec_t2(120)

WHERE f1 = 120;

END;

Коллекцияларды инициализациялау

Коллекцияларды инициализациялау үшін конструктор қолданылады- бір атты типпен коллекцияны автоматты түрде құратын функция.

Конструктор коллекцияны оған берілген тізім параметрлеріндегі мәндер арқылы құрады. Конструктор хабарламалау секциясында типті көрсеткеннен кейін меншіктеу белгісінен кейін, сонымен қатар программа денесінде де шақырыла алады. Конструкторды шақыру параметрі коллекцияның инициализациялануын бос ретінде көрсетеді, бірақ оны NULL теңестірмейді.

Мысалы

DECLARE

CREATE TYPE rec_var1

AS VARRAY(3) OF num;

CREATE TYPE rec_var2

AS VARRAY(3) OF rec_obj;

r1 rec_var1; r2 rec_var2;

BEGIN

/* Инициализация коллекции

из трех элементов */

r1 := rec_var1 (2.0, 2.1, 2.2);

/*Инициализация varray-массива,

содержащего объекты типа rec_obj */

r2 := rec_var2 (rec_obj(1, 100, 'fff'),

rec_obj (2,110, 'ggg'),

rec_obj (3,120, 'jjj'));

CREATE TYPE операторы анықталған типті мәліметтер базасында сақтауға мүмкіндік береді.

Конструкторды функцияның шақыруы бар жердің барлығында шақыруға болады. Мәліметтер базасындағы кестеге жол қосу үшін коллекция типіндегі аймаққа конструктор ды қолдану керек.

Мысалы:

BEGIN

INSERT INTO tbl_coll

VALUES (1, 'aaa', rec_obj

(3,120, 'jjj'));

Коллекциялармен жұмыс істеу барысында қолданылатын әдістер

PL/SQL тілінде коллекциялармен жұмыс істеудің енгізілген әдістері бар. Бұл әдістер былацшы шақырылады

collection_name.method_name[(parameters)]

Бұл әдістерді SQL-оператордан шақыруға болмайды.

Келесі кестеде коллекциямен жұмыс істеу барысында қолданылатын енгізілген функциялардың бейнеленулері көрсетілген.

Әдіс

Бейнеленуі

EXISTS(n)

Егер коллекцияның n-ші элементі бар болса, онда функция TRUE мәнін қайтарады

COUNT

Коллекцияда бар эелементтердің нақты санын қайтарады

LIMIT

varray-массивтің өлшемін қайтарады немесе NULL – енгізілген кестелер үшін

DELETE(m,n)

Бұл процедура енгізілген немесе индекстелген кестелерден элементтерді жояды. Егер параметрлер берілмеген болсе, онда коллекциядағы барлық элементтер жойылады n параметрді берген жағдайда енгізілген кестенің n-ші элементің жояды, ал егер екі параметр де берілген болса, онда n нен m аралығындағы барлық элементтер өшіріледі

FIRST, LAST

Функция коллекция элементтерінің ең үлкен немесе ең кіші индекстерін қайтарады. Бос енгізілген кестелер үшін екі фнукция да NULL мәнін қбалдайды. Varray-массив үшін FIRST функциясын шақыру 1 мәнін береді

PRIOR(n)

Бұл функция цикл үшін немесе тізбекті көрсетілім үшін қолданылады жіне берілген n параметрдегі элемент индексін қайтарады. Егер мұндай элемент жоқ болатын болса, онда NULL мәнін қайтарады

NEXT(n)

Функция цикл үшін немесе енгізілген кесте элементтерінің тізбекті түрдегі көрсетілімін қолдану үшін және келесі көрсетілген n параметрлі элемент индексін қайтару үшін қолданылады. Егер ондай элементтер жоқ болса, онда NULL мәнін қайтарады

EXTEND(n,i)

Функция енгізілген немесе индекстелген кесте өлшемін үлкейту үшін қолданылады, олар коллекцияға бір немесе бірнеше элементтер қосу арқылы жүзеге асырылады. Егер параметрлер берілмеген болса, онда коллекцияға бір null-элементі қосылады, ал егер тек қана n параметрі көрсетілген болса, онда n элементтер қосылады , олар коллекцияның i-ші элементінің көшірмесі болып табылады.

TRIM(n)

Функция енгізілген немесе индекстелген кестелердің бір немесе бірнеше элементтерін өшіреді. Егер параметр берілмеген болса, онда соңғы бір элемент өшіріледі, ал параметр берілген болса, онда соңғы n элементтер өшіріледі. Егер параметр мәні нақты элементтер санынан асып кететін болса, онда шығарып тастау инициялизацияланады. Егер элемент бұрын DELETE функциясы арқылы өшірілген болса, онда ол сонда да TRIM функциясы арқылы өшірілетін элементтер тізіміне енеді

TRIM және EXTEND функцияларын қолдану енгізілген кестелер үшін стек механизмінің кестесін жүзеге асырады, ол элементтерді енгізілен кестенің соңынан өшіру немесе соңына қосуға мүмкіндік береді. DELETE функциясы элементтерді өшіруге мүмкіндік береді, оның соңынан бос орын қалады, олар кейін TRIM функциясы арқылы өлшенеді.

COUNT функциясымен қайтарылатын мәндер коллекция элементтерінің цикл санағышының максималды мәні ретінде қолданыла алады.

Мысалы:

FOR i IN 1..tbl1.COUNT LOOP

END LOOP;

COUNT функциясы мәліметтер базасындағы енгізілген кестелер қатарынан алынған жолдар санын анықтау үшін де қолданылады.

Varray-массив үшін COUNT функциясымен қайтарылатын мән LAST функциясымен қайтарылатын мәнге эквиваленттәі болып келеді. Енгізілген кестелер үшін бұл мәндер коллекциядан элементтерді өшіретін DELETE функциясы қолданылған жағдайда әртүрлі болуы мүмікн. Коллекция инициализацияланбас бұрын можно EXISTS әдісін қолдануға болады. Кез келген енгізілген әдісті шақыру кезінде шығарып тасталыну қолданылады.

Мысалы:

DECLARE

- Вложенная таблица

TYPE cl IS TABLE OF VARCHAR2(10);

c1 cl;

BEGIN

- Инициализации

- коллекции конструктором

c1 := cl('с 1', 'с 2', 'с 3');

- Удаление последнего (3-го) элемента

c1.DELETE(c1.LAST);

- Удаление двух последних элементов:

- (2-го и 3-го)

c1.TRIM(c1.COUNT);

- Запись в поток

- вывода значения 'с 1'

DBMS_OUTPUT.PUT_LINE(c1(1));

END;

Егер коллекциямен жұмыс жасау барысында қателер пайда болатын болса, онда Oracle шығарып тастауды инициализациялайды. Келесі кестеде коллекциялар үшін арналған қателердің пайда болу себебі көрсетілген.

Шығарып тастау

Қатенің себебі

COLLECTION_IS_NULL

Коллекция инициализацияланбаған

NO_DATA_FOUND

Индекс коллекцияның бұрын өшірілген элементіне сілтеме жасаған

SUBSCRIPT_BEYOND_COUNT

Индекс коллекциядағы элементтер санына қарағанда үлкен

SUBSCRIPT_OUTSIDE_LIMIT

Мәндер индексі диапазонына индекс сәйкес келмейді

VALUE_ERROR

Индекс мәні NULL тең немесе бүтінге айнала алмайды

Шығарып тастау жағдайы инициализацияланбайды, егер DELETE процедурасында параметр ретінде NULL индексі берлген болса немесе индексті көрсету барысында бұрын өшіріліп тасталынған элементке жіберілсе

Жазбалар

Жазба дегеніміз жазба аймағында сақталынатын элементтер жиынтығы. Әрбір аймақтың өзінің аты және типі болады.

Жазбаларды теңдікке немесе теңсіздікке және NULL мәнінің эквиваленттілігіне салыстыруға болмайды.

Жазба базадағы бар кесте құрылымында немесе жаңа тип ретінде жариялана алады.

Жазбаны хабарлау үшін %ROWTYPE атрибуты қолданылады.

"Жазба" жаңа типін жариялау келесі формальды бейнеленулерлен тұра алады:

TYPE type_name IS RECORD

(field_declaration

[, field_declaration]...);

Аймақты бейнелеу (field_declaration) келесідей көрсетіледі:

field_name field_type

[[NOT NULL] {:= | DEFAULT} expression]

type_name параметрі анықталатын типтің атын береді; field_type аймақ типін кез келген PL/SQL типі ретінде көрсетеді, оның ішіне тек қана REF CURSOR кірмейді; expression я инициализация мәнін анықтайды.

Коллекция үшін секілді жазбаны құру үшін де ең алдымен RECORD типін анықтау керек, сосын берілген типтегі жазбаны жариялау қажет.

"Жазба" типі программаның орындалуы барысында ғана бар болады және деректер базасында TABLE және VARRAY типтерімен салыстырғанда сақтала алмайды.

Кез келген жазба аймағына қол жетімдік болу үшін келесі нотация қолданылады: record_name.field_name. Егер field_name жазба болса, онда оның енгізілген аймағы үшін сол нотация қолданылады: record_name.field_name.field1_name және т.б.

PL/SQL тілінің өрнектерінде мәндерді меншіктеу жеке аймақта немесе барлық жазбаларда жүзеге асыруға болады.

Барлық жазбалардың мәндерін меншіктеудің екі түрлі әдісі бар:

  • Меншіктелетін мән ретінде сол типтегі жазба мәнін қолдану;
  • Жазбаны SQL-операторында INTO-айнымалы ретінде SELECT немесе FETCH беру.

Мысалы:

DECLARE

- Типті анықтау

TYPE T_rec IS RECORD (

f1 tbl1.f1%TYPE,

f2 VARCHAR2(15),

f3 REAL(7,2));

- Кесте жолы негізіндегі тип

rec3 tbl1%ROWTYPE;

- Жазбаларды жариялау

rec1 T_rec;

f_sum1 REAL;

FUNCTION sum_f3 (n INTEGER)

RETURN T_rec IS

rec2 T_rec;

BEGIN

- :

- Функция мәнді қайтарады

- жазба типі

RETURN rec2;

END;

BEGIN

- функцияны шақыру

rec1 := sum_f3(4);

f_sum1 := sum_f3(4).f3;

SELECT * INTO rec3 FROM tbl1

WHERE f1 = 1;

END;