DBMS-də kursorlar

Müəyyən qeydləri almaq istədikdə SELECT ifadələrindən istifadə edirik. WHERE bəndindəki filtr şərtləri üçün bütün uyğun qeydləri alırlar. Ancaq PL / SQL blokunda istifadə olunan bu SELECT ifadəsi yalnız bir sıra qaytarmaq üçün məhdudlaşdırıldıqda. Bu bir proqramda həmişə xoş qarşılanmır. SEÇMƏ sorğusundan istifadə edərək çoxsaylı sətir seçməli olduğumuz vəziyyətlər olacaqdır. Bunu etmək üçün; birdən çox sətir almaq üçün SEÇMƏ sorğusu yazdığımız kursorlardan istifadə edirik. Bu kursorlar adlı SELECT sorğusudur və nəticəsi ilmələrdən istifadə edərək proqramda bir-bir keçiləcəkdir.

İki növ imlec var - Örtük və Açıq İmleclər

Qapalı İmleclər

Bunlar DBMS tərəfindən avtomatik olaraq yaradılan və istifadə olunan kursorlardır. Bu kursorlar istifadə etdiyimiz zaman yaradılır DML INSERT, DELETE və ya UPDATE kimi ifadələr və ya SELECT sorğusundan istifadə etdiyimiz zaman. Bir sıra SELECT ifadəsi üçün belə DBMS gizli imleclər yaradır. Məlumatı saxlamaq üçün yaddaşda bir az yer ayırır. DML ifadələrini atəşə tutduğumuz zaman belə, uyğun qeydləri seçmək üçün gizli kursor işə salınır və yaddaşdakı qeydlər üçün yer ayrılır.

Bu gizli imleçlər daxili olmasına və istifadəçilər / inkişaf etdiricilər onların icrasına nəzarət edə bilməməsinə baxmayaraq, inkişaf etdiricilər bu imleclərin detallarına öz atributlarından istifadə edərək baxa bilərlər. SQL imlecinə istinad edən 'SQL' istifadə edərək bu gizli imleci əldə edə bilərik. Atributları aşağıda təsvir edilmişdir:

  • ISOPEN - İmlecin icrası üçün hələ açıq olub olmadığına görə TRUE və FALSE qaytarır. DBMS imleci avtomatik olaraq icra edib bağladığı üçün gizli imlec üçün həmişə FALSE qaytarır.
  • FOUND - DML ifadəsi satırlardan hər hansı birini təsir edərsə və ya SELECT ifadəsi bir və ya daha çox satır alırsa TRUE qaytarır. Əks təqdirdə FALSE qaytarır. Bəyanatlar icra edilmirsə, NULL qaytarır.
  • %TAPILMADI -% FOUND-un əksidir. DML ifadəsi satırların heç birini təsir etmirsə və ya SELECT ifadəsi heç bir satır almırsa TRUE qaytarır. Əks təqdirdə FALSE qaytarır.
  • ROWCOUNT - DML ifadələrindən təsirlənən sətirlərin sayını və ya SELECT ifadəsi ilə alınan sətirlərin sayını qaytarır.

Bu gizli kursor xüsusiyyətləri aşağıdakı kimi adlanır:

SQL%ISOPEN
SQL%ROWCOUNT
SQL%FOUND
SQL%NOTFOUND

 Örtülü imlecin nümunələrindən biri

DECLARE
	n_count NUMBER;
BEGIN
	UPDATE EMPLOYEE
       	      SET SALARY = SALARY + (SALARY*0.1) – 10% increment in salary for DEPT_ID = 10 employees
	WHERE DEPT_ID = 10;
IF SQL%FOUND THEN – checks if any row is updated
	n_count: = SQL%ROWCOUNT; -- Number of rows updated are counted
 	DBMS_OUTPUT.PUT_LINE (‘Total Number of employees who got increment: ‘|| n_count);
ELSE
	DBMS_OUTPUT.PUT_LINE (‘None of the employees got increment’);
END IF;
END;

Açıq Cursors

Bu kursorlar proqramı tərəfindən geliştirici tərəfindən yaradılmışdır. Bu tip imleçlərdə geliştirici üzərində nəzarət olacaqdır. Açıq imleclər DECLARE bölməsində elan edilməli və digər hər hansı bir dəyişən kimi istifadə edilə bilər, lakin bir və ya daha çox məlumat satırına sahib olacaqdır.

PL / SQL blokunda yaradılmış hər hansı bir aydın kursorun dörd əsas addımı olacaq:

  • Kursoru elan edin - Bu addım imleci adı ilə elan edir və imlec üçün SELECT ifadəsini təyin edir. Açıq kursor elan etmək üçün ümumi sintaksis aşağıdakı kimidir:

CURSOR cursor_name IS
	           SELECT STATEMENT;
E.g.: 
	CURSOR cursor_Dept10Emp IS
	           SELECT EMP_ID, EMP_NAME FROM EMPLOYEE WHERE DEPT_ID = 10;

  •  Kursoru AÇIN - Kursor oradakı qeydləri oxumaq üçün açılır. Kursoru açdığımız zaman yerinə yetirilir və qeydlər üçün yaddaş sahəsi ayrılır.

OPEN cursor_name

OPEN cursor_Dept10Emp;

  •  Qeydləri əldə edin - Bu addım imlecdəki qeydləri keçməyə başlayacaq. Bu kursordan satırlar bir-bir alınacaq. Bu gətirilən qeydlərdə hər hansı bir hesablama və ya manipulyasiya edə bilərik.

FETCH cursor_Dept10Emp INTO n_empID, v_empName;

  •  İmleci bağlayın - Kursor istifadə edildikdən və proqramda artıq tələb olunmadıqdan sonra kursoru bağlayın. Bu, bu kursor üçün ayrılmış yaddaşı buraxacaq.

CLOSE cursor_Dept10Emp;

Yuxarıdakı 4 addımdan ibarət sadə bir proqram aşağıdakı kimidir

DECLARE
	CURSOR cursor_Dept10Emp IS   -- Declare the cursor
	           SELECT EMP_ID, EMP_NAME FROM EMPLOYEE WHERE DEPT_ID = 10;

	n_empID EMPLOYEE.EMP_ID%TYPE;
	v_empName EMPLOYEE.EMP_NAME%TYPE;
BEGIN
	OPEN cursor_Dept10Emp; -- Open the cursor

	LOOP
		FETCH cursor_Dept10Emp INTO n_empID, v_empName; -- Fetch cursor records

		EXIT WHEN cursor_Dept10Em%NOTFOUND;
	DBMS_OUTPUT.PUT_LINE (‘Employee ID: ‘|| n_empID|| ‘Employee Name:’|| v_empName);
END LOOP;

CLOSE cursor_Dept10Emp; -- Close the Cursor
END;

Döngü üçün kursor

Yuxarıda göstərilən dörd addımda FETCH addımı bir dəfəyə yalnız bir qeyd alacaq və fərdi sütun dəyərlərini müvafiq dəyişənlərə təyin edəcəkdir. Bütün qeydləri təkrarlamaq üçün ayrıca bir döngə yaradılmalıdır. Kursorlar üçün For loop istifadə etsək, for loop dəyişənindən istifadə edərək kursor sorğusunun bütün qeydlərini (bütün sütunları) təkrarlaya və keçə bilərik. Bu bir cədvəlin bütün qeydlərinin proqramda istifadə edilməsi lazım olduqda faydalıdır. Kursor FOR döngəsində çağırıldıqda avtomatik olaraq açılacaq və döngə bitdikdə bağlanacaq. Kursoru açıq şəkildə AÇMAQ ya da KAPATMAĞA ehtiyac yoxdur. Nümunə aşağıda loop üçün kursorun yuxarıdakı dörd pillədən necə fərqləndiyini göstərir.

DECLARE
	CURSOR cursor_Dept10Emp IS   -- Declare the cursor
	           SELECT EMP_ID, EMP_NAME FROM EMPLOYEE WHERE DEPT_ID = 10;

	rec_emp EMPLOYEE%ROWTYPE
BEGIN
	FOR rec_emp IN cursor_Dept10Emp -- implicitly opens cursor and assigns cursor variable rec_emp
	LOOP 
	DBMS_OUTPUT.PUT_LINE (‘Employee ID: ‘||rec_emp.EMP_ID|| ‘Employee Name:’|| rec_emp.EMP_NAME);
END LOOP;
END;

Kursor Parametri

Hətta prosedur və funksiyalardakı kimi parametrləri imleclərə ötürə bilərik. Bu parametrlər məlumatları almaq üçün kursor sorğusunda istifadə olunur. Kursor parametrinin əhatə dairəsi yalnız kursor üçün lokallaşdırılmışdır.

DECLARE
	CURSOR cursor_Dept10Emp (deptID EMPLOYEE.DEPT_ID%TYPE) IS   	          
		 SELECT EMP_ID, EMP_NAME FROM EMPLOYEE WHERE DEPT_ID = deptID; -- deptID is the cursor parameter
	rec_emp EMPLOYEE%ROWTYPE

BEGIN
	FOR rec_emp IN cursor_Dept10Emp (10) – Pass the cursor parameter as 10
	LOOP 
	DBMS_OUTPUT.PUT_LINE (‘Employee ID: ‘||rec_emp.EMP_ID|| ‘Employee Name:’|| rec_emp.EMP_NAME);
END LOOP;
END;

 

Ref Kursorları

Bunlar statik imlecə istinad və istifadə etmək üçün istifadə olunan kursor dəyişənləridir. Bu dəyişəni prosedurlara / funksiyalara ötürə bilərik və funksiyaları bir resursor olaraq əldə edə bilərik. Qısacası bir dəyişən işləyir, ancaq iş vaxtında təyin olunan sorğuya istinad.

Aşağıdakı proqramda kursorla refursor arasındakı fərqi görə bilərik.

DECLARE
           TYPE rc_cursor is ref cursor; 
	CURSOR c_course IS
		SELECT * FROM COURSE;
           l_cursor rc_cursor;
         n_ID NUMBER;
BEGIN
	IF n_ID = 10 THEN
	-- Dynamically opens the cursor for student ids less than 10
		Open l_cursor FOR ‘SELECT * FROM STUDENT WHERE STD_ID<= 10’;
	ELSE	
	-- Dynamically opens the cursor for student ids greater than 10
		OPEN l_cursor FOR ‘SELECT * FROM STUDENT WHERE STD_ID > 10’;
	 END IF;
	-- Opens static cursor c_course
	 OPEN c_course;
END;

Translate »