Database ProgrammingUnit 610 min read
PL/SQL Records, Collections & Cursors: Data Handling & Control
Unit 6 of Database Programming: Explores PL/SQL’s advanced data structures (records, collections) and cursor mechanics to manipulate datasets efficiently, with practical examples like employee payroll processing and dynamic query execution.
TAKEAWAYS:
- Records in PL/SQL mirror database rows but allow in-memory manipulation before database commits.
- Collections (associative arrays, nested tables) store heterogeneous data dynamically, replacing multiple variables.
- Cursors enable row-by-row processing of query results, with explicit control over iteration (OPEN-FETCH-CLOSE).
- Explicit cursors (user-defined) replace implicit cursors (SQL*Plus defaults) for fine-grained result handling.
- Collections reduce procedural code by bundling related data (e.g., inventory items, order details).
- Cursor FOR loops simplify iteration with automatic OPEN/FETCH/CLOSE, but explicit cursors offer full control.
1. PL/SQL Records: Structured Data in Memory
Definition: A record is a PL/SQL data type that groups multiple fields (like a database row) into a single variable. Unlike database rows, records exist in memory and can be modified before committing to the database.
How It Works:
- Declared using
%ROWTYPE(to mirror a table’s structure) or explicitly with field names and types. - Fields can be accessed like an object (e.g.,
record_name.field_name). - Used to pass row data between PL/SQL blocks or store intermediate results.
Example: Employee Record
classDiagram
EmployeeRecord : +String emp_id
EmployeeRecord : +String emp_name
EmployeeRecord : +Number salaryDECLARE
TYPE emp_rec IS RECORD (
emp_id VARCHAR2(10),
emp_name VARCHAR2(50),
salary NUMBER(10,2)
);
v_emp emp_rec;
BEGIN
-- Fetch a row into the record
SELECT emp_id, emp_name, salary INTO v_emp
FROM employees
WHERE emp_id = 'E1001';
-- Modify salary in memory
v_emp.salary := v_emp.salary * 1.1; -- 10% raise
-- Commit changes (if needed)
UPDATE employees
SET salary = v_emp.salary
WHERE emp_id = 'E1001';
END;
Advantages:
- Memory efficiency: Avoids repeated database calls for small updates.
- Readability: Clearly defines related data fields.
- Flexibility: Can be used in collections or passed as parameters.
Disadvantages:
- Static structure: Fields cannot be added/removed dynamically (unlike collections).
- Limited to one row: For multi-row operations, use cursors or collections.
2. PL/SQL Collections: Dynamic Data Storage
Definition: Collections are variable-sized arrays in PL/SQL that store heterogeneous data (unlike arrays, which require fixed types). Two types:
- Associative Arrays (indexed by strings/numbers).
- Nested Tables (ordered, indexed by position).
How It Works:
- Declared with
TYPEandVARRAY(variable-length array) orTABLE(ordered table). - Elements accessed via
collection_name(index). - Used to return multiple rows from procedures or store intermediate results.
Example: Inventory Collection
classDiagram
InventoryCollection : +VARRAY<STRING> item_names
InventoryCollection : +VARRAY<NUMBER> quantitiesDECLARE
TYPE item_varray IS VARRAY(10) OF VARCHAR2(50);
TYPE qty_varray IS VARRAY(10) OF NUMBER;
v_items item_varray := item_varray('Laptop', 'Mouse', 'Keyboard');
v_quantities qty_varray := qty_varray(10, 50, 20);
BEGIN
-- Display inventory
FOR i IN 1..v_items.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(v_items(i) || ': ' || v_quantities(i));
END LOOP;
END;
Comparison Table: Collections vs. Records
| Feature | Records | Collections |
|---|---|---|
| Size | Fixed (1 row) | Dynamic (variable-length) |
| Data Type | Homogeneous (mirrors a row) | Heterogeneous (mixed types) |
| Indexing | No index (field names only) | Indexed (numeric or string) |
| Use Case | Single-row manipulation | Multi-row storage/processing |
| Example | emp_rec %ROWTYPE |
v_items VARRAY(10) OF VARCHAR2 |
Real-World Use: Daraz Order Processing Daraz uses collections to bundle multiple product items in a single order. For example:
- A customer orders:
- 2 laptops (
item_names[1..2] = 'Laptop') - 1 mouse (
item_names[3] = 'Mouse')
- 2 laptops (
- Quantities are stored in a parallel collection (
quantities[1] = 2,quantities[2] = 1). - The system processes payments and inventory updates in bulk using these collections.
3. Cursors: Row-by-Row Processing
Definition: A cursor is a pointer to a SQL query result set, allowing row-by-row processing in PL/SQL. Two types:
- Implicit Cursors: Default in SQL*Plus (e.g.,
SELECT INTO). - Explicit Cursors: User-defined for complex processing (e.g., loops, bulk operations).
How It Works:
- DECLARE: Define the cursor with a SQL query.
- OPEN: Execute the query.
- FETCH: Retrieve rows one by one.
- CLOSE: Release resources.
Example: Employee Salary Report
sequenceDiagram
participant PL/SQL
participant DB
PL/SQL->>DB: DECLARE emp_cursor CURSOR FOR SELECT * FROM employees;
PL/SQL->>DB: OPEN emp_cursor;
loop For each row
PL/SQL->>DB: FETCH emp_cursor INTO v_emp;
PL/SQL->>PL/SQL: Process v_emp (e.g., print salary)
end
PL/SQL->>DB: CLOSE emp_cursor;DECLARE
CURSOR emp_cursor IS SELECT emp_id, emp_name, salary FROM employees;
v_emp employees%ROWTYPE;
BEGIN
OPEN emp_cursor;
LOOP
FETCH emp_cursor INTO v_emp;
EXIT WHEN emp_cursor%NOTFOUND; -- Exit if no more rows
DBMS_OUTPUT.PUT_LINE(v_emp.emp_name || ': ' || v_emp.salary);
END LOOP;
CLOSE emp_cursor;
END;
Explicit vs. Implicit Cursors
| Feature | Implicit Cursor | Explicit Cursor |
|---|---|---|
| Declaration | Automatic (SQL*Plus) | Manual (DECLARE CURSOR) |
| Control | Limited (e.g., SELECT INTO) |
Full (OPEN/FETCH/CLOSE) |
| Use Case | Simple queries | Complex processing (loops, bulk) |
| Example | SELECT salary INTO v_sal FROM emp; |
CURSOR emp_cursor FOR SELECT * FROM emp; |
Real-World Use: Bank Loan Processing A bank uses explicit cursors to process loan applications dynamically:
- A cursor fetches all pending loans (
SELECT * FROM loans WHERE status = 'Pending'). - For each loan, the system checks credit scores and updates the database.
- The cursor ensures only one loan is processed at a time, avoiding race conditions.
4. Collections in Practice: Associative Arrays
Definition: An associative array is a collection indexed by strings or numbers (not just sequential integers). Useful for mapping keys to values (e.g., employee IDs to salaries).
Example: Employee Salary Map
classDiagram
SalaryMap : +ASSOCIATIVE ARRAY<STRING, NUMBER>
SalaryMap : +'E1001' --> 50000
SalaryMap : +'E1002' --> 60000DECLARE
TYPE emp_salary_map IS TABLE OF NUMBER INDEX BY VARCHAR2(10);
v_salaries emp_salary_map;
BEGIN
-- Populate the map
v_salaries('E1001') := 50000;
v_salaries('E1002') := 60000;
-- Retrieve a salary
DBMS_OUTPUT.PUT_LINE('E1001 salary: ' || v_salaries('E1001'));
END;
Advantages:
- Key-based access: Faster than sequential arrays for large datasets.
- Dynamic sizing: Add/remove elements without redeclaring.
- Flexibility: Indexes can be strings (e.g., employee IDs).
Disadvantages:
- Memory overhead: Each element stores its key and value.
- No ordering: Unlike nested tables, elements are not ordered.
5. Cursors FOR Loops: Simplified Iteration
Definition: A cursor FOR loop automates the OPEN/FETCH/CLOSE cycle, reducing boilerplate code.
Syntax:
FOR record_variable IN cursor_name LOOP
-- Process each row
END LOOP;
Example: Display All Employees
DECLARE
CURSOR emp_cursor IS SELECT emp_id, emp_name FROM employees;
BEGIN
FOR emp_rec IN emp_cursor LOOP
DBMS_OUTPUT.PUT_LINE(emp_rec.emp_id || ': ' || emp_rec.emp_name);
END LOOP;
-- No need for OPEN/CLOSE; cursor is closed automatically
END;
When to Use:
- Simple iteration: When you don’t need manual control over fetching.
- Read-only operations: Avoids explicit error handling for
%NOTFOUND.
Limitations:
- No manual control: Cannot fetch rows out of order or skip rows.
- Less flexible: Cannot use
FETCHwith conditions likeWHEN OTHERS.
In the Real World
Khalti Payment Gateway:
- Uses collections to bundle multiple payment methods (e.g., credit card, UPI, eSewa) into a single transaction request.
- Example: A user’s payment options are stored in a
VARRAYofpayment_methods, which the system processes sequentially.
NTC Traffic Management:
- Cursors dynamically fetch real-time traffic data (e.g., congestion levels) from sensors.
- The system uses an explicit cursor to process each sensor’s data, updating traffic lights in real time.
Ncell Call Routing:
- Associative arrays map phone numbers to subscriber details (e.g.,
v_subscribers('9812345678')returns a record). - When a call comes in, the system quickly looks up the subscriber’s plan and routes the call accordingly.
- Associative arrays map phone numbers to subscriber details (e.g.,
Exam Tip
- Focus on syntax: Explicit cursors (
DECLARE CURSOR...) and collections (TYPE...VARRAY) are high-weight topics. Memorize their declarations and usage. - Compare implicit vs. explicit cursors: Always include a table like the one above to show differences.
- Worked examples: Practice writing a cursor FOR loop and a collection-based procedure (e.g., updating salaries for all employees in a department).
- Collections > Records: For multi-row operations, collections are almost always the right tool. Records are for single-row manipulation.
- Error handling: Include
WHEN OTHERSin cursor examples to handle%NOTFOUNDgracefully. - Real-world tie-ins: Relate collections to Daraz orders or cursors to bank transactions. Examiners love practical examples.
A flowchart showing the steps of an explicit cursor (DECLARE → OPEN → FETCH → LOOP → CLOSE).
A table comparing associative arrays (key-value pairs) and nested tables (ordered lists) with icons for each.
A side-by-side diagram of a SQL cursor (implicit) and a PL/SQL cursor (explicit), highlighting control steps.
Based on the TU BCA syllabus for Database Programming (CACS484), unit 6.
Discussion
Loading…