尝试关闭时光标状态无效

发布于 2024-07-27 04:13:08 字数 1528 浏览 2 评论 0原文

我有大量的 INSERT 语句要运行。 当我运行它们时,我可以理解地得到“超出最大打开游标数”。

OK 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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

谁许谁一生繁华 2024-08-03 04:13:08

我认为您关闭了游标两次:

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

因此,调用 SQLCloseCursor 将返回“无效的光标状态”(请参阅​​注意)。

我认为你需要的是:

SQLCloseCursor(hStmt);

SQLFreeHandle(SQL_HANDLE_STMT,hStmt) // replace SQLFreeStmt with this

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
蓦然回首 2024-08-03 04:13:08

我有大量的INSERT
要运行的语句。 当我运行它们时,我
可以理解的是获得“最大开放
光标超出”。

实际上,这对我来说没有意义 - INSERT 语句不使用游标。您确定这是您收到的错误吗这将解释您收到的原因:

SQLCloseCursor( hStmt )

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

因为不会有光标。MySQL

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

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

认为 Alan 已确定您的问题,然后对其调用 clopse 游标 - 这是 ODBC 未定义的。您确实认为需要关闭游标(我不这样做),然后在释放语句之前将其关闭。

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.

对你的占有欲 2024-08-03 04:13:08

插入确实使用光标。 如果您要进行大量插入,则应该重用游标。
模式应该是

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

在你的情况下,我没有看到显式打开的游标,所以我猜你依赖 c++ 来隐式管理它,而且它似乎做得不好。 从此处的代码来看,您需要适合SQLPrepare进入逻辑。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文