ORA-01000: Maximum Open Cursors Exceeded — What You Need to Know
ORA-01000 is one of the most common Oracle errors encountered in production environments. It occurs when a database session attempts to open more cursors than the limit defined by the OPEN_CURSORS initialization parameter. This typically signals a cursor leak in application code, an undersized parameter value, or inefficient SQL that skips bind variables.
Top 3 Causes
1. Cursor Leaks in Application Code
The most frequent culprit. When applications open cursors (via JDBC statements, Python cx_Oracle calls, etc.) without explicitly closing them, cursors accumulate over time until the limit is hit.
-- Identify sessions with the most open cursors
SELECT s.sid,
s.username,
s.machine,
s.program,
COUNT(c.cursor#) AS open_cursors
FROM v$session s
JOIN v$open_cursor c ON s.saddr = c.saddr
WHERE s.username IS NOT NULL
GROUP BY s.sid, s.username, s.machine, s.program
ORDER BY open_cursors DESC
FETCH FIRST 10 ROWS ONLY;
2. OPEN_CURSORS Parameter Set Too Low
The default value of OPEN_CURSORS (typically 300) may be insufficient for large-scale applications with many concurrent users or complex PL/SQL packages.
-- Check current parameter value
SELECT name, value
FROM v$parameter
WHERE name = 'open_cursors';
-- Increase the limit dynamically (no restart required)
ALTER SYSTEM SET open_cursors = 1000 SCOPE = BOTH;
3. Missing Bind Variables Causing Excessive Hard Parsing
When SQL statements use literal values instead of bind variables, Oracle treats each variation as a unique query and opens a new cursor for each one, rapidly exhausting the cursor pool.
-- BAD: Each execution creates a new cursor
SELECT * FROM orders WHERE order_id = 5001;
SELECT * FROM orders WHERE order_id = 5002;
SELECT * FROM orders WHERE order_id = 5003;
-- GOOD: Single cursor reused with bind variable
SELECT * FROM orders WHERE order_id = :order_id;
-- Check SQL statements consuming the most cursors
SELECT sql_text,
COUNT(*) AS cursor_count
FROM v$open_cursor
GROUP BY sql_text
ORDER BY cursor_count DESC
FETCH FIRST 15 ROWS ONLY;
Quick Fix Solutions
Step 1: Temporarily increase OPEN_CURSORS to restore service immediately.
ALTER SYSTEM SET open_cursors = 1000 SCOPE = BOTH;
Step 2: Always close cursors explicitly in PL/SQL, especially in exception handlers.
DECLARE
CURSOR c_emp IS
SELECT employee_id, salary FROM employees WHERE department_id = :dept;
BEGIN
OPEN c_emp;
-- fetch and process rows ...
CLOSE c_emp;
EXCEPTION
WHEN OTHERS THEN
IF c_emp%ISOPEN THEN
CLOSE c_emp;
END IF;
RAISE;
END;
/
Step 3: Enable session cursor caching to improve reuse.
-- Boost cursor cache at system level
ALTER SYSTEM SET session_cached_cursors = 100 SCOPE = SPFILE;
-- Verify cursor cache effectiveness
SELECT name, value
FROM v$sysstat
WHERE name IN ('session cursor cache hits', 'parse count (total)');
Prevention Tips
-
Monitor cursor usage proactively. Set up alerts when cursor usage exceeds 80% of the
OPEN_CURSORSlimit. Review AWR reports weekly for cursor-related statistics. -
Enforce coding standards. Mandate the use of bind variables and require explicit resource cleanup (try-with-resources in Java,
withstatements in Python) in all code reviews. Configure connection pool settings (maxStatements, Statement Cache) to maximize cursor reuse across transactions.
Proper cursor management is a shared responsibility between DBAs and developers. Addressing ORA-01000 at the root — through code fixes and proactive monitoring — is far more effective than simply raising the parameter limit.
📖 Want a more detailed guide?
Check out the full in-depth version (Korean) on oraerror.com — includes detailed analysis, additional SQL examples, and prevention tips.
Top comments (0)