2009-07-18 26 views
1

我有大量的INSERT语句要运行。当我运行它们时,我理解地获得了“超出最大游标数”。尝试关闭时光标状态无效

OK Oracle,所以我将在运行INSERT语句后立即关闭游标。

 
SQLCloseCursor(hStmt) 

但是Oracle对此表示“无效的游标状态”。

为什么Oracle不满意我关闭游标?我通过My​​SQL dsn测试了这种相同类型的查询,MySQL似乎没有抱怨在INSERT语句后立即关闭游标。

编辑 -

下面是执行查询

检查是检查的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像这样

 
nonquery("sql statement") ; 

所以我得到:(?这可能是由于INSERT语句没有光标)

 
[24000][0] [Oracle][ODBC]Invalid cursor state. 

起初,后来,在许多插入(非查询简单地称为许多,连续多次)后,我得到

 
ORA-01000: maximum open cursors exceeded 

回答

1

我有大量的INSERT statments来运行。当我运行它们时,我可以理解为 “最大打开 游标超出”。

实际上,这对我没有意义 - INSERT语句不使用游标。你确定这是你得到这为什么你会解释错误:

SQLCloseCursor(HSTMT)

但Oracle说这个“无效 光标状态。”

因为没有光标。

MySQL没有抱怨的事实可能是由于驱动程序的差异。他们都是ODBC 3.0吗?

编辑:看了你的代码,我有两个问题。首先,我们可以看到导致问题的SQL命令吗?其次,SQLRowCount是一个有点可疑的函数 - 许多数据库不能支持某些查询类型,我可以看到它可能需要一个游标本身。你可以尝试使用不调用SQLRowCount的函数版本吗?

编辑2:认为艾伦已经确定了您的问题。你释放一个语句,然后调用clopse游标 - 这是由ODBC未定义的。如果你真的认为你需要关闭一个游标(我不这么做),在释放语句之前关闭游标。

+0

http://dev.mysql.com/doc/refman/5.1/en/connector-odbc-versions.html说MySQL驱动是“1级和2级“。 我相信我的oracle驱动程序必须是ODBC 2 http://www.oracle.com/technology/software/tech/windows/odbc/index.html 我认为这是有道理的,插入语句不应该有一个游标..但我仍然如何“超过最大游标”? – bobobobo 2009-07-18 19:06:42

+0

MSDN说“无效光标”只能由3.0驱动程序返回。我会忘记MySQL并专注于甲骨文 - 你可以发布一个小例子来说明问题吗?您可能还想在更面向Oracle的网站上发布该问题,因为我的印象不是太多,所以常客使用它 - 恐怕我自己也不会。 – 2009-07-18 19:12:40

0

插入使用游标。如果你正在做很多插入,你应该重新使用光标。 上的图案应该

OPEN cursor 
    start loop 
    BIND variables 
    EXECUTE CURSOR 
    end loop 
CLOSE cursor 

在你的情况,我没有看到一个明确的打开的游标,所以我猜你是依靠C++隐含管理这一点,这似乎并没有做一份好工作。通过代码here来判断,您需要将SQLPrepare放入逻辑中。

+0

你说“插入使用光标” - 这方面的一些证据?根据SQL标准,它们当然不在Sybase,SQLServer或MySQL上,或者如果我没有记错的话。 – 2009-07-18 22:35:22

1

我想你关闭游标两次:

SQLFreeStmt(SQL_ CLOSE) - 从MSDN:“关闭与StatementHandle关联的游标(如果定义),并丢弃所有待处理结果

因此,调用SQLCloseCursor将返回“无效光标状态”(请参见Note)。

我想你需要的是:

SQLCloseCursor(hStmt); 

SQLFreeHandle(SQL_HANDLE_STMT,hStmt) // replace SQLFreeStmt with this 
相关问题