VastbaseG100

基于openGauss内核开发的企业级关系型数据库。

Menu

使用游标获取结果

默认情况下,驱动程序将一次性获取查询的所有结果,当某个查询的结果集很庞大时,一次获取所有结果很不合理,因此ODBC驱动程序提供了一种基于数据库游标的结果集处理方法,只获取少量的行缓存在客户端。通过重新定位游标来获取下一批数据。

游标不能在所有情况下使用。有许多限制会使驱动程序一次性获取整个结果集:

  • 连接不能使用自动提交模式 ,因为后端会在事务结束时关闭游标,因此在自动提交模式下,事务结束后,在从游标获取数据之前,游标已经被关闭。

  • UseDeclareFetch参数设置为true,默认缓存 100行数据,为false时将不会使用游标,直接获取整个结果集。

  • 给定的查询语句必须是单条语句,不能是用分号连接在一起的多个语句。

  • 设置fetch size,且fetch size不能为0.

示例:

int rc;
int i;

/*关闭自动提交*/
rc = SQLSetConnectAttr(V_OD_hdbc, SQL_AUTOCOMMIT, (SQLPOINTER) SQL_AUTOCOMMIT_OFF, 0);
	CHECK_CONN_RESULT(rc, "SQL_AUTOCOMMIT off failed", V_OD_hdbc);
	
/*执行SQL*/
rc = SQLExecDirect(V_OD_hstmt, (SQLCHAR *) "SELECT 'foo' || g FROM generate_series(1, 3210) g", SQL_NTS);
CHECK_STMT_RESULT(rc, "SQLExecDirect failed", V_OD_hstmt);

/*获取结果*/
for (;; i++)
{
	char buf[40];
	SQLLEN ind;
	rc = SQLFetch(V_OD_hstmt);
	if (rc == SQL_NO_DATA)
		break;
	if (rc != SQL_SUCCESS)
	{
		char sqlstate[32] = "";
		SQLINTEGER nativeerror;
		SQLSMALLINT textlen;
		SQLGetDiagRec(SQL_HANDLE_STMT, V_OD_hstmt, 1, sqlstate, &nativeerror, NULL, 0, &textlen);
 /*在读取游标的过程中,如果调用用SQLEndTran提交或回滚了事务,游标将被关闭*/
		if (strcmp(sqlstate, "HY010") == 0)
		{
			printf("SQLFetch failed with HY010 (which probably means that the cursor was closed at commit/rollback)");
			break;
		}
		else
			CHECK_STMT_RESULT(rc, "SQLGetDiagRec failed", V_OD_hstmt);
	}
	rc = SQLGetData(V_OD_hstmt, 1, SQL_C_CHAR, buf, sizeof(buf), &ind);
	CHECK_STMT_RESULT(rc, "SQLGetData failed", V_OD_hstmt);
}