tags:

views:

626

answers:

3
+1  A: 

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.

anon
http://dev.mysql.com/doc/refman/5.1/en/connector-odbc-versions.html says the MySQL driver is "Level 1 and Level 2".I believe my oracle driver must be ODBC 2 http://www.oracle.com/technology/software/tech/windows/odbc/index.html I think it makes sense that the insert statement should not have a cursor.. but how am I still getting "maximum cursors exceeded"?
bobobobo
anon
A: 

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.

Gary
You say "inserts do use a cursor" - some evidence for this? They certainly don't on Sybase, SQLServer or MySQL, or if I remember correctly, according to the SQL standard.
anon
It may me a terminology thing.http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14354/chapter2.htm#sthref73"Oracle implicitly declares a cursor for all data definition and data manipulation statements, including SELECT statements (queries) that return only one row"
Gary
+2  A: 

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
Alan
+1 Yes - that will certainly be a problem! Don't know how I missed that :-(
anon
You seem to have edited your post quickly, so I can't see the history - a bad SO feature. Bit don't complicate things - once you call SQLFreeStmt, you can no longer use the statement handle, and tjhis appears to be the questioner's problem, not the cursor stuff, which I think is red herring.
anon