CREATE TABLE qz_employees
(
employee_id INTEGER,
last_name VARCHAR2 (100),
salary NUMBER
)
Table created.
BEGIN
INSERT INTO qz_employees
VALUES (1000, 'Frogbit', 1000);
INSERT INTO qz_employees
VALUES (2000, 'Kudzu', 5000);
INSERT INTO qz_employees
VALUES (3000, 'Loosestrife', 10000);
COMMIT;
END;
1 row(s) inserted.
CREATE OR REPLACE TYPE qz_numbers_t IS TABLE OF NUMBER
Type created.
Using GOTOs
CREATE OR REPLACE PROCEDURE qz_proc (
numbers_in IN qz_numbers_t)
IS
BEGIN
FOR indx IN 1 .. numbers_in.COUNT
LOOP
IF numbers_in (indx) < 0
THEN
GOTO end_loop;
END IF;
UPDATE qz_employees
SET salary = numbers_in (indx)
WHERE employee_id = TRUNC (numbers_in (indx));
IF SQL%ROWCOUNT > 0
THEN
GOTO end_loop;
END IF;
DBMS_OUTPUT.put_line (
'No row updated for ' || numbers_in (indx));
<<end_loop>>
NULL;
END LOOP;
END;
Procedure created.
DECLARE
l_ids qz_numbers_t
:= qz_numbers_t (-2000, 1000.50, 3500);
BEGIN
qz_proc (l_ids);
END;
No row updated for 3500
Using CONTINUE-WHEN
CREATE OR REPLACE PROCEDURE qz_proc (
numbers_in IN qz_numbers_t)
IS
BEGIN
FOR indx IN 1 .. numbers_in.COUNT
LOOP
CONTINUE WHEN numbers_in (indx) < 0;
UPDATE qz_employees
SET salary = numbers_in (indx)
WHERE employee_id = TRUNC (numbers_in (indx));
CONTINUE WHEN SQL%ROWCOUNT > 0;
DBMS_OUTPUT.put_line (
'No row updated for ' || numbers_in (indx));
END LOOP;
END;
Procedure created.
DECLARE
l_ids qz_numbers_t
:= qz_numbers_t (-2000, 1000.50, 3500);
BEGIN
qz_proc (l_ids);
END;
No row updated for 3500
Using GOTOs and No Loop
CREATE OR REPLACE PROCEDURE qz_proc (
numbers_in IN qz_numbers_t)
IS
l_index PLS_INTEGER := numbers_in.FIRST - 1;
BEGIN
<<check_numbers>>
l_index := numbers_in.NEXT (l_index);
IF l_index <= numbers_in.LAST
THEN
IF numbers_in (l_index) < 0
THEN
GOTO check_numbers;
END IF;
UPDATE qz_employees
SET salary = numbers_in (l_index)
WHERE employee_id = TRUNC (numbers_in (l_index));
IF SQL%ROWCOUNT > 0
THEN
GOTO check_numbers;
END IF;
DBMS_OUTPUT.put_line (
'No row updated for ' || numbers_in (l_index));
GOTO check_numbers;
END IF;
END;
Procedure created.
DECLARE
l_ids qz_numbers_t
:= qz_numbers_t (-2000, 1000.50, 3500);
BEGIN
qz_proc (l_ids);
END;
No row updated for 3500
Using Exceptions
CREATE OR REPLACE PROCEDURE qz_proc (
numbers_in IN qz_numbers_t)
IS
l_index PLS_INTEGER := numbers_in.FIRST;
e_no_more_to_do EXCEPTION;
BEGIN
FOR indx IN 1 .. numbers_in.COUNT
LOOP
BEGIN
IF numbers_in (indx) < 0
THEN
RAISE e_no_more_to_do;
END IF;
UPDATE qz_employees
SET salary = numbers_in (indx)
WHERE employee_id = TRUNC (numbers_in (indx));
IF SQL%ROWCOUNT > 0
THEN
RAISE e_no_more_to_do;
END IF;
DBMS_OUTPUT.put_line (
'No row updated for ' || numbers_in (indx));
EXCEPTION
WHEN e_no_more_to_do
THEN
NULL;
END;
END LOOP;
END;
Procedure created.
DECLARE
l_ids qz_numbers_t
:= qz_numbers_t (-2000, 1000.50, 3500);
BEGIN
qz_proc (l_ids);
END;
No row updated for 3500
DROP TABLE qz_employees
Table dropped.
DROP PROCEDURE qz_proc
Procedure dropped.
DROP TYPE qz_numbers_t FORCE
Type dropped.