Cursor declaration and usage in PostgreSQL - Time & Space Complexity
Start learning this pattern below
Jump into concepts and practice - no test required
When using cursors in PostgreSQL, it's important to understand how the time to process data grows as the amount of data increases.
We want to know how the number of steps changes when we fetch rows one by one using a cursor.
Analyze the time complexity of the following cursor usage in PostgreSQL.
DECLARE my_cursor CURSOR FOR
SELECT id, name FROM employees;
OPEN my_cursor;
LOOP
FETCH my_cursor INTO emp_id, emp_name;
EXIT WHEN NOT FOUND;
-- process each employee row here
END LOOP;
CLOSE my_cursor;
This code declares a cursor to select all employees, then fetches and processes each row one at a time.
Look for repeated actions in the code.
- Primary operation: Fetching one row from the cursor inside the loop.
- How many times: Once for each row in the result set.
As the number of rows grows, the number of fetch operations grows the same way.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 fetches |
| 100 | 100 fetches |
| 1000 | 1000 fetches |
Pattern observation: The work grows directly with the number of rows; doubling rows doubles the fetches.
Time Complexity: O(n)
This means the time to process grows linearly with the number of rows fetched by the cursor.
[X] Wrong: "Using a cursor makes the query run faster because it processes rows one by one."
[OK] Correct: The cursor still processes every row; it just controls how rows are fetched. The total work depends on the number of rows, not on using a cursor.
Understanding how cursors work and their time cost helps you explain data processing choices clearly and confidently in real projects.
"What if we fetched multiple rows at once instead of one by one? How would the time complexity change?"
Practice
Solution
Step 1: Understand what a cursor does
A cursor allows you to handle query results row by row instead of all at once.Step 2: Compare options with cursor purpose
Only To process query results one row at a time describes this behavior; others describe unrelated tasks.Final Answer:
To process query results one row at a time -> Option BQuick Check:
Cursor purpose = process rows one by one [OK]
- Confusing cursors with table creation
- Thinking cursors speed up inserts
- Assuming cursors automate backups
cur_emp for selecting all rows from employees table?Solution
Step 1: Recall cursor declaration syntax
In PostgreSQL, cursors are declared with DECLARE cursor_name CURSOR FOR query.Step 2: Match syntax with options
DECLARE cur_emp CURSOR FOR SELECT * FROM employees; matches this exactly; others use incorrect keywords or order.Final Answer:
DECLARE cur_emp CURSOR FOR SELECT * FROM employees; -> Option CQuick Check:
DECLARE + CURSOR + FOR + query = correct syntax [OK]
- Using OPEN instead of DECLARE for declaration
- Confusing FETCH with DECLARE
- Using CREATE CURSOR which is invalid syntax
DECLARE cur_emp CURSOR FOR SELECT id FROM employees ORDER BY id LIMIT 3; OPEN cur_emp; FETCH NEXT FROM cur_emp; FETCH NEXT FROM cur_emp;
Solution
Step 1: Understand cursor declaration and fetch
The cursor selects 3 employee ids ordered ascending. FETCH NEXT retrieves one row each time.Step 2: Analyze fetch calls
Two FETCH NEXT calls return the first two rows from the cursor result.Final Answer:
First two employee ids in ascending order -> Option AQuick Check:
Two FETCH NEXT = two rows fetched [OK]
- Assuming FETCH returns all rows at once
- Thinking missing CLOSE causes syntax error
- Believing cursor must be closed before fetching
DECLARE cur_dept CURSOR FOR SELECT name FROM departments; FETCH NEXT FROM cur_dept; OPEN cur_dept; CLOSE cur_dept;
Solution
Step 1: Check the order of cursor operations
Cursors must be declared, then opened, then fetched, then closed.Step 2: Identify incorrect sequence
Here, FETCH is called before OPEN, which is invalid.Final Answer:
Cursor is fetched before it is opened -> Option DQuick Check:
OPEN must precede FETCH [OK]
- Fetching before opening cursor
- Closing cursor before opening
- Misordering declaration and fetch
orders table one by one using a cursor in a PL/pgSQL function. Which sequence of statements correctly implements this?Solution
Step 1: Understand correct cursor usage in PL/pgSQL
Declare cursor, open it, then loop fetching rows until no more rows, then close cursor.Step 2: Analyze each option
DECLARE cur_orders CURSOR FOR SELECT * FROM orders; OPEN cur_orders; LOOP FETCH cur_orders INTO rec; EXIT WHEN NOT FOUND; -- process rec END LOOP; CLOSE cur_orders; follows correct order and uses LOOP with EXIT WHEN NOT FOUND to process all rows. Others have wrong order or invalid FETCH ALL.Final Answer:
DECLARE cur_orders CURSOR FOR SELECT * FROM orders; OPEN cur_orders; LOOP FETCH cur_orders INTO rec; EXIT WHEN NOT FOUND; -- process rec END LOOP; CLOSE cur_orders; -> Option AQuick Check:
Declare, Open, Loop Fetch, Close = correct pattern [OK]
- Opening cursor before declaring
- Fetching before opening
- Using FETCH ALL which is invalid for cursors
