Reputation: 67276
I have a large number of INSERT statments to run. As I run them, I understandably get "maximum open cursors exceeded".
OK Oracle, so I will close the cursors immediately after running the INSERT statements.
SQLCloseCursor( hStmt )
But Oracle says to this "Invalid cursor state."
Why is Oracle not happy with me closing the cursor? I tested this same type of query out through a MySQL dsn and MySQL doesn't seem to complain about closing a cursor immediately after an INSERT statement.
edit --
Here is the code that executes the query
CHECK is a function that checks an SQLRESULT and logs error if any returns TRUE if successful, FALSE if failure. "status()" uses SQLGetDiagRec() to log the rest of the error info.
SQLINTEGER nonquery( char * nonquery ) { SQLINTEGER rowsAffected = 0 ; SQLHANDLE hStmt ; CHECK( SQLAllocHandle( SQL_HANDLE_STMT, hConn, &hStmt ), "allocate handle for statement" ) ; if( !CHECK( SQLExecDirectA( hStmt, (SQLCHAR*)nonquery, SQL_NTS ), "execute query" ) ) { status( SQL_HANDLE_STMT, hStmt, __LINE__ ) ; } // Get rows affected if( !CHECK( SQLRowCount( hStmt, &rowsAffected ), "row count after non-query" ) ) { status( SQL_HANDLE_STMT, hStmt, __LINE__ ) ; } if( ! CHECK( SQLFreeStmt( hStmt, SQL_CLOSE ), "Sql free stmt" ) ) { status( SQL_HANDLE_STMT, hStmt, __LINE__ ) ; } // CLose up. if( !CHECK( SQLCloseCursor( hStmt ), "close cursor" ) ) { status( SQL_HANDLE_STMT, hStmt, __LINE__ ) ; } return rowsAffected ; }
I call nonquery like so
nonquery( "sql statement" ) ;
So I'm getting:
[24000][0] [Oracle][ODBC]Invalid cursor state.
At first, (which might be due to an INSERT statement has no cursor?), and later, after many inserts (nonquery is simply called many, many times in a row), I get
ORA-01000: maximum open cursors exceeded
Upvotes: 1
Views: 3443
Reputation:
I have a large number of INSERT statments to run. As I run them, I understandably get "maximum open cursors exceeded".
Actually, this doesn't make sense to me - INSERT statements don't use a cursor. Are you sure this is the error you are getting This would explain why you get:
SQLCloseCursor( hStmt )
But Oracle says to this "Invalid cursor state."
as there would be no cursor.
The fact that MySQL doesn't complain could be due to differences in the drivers. Are they both ODBC 3.0?
Edit: Having looked at your code, I have two questions. Firstly, could we see the SQL commands that cause the problem? Secondly, SQLRowCount is a somewhat dubious function - many databases cannot support it for certain query types, and I can see how it might need a cursor itself. Can you try using a version of your function that doesn't call SQLRowCount?
Edit2: Think that Alan has identified your problem. You free a statement and then call clopse cursor on it - this is undefined by ODBC. If you really think you need to close a cursor (which I don't) close it before freeing the statement.
Upvotes: 1
Reputation: 13731
I think you're closing the cursor twice:
SQLFreeStmt(SQL_ CLOSE)
- From the MSDN: "Closes the cursor associated with StatementHandle (if one was defined) and discards all pending results"
Therefore, calling SQLCloseCursor will return a "Invalid Cursor State" (see Note).
I think what you need is:
SQLCloseCursor(hStmt);
SQLFreeHandle(SQL_HANDLE_STMT,hStmt) // replace SQLFreeStmt with this
Upvotes: 1
Reputation: 35401
Inserts do use a cursor. If you are doing lots of inserts, you should be reusing the cursor. The pattern should be
OPEN cursor
start loop
BIND variables
EXECUTE CURSOR
end loop
CLOSE cursor
In your case, I don't see an explicit open cursor, so I'd guess you are relying on c++ to manage that implicitly, and it doesn't seem to be doing a good job. Judging by the code here you need to fit SQLPrepare into the logic.
Upvotes: 0