در این فصل انواع LOOP یا حلقه در PL/SQL را بررسی می کنیم. ممکن است در یک برنامه نیاز باشد یک بلاک از کد چندین مرتبه اجرا شود در این مواقع از حلقه استفاده می شود.
در جدول زیر انواع روش های حلقه و توضیح آنها را مشاهده می کنید.
حلقه ساده
سینتکس حلقه ساده به این شکل است:
LOOP
Sequence of statements;
END LOOP;
در این سینتکس Sequence of statements می تواند یک دستور یا یک بلاک از دستورات باشد.
نکته: برای خروج از حلقه ساده باید از دستور EXIT یا EXIT WHEN استفاده نمود.
مثال 1:
DECLARE
x number := 10;
BEGIN
LOOP
dbms_output.put_line(x);
x := x + 10;
IF x > 50 THEN
exit;
END IF;
END LOOP;
— after exit, control resumes here
dbms_output.put_line(‘After Exit x is: ‘ || x);
END;
/
خروجی
10
20
30
40
50
After Exit x is: 60
PL/SQL procedure successfully completed.
مثال 2: برای خروج از حلقه، از دستور EXIT WHEN استفاده شده است.
DECLARE
x number := 10;
BEGIN
LOOP
dbms_output.put_line(x);
x := x + 10;
exit WHEN x > 50;
END LOOP;
— after exit, control resumes here
dbms_output.put_line(‘After Exit x is: ‘ || x);
END;
/
خروجی
10
20
30
40
50
After Exit x is: 60
PL/SQL procedure successfully completed.
حلقه WHILE
سینتکس حلقه WHILE به این شکل است:
WHILE condition LOOP
sequence_of_statements
END LOOP;
مثال:
DECLARE
a number(2) := 10;
BEGIN
WHILE a < 20 LOOP
dbms_output.put_line(‘value of a: ‘ || a);
a := a + 1;
END LOOP;
END;
/
خروجی
value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 15
value of a: 16
value of a: 17
value of a: 18
value of a: 19
PL/SQL procedure successfully completed.
حلقه FOR
FOR counter IN initial_value .. final_value LOOP
sequence_of_statements;
END LOOP;
در این روش initial value و final value می توانند از نوع LITERAL ، متغیر یا یک عبارت باشند به شرطی که به عنوان اعداد باشند وگرنه خطای VALUE_ERROR دریافت می کنیم.
همچنین نیازی نیست که intial value در یک حلقه FOR برابر با یک باشد ولی افزایش و کاهش شمارنده باید یک باشد. می توان محدوده initial value و final value را به صورت دینامیک و در زمان اجرا مشخص نمود.
مثال 1:
DECLARE
a number(2);
BEGIN
FOR a in 10 .. 20 LOOP
dbms_output.put_line(‘value of a: ‘ || a);
END LOOP;
END;
/
خروجی
value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 15
value of a: 16
value of a: 17
value of a: 18
value of a: 19
value of a: 20
PL/SQL procedure successfully completed.
نکته: زمانی که می خواهیم در حلقه FOR به صورت معکوس شمارش انجام شود از کلمه کلیدی REVERSE استفاده می گردد. در ضمن باید در دستور FOR محدوده شمارش را به همان صورت صعودی مشخص کرد.
مثال 2:
DECLARE
a number(2) ;
BEGIN
FOR a IN REVERSE 10 .. 20 LOOP
dbms_output.put_line(‘value of a: ‘ || a);
END LOOP;
END;
/
خروجی
value of a: 20
value of a: 19
value of a: 18
value of a: 17
value of a: 16
value of a: 15
value of a: 14
value of a: 13
value of a: 12
value of a: 11
value of a: 10
PL/SQL procedure successfully completed.
حلقه های تودرتو
در ادامه سینتکس های مربوط به روش های حلقه تودرتو را می بینید:
—LOOP
LOOP
Sequence of statements1
LOOP
Sequence of statements2
END LOOP;
END LOOP;
—FOR
FOR counter1 IN initial_value1 .. final_value1 LOOP
sequence_of_statements1
FOR counter2 IN initial_value2 .. final_value2 LOOP
sequence_of_statements2
END LOOP;
END LOOP;
—WHILE
WHILE condition1 LOOP
sequence_of_statements1
WHILE condition2 LOOP
sequence_of_statements2
END LOOP;
END LOOP;
مثال: برنامه ای بنویسید که اعداد اول بین 2 تا 50 را نمایش دهد.
DECLARE
i number(3);
j number(3);
BEGIN
i := 2;
LOOP
j:= 2;
LOOP
exit WHEN ((mod(i, j) = 0) or (j = i));
j := j +1;
END LOOP;
IF (j = i ) THEN
dbms_output.put_line(i || ‘ is prime’);
END IF;
i := i + 1;
exit WHEN i = 50;
END LOOP;
END;
/
خروجی
2 is prime
3 is prime
5 is prime
7 is prime
11 is prime
13 is prime
17 is prime
19 is prime
23 is prime
29 is prime
31 is prime
37 is prime
41 is prime
43 is prime
47 is prime
PL/SQL procedure successfully completed.
نکته: با علامت براکت << >> می توان یک LABEL یا برچسب برای حلقه در نظرگرفت که قبل از دستور حلقه قرار می گیرد.
مثال:
DECLARE
i number(1);
j number(1);
BEGIN
<< outer_loop >>
FOR i IN 1..3 LOOP
<< inner_loop >>
FOR j IN 1..3 LOOP
dbms_output.put_line(‘i is: ‘|| i || ‘ and j is: ‘ || j);
END loop inner_loop;
END loop outer_loop;
END;
/
خروجی
i is: 1 and j is: 1
i is: 1 and j is: 2
i is: 1 and j is: 3
i is: 2 and j is: 1
i is: 2 and j is: 2
i is: 2 and j is: 3
i is: 3 and j is: 1
i is: 3 and j is: 2
i is: 3 and j is: 3
PL/SQL procedure successfully completed.
دستورات کنترلی حلقه ها
دیاگرام دستور EXIT را در شکل زیر می بینید.
مثال:
DECLARE
a number(2) := 10;
BEGIN
— while loop execution
WHILE a < 20 LOOP
dbms_output.put_line (‘value of a: ‘ || a);
a := a + 1;
IF a > 15 THEN
— terminate the loop using the exit statement
EXIT;
END IF;
END LOOP;
END;
/
خروجی
value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 15
PL/SQL procedure successfully completed.
نکته: اگر از دستور EXIT WHEN استفاده شود یک شرط برای خارج شدن از حلقه بررسی می گردد بنابراین استفاده از این دستور مانند زمانی است که از IF-THEN استفاده شود. اگر شرط برقرار نباشد این دستور مانند دستور NULL عمل می کند.
مثال:
DECLARE
a number(2) := 10;
BEGIN
— while loop execution
WHILE a < 20 LOOP
dbms_output.put_line (‘value of a: ‘ || a);
a := a + 1;
— terminate the loop using the exit when statement
EXIT WHEN a > 15;
END LOOP;
END;
/
خروجی
value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 15
PL/SQL procedure successfully completed.
در شکل زیر دیاگرام دستور CONTINUE را می بینید.
مثال:
DECLARE
a number(2) := 10;
BEGIN
— while loop execution
WHILE a < 20 LOOP
dbms_output.put_line (‘value of a: ‘ || a);
a := a + 1;
IF a = 15 THEN
— skip the loop using the CONTINUE statement
a := a + 1;
CONTINUE;
END IF;
END LOOP;
END;
/
خروجی
value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 16
value of a: 17
value of a: 18
value of a: 19
PL/SQL procedure successfully completed.
نکته: از آنجایی که دستور GOTO سبب پیچیدگی در فهم برنامه می شود استفاده از آن توصیه نمی گردد.
در شکل زیر دیاگرام دستور GOTO را می بینید.
مثال:
DECLARE
a number(2) := 10;
BEGIN
<<loopstart>>
— while loop execution
WHILE a < 20 LOOP
dbms_output.put_line (‘value of a: ‘ || a);
a := a + 1;
IF a = 15 THEN
a := a + 1;
GOTO loopstart;
END IF;
END LOOP;
END;
/
خروجی
value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 16
value of a: 17
value of a: 18
value of a: 19
PL/SQL procedure successfully completed.
نکته 1: دستور GOTO فقط در بلاک فعلی عمل می کند و نمی توان از طریق آن به یک بلاک درونی انتقال یافت.
نکته 2: در داخل یک EXCEPTION HANDLER نمی توان از GOTO برای بازگشت به بلاک فعلی استفاده نمود.
نکته 3: نمی توان با دستور GOTO به داخل یک IF ، CASE یا حلقه انتقال یافت.