PLSQL Cursor
A cursor is a pointer to this context area. PL/SQL controls the context area through a cursor. A cursor holds the rows (one or more) returned by a SQL statement. The set of rows the cursor holds is referred to as the active set.
Cursors are used to retrieve and manipulate data from a query. They act as pointers to a result set and are particularly useful when you need to fetch rows one at a time.
Explicit Cursors
Attributes:
total_rows number(2);
BEGIN
UPDATE employess
SET salary = salary + 500;
IF sql%notfound THEN
dbms_output.put_line('no customers selected');
ELSIF sql%found THEN
total_rows := sql%rowcount;
dbms_output.put_line( total_rows || ' customers selected ');
END IF;
END;
/
-- Declare cursor
CURSOR emp_cursor IS
SELECT employee_id, employee_name
FROM employees;
-- Declare variables to hold cursor data
v_employee_id employees.employee_id%TYPE;
v_employee_name employees.employee_name%TYPE;
BEGIN
-- Open the cursor
OPEN emp_cursor;
-- Fetch data and process
LOOP
FETCH emp_cursor INTO v_employee_id, v_employee_name;
EXIT WHEN emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('ID: ' || v_employee_id || ' Name: ' || v_employee_name);
END LOOP;
-- Close the cursor
CLOSE emp_cursor;
END;
Example 2:
DECLARE
-- Define an explicit cursor
CURSOR emp_cursor IS
SELECT employee_id, employee_name FROM employees;
-- Variables to hold the fetched data
v_employee_id employees.employee_id%TYPE;
v_employee_name employees.employee_name%TYPE;
-- Variable to count the number of rows fetched
v_row_count INTEGER := 0;
BEGIN
-- Open the cursor
OPEN emp_cursor;
-- Loop to fetch rows and process them
LOOP
FETCH emp_cursor INTO v_employee_id, v_employee_name;
-- Check if there are no more rows to fetch
EXIT WHEN emp_cursor%NOTFOUND;
-- Increment the row count
v_row_count := v_row_count + 1;
-- Display fetched data
DBMS_OUTPUT.PUT_LINE('ID: ' || v_employee_id || ' Name: ' || v_employee_name);
-- Check if cursor is open (it should be)
IF emp_cursor%ISOPEN THEN
DBMS_OUTPUT.PUT_LINE('Cursor is still open.');
END IF;
END LOOP;
-- Display the number of rows fetched
DBMS_OUTPUT.PUT_LINE('Total rows fetched: ' || v_row_count);
-- Check if any rows were found
IF emp_cursor%FOUND THEN
DBMS_OUTPUT.PUT_LINE('At least one row was found.');
ELSE
DBMS_OUTPUT.PUT_LINE('No rows were found.');
END IF;
-- Close the cursor
CLOSE emp_cursor;
-- Check if the cursor is closed (it should be)
IF NOT emp_cursor%ISOPEN THEN
DBMS_OUTPUT.PUT_LINE('Cursor is closed.');
END IF;
-- Check the row count attribute
DBMS_OUTPUT.PUT_LINE('Final row count: ' || emp_cursor%ROWCOUNT);
EXCEPTION
WHEN OTHERS THEN
-- Handle any errors
DBMS_OUTPUT.PUT_LINE('An error occurred: ' || SQLERRM);
IF emp_cursor%ISOPEN THEN
-- Ensure the cursor is closed in case of an error
CLOSE emp_cursor;
END IF;
END;
TYPE emp_table_type IS TABLE OF employees%ROWTYPE;
emp_table emp_table_type;
BEGIN
SELECT * BULK COLLECT INTO emp_table FROM employees;
FOR i IN 1 .. emp_table.COUNT LOOP
DBMS_OUTPUT.PUT_LINE('ID: ' || emp_table(i).employee_id || ' Name: ' || emp_table(i).employee_name);
END LOOP;
END;
CURSOR emp_cursor IS
SELECT employee_id, employee_name FROM employees;
TYPE emp_rec IS RECORD (
employee_id employees.employee_id%TYPE,
employee_name employees.employee_name%TYPE);
TYPE emp_table_type IS TABLE OF emp_rec;
emp_table emp_table_type;
BEGIN
OPEN emp_cursor;
FETCH emp_cursor BULK COLLECT INTO emp_table;
CLOSE emp_cursor;
FOR i IN 1 .. emp_table.COUNT LOOP
DBMS_OUTPUT.PUT_LINE('ID: ' || emp_table(i).employee_id || ' Name: ' || emp_table(i).employee_name);
END LOOP;
END;
Notes:
Cursors are used to retrieve and manipulate data from a query. They act as pointers to a result set and are particularly useful when you need to fetch rows one at a time.
Types of Cursor
Implicit CursorsExplicit Cursors
Implicit Cursors:
Automatically created by Oracle for SQL statements like SELECT INTO, INSERT, UPDATE, and DELETE. These are managed by Oracle internally.Attributes:
- Sql%notfound
- Sql%found
- Sql %rowcount
Example
DECLAREtotal_rows number(2);
BEGIN
UPDATE employess
SET salary = salary + 500;
IF sql%notfound THEN
dbms_output.put_line('no customers selected');
ELSIF sql%found THEN
total_rows := sql%rowcount;
dbms_output.put_line( total_rows || ' customers selected ');
END IF;
END;
/
Explicit Cursors:
Defined by the programmer to have more control over the context and the row processing.
Attributes
- %ISOPEN: Returns TRUE if the cursor is open.
- %FOUND: Returns TRUE if the last fetch returned a row.
- %NOTFOUND: Returns TRUE if the last fetch did not return a row.
- %ROWCOUNT: Returns the number of rows fetched so far.
Example 1:
DECLARE-- Declare cursor
CURSOR emp_cursor IS
SELECT employee_id, employee_name
FROM employees;
-- Declare variables to hold cursor data
v_employee_id employees.employee_id%TYPE;
v_employee_name employees.employee_name%TYPE;
BEGIN
-- Open the cursor
OPEN emp_cursor;
-- Fetch data and process
LOOP
FETCH emp_cursor INTO v_employee_id, v_employee_name;
EXIT WHEN emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('ID: ' || v_employee_id || ' Name: ' || v_employee_name);
END LOOP;
-- Close the cursor
CLOSE emp_cursor;
END;
Example 2:
DECLARE
-- Define an explicit cursor
CURSOR emp_cursor IS
SELECT employee_id, employee_name FROM employees;
-- Variables to hold the fetched data
v_employee_id employees.employee_id%TYPE;
v_employee_name employees.employee_name%TYPE;
-- Variable to count the number of rows fetched
v_row_count INTEGER := 0;
BEGIN
-- Open the cursor
OPEN emp_cursor;
-- Loop to fetch rows and process them
LOOP
FETCH emp_cursor INTO v_employee_id, v_employee_name;
-- Check if there are no more rows to fetch
EXIT WHEN emp_cursor%NOTFOUND;
-- Increment the row count
v_row_count := v_row_count + 1;
-- Display fetched data
DBMS_OUTPUT.PUT_LINE('ID: ' || v_employee_id || ' Name: ' || v_employee_name);
-- Check if cursor is open (it should be)
IF emp_cursor%ISOPEN THEN
DBMS_OUTPUT.PUT_LINE('Cursor is still open.');
END IF;
END LOOP;
-- Display the number of rows fetched
DBMS_OUTPUT.PUT_LINE('Total rows fetched: ' || v_row_count);
-- Check if any rows were found
IF emp_cursor%FOUND THEN
DBMS_OUTPUT.PUT_LINE('At least one row was found.');
ELSE
DBMS_OUTPUT.PUT_LINE('No rows were found.');
END IF;
-- Close the cursor
CLOSE emp_cursor;
-- Check if the cursor is closed (it should be)
IF NOT emp_cursor%ISOPEN THEN
DBMS_OUTPUT.PUT_LINE('Cursor is closed.');
END IF;
-- Check the row count attribute
DBMS_OUTPUT.PUT_LINE('Final row count: ' || emp_cursor%ROWCOUNT);
EXCEPTION
WHEN OTHERS THEN
-- Handle any errors
DBMS_OUTPUT.PUT_LINE('An error occurred: ' || SQLERRM);
IF emp_cursor%ISOPEN THEN
-- Ensure the cursor is closed in case of an error
CLOSE emp_cursor;
END IF;
END;
Bulk Collecter
Bulk Collect is used to fetch multiple rows of data at once into a PL/SQL collection (such as a TABLE or ARRAY). It improves performance by reducing the number of context switches between SQL and PL/SQL engines.Bulk Collect Example:
DECLARETYPE emp_table_type IS TABLE OF employees%ROWTYPE;
emp_table emp_table_type;
BEGIN
SELECT * BULK COLLECT INTO emp_table FROM employees;
FOR i IN 1 .. emp_table.COUNT LOOP
DBMS_OUTPUT.PUT_LINE('ID: ' || emp_table(i).employee_id || ' Name: ' || emp_table(i).employee_name);
END LOOP;
END;
Cursor with Bulk Collect Example:
DECLARECURSOR emp_cursor IS
SELECT employee_id, employee_name FROM employees;
TYPE emp_rec IS RECORD (
employee_id employees.employee_id%TYPE,
employee_name employees.employee_name%TYPE);
TYPE emp_table_type IS TABLE OF emp_rec;
emp_table emp_table_type;
BEGIN
OPEN emp_cursor;
FETCH emp_cursor BULK COLLECT INTO emp_table;
CLOSE emp_cursor;
FOR i IN 1 .. emp_table.COUNT LOOP
DBMS_OUTPUT.PUT_LINE('ID: ' || emp_table(i).employee_id || ' Name: ' || emp_table(i).employee_name);
END LOOP;
END;
Notes:
- Cursors provide a way to process rows one at a time.
- Bulk Collect allows fetching multiple rows at once to improve performance.
- Combining them can be useful for handling large datasets efficiently.
Comments
Post a Comment