我有大量的INSERT语句要运行。当我运行它们时,我可以理解地得到“超出最大开放游标数”。
确定Oracle,因此我将在运行INSERT语句后立即关闭游标。
SQLCloseCursor( hStmt )
但Oracle对此说“无效的游标状态。”
为什么Oracle对我关闭游标不满意?我通过MySQL dsn测试了这种相同类型的查询,并且MySQL似乎没有抱怨在INSERT语句之后立即关闭游标。
编辑 -
以下是执行查询的代码
CHECK是一个检查SQLRESULT并记录错误的函数,如果有的话,如果成功则返回TRUE,如果失败则返回FALSE。 “status()”使用SQLGetDiagRec()记录其余的错误信息。
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 ; }
我称之为非查询
nonquery( "sql statement" ) ;
所以我得到了:
[24000][0] [Oracle][ODBC]Invalid cursor state.
首先,(可能是由于INSERT语句没有游标?),之后,经过多次插入(非查询简单地称为多次,连续多次),我得到了
ORA-01000: maximum open cursors exceeded
答案 0 :(得分:1)
我有大量的INSERT 要运行的语句。当我跑他们的时候,我 可以理解得到“最大限度开放 游标超过了“。
实际上,这对我没有意义 - INSERT语句不使用游标。你确定这是你得到的错误这可以解释你为什么得到:
SQLCloseCursor(hStmt)
但甲骨文对此说“无效” 光标状态。“
因为没有光标。
MySQL不抱怨的事实可能是由于驱动程序的差异。它们都是ODBC 3.0吗?
修改:看了你的代码,我有两个问题。首先,我们能看到导致问题的SQL命令吗?其次,SQLRowCount是一个有点可疑的功能 - 许多数据库不支持某些查询类型,我可以看到它本身可能需要一个游标。您可以尝试使用不调用SQLRowCount的函数版本吗?
编辑2:认为Alan确定了您的问题。你释放一个语句,然后在它上面调用clopse游标 - 这是ODBC未定义的。如果你真的认为你需要在释放语句之前关闭它(我没有)关闭它。
答案 1 :(得分:1)
我认为你正在关闭光标两次:
SQLFreeStmt(SQL_ CLOSE)
- 来自MSDN:“关闭与StatementHandle关联的游标(如果已定义)并丢弃所有待处理结果”
因此,调用SQLCloseCursor将返回“无效的游标状态”(参见Note)。
我认为你需要的是:
SQLCloseCursor(hStmt);
SQLFreeHandle(SQL_HANDLE_STMT,hStmt) // replace SQLFreeStmt with this
答案 2 :(得分:0)
插入确实使用游标。如果要进行大量插入,则应该重用光标。 模式应该是
OPEN cursor
start loop
BIND variables
EXECUTE CURSOR
end loop
CLOSE cursor
在你的情况下,我没有看到一个明确的打开游标,所以我猜你依靠c ++来隐式地管理它,而且它似乎没有做得很好。根据代码here判断,您需要将SQLPrepare放入逻辑中。