VastbaseE100

基于开源技术的HTAP数据库管理系统。性能优异,稳定可靠,提供诸多专属领域特性。

Menu

执行SQL语句并处理结果

向数据库发出执行SQL的请求时,需要使用语句句柄,并调用SQLExecDirect或SQLExecute发出查询,服务端执行完成后查询的结果将保存在语句句柄中。

执行查询

直接执行

调用SQLAllocHandle()函数获取句柄,调用SQLExecDirect函数执行查询

HSTMT hstmt = SQL_NULL_HSTMT; //语句句柄
ret = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt);
if (!SQL_SUCCEEDED(ret))
{
	printf("failed to allocate stmt handle");
	return;
}
/*执行语句*/
ret = SQLExecDirect(hstmt, (SQLCHAR *) "select * from test", SQL_NTS);
/*获取结果*/
ret = SQLFetch(hstmt);
if (ret == SQL_NO_DATA)
	return;
if (ret == SQL_SUCCESS)
{
char buf[40];
SQLLEN ind;
/*获取列数据*/
	ret = SQLGetData(hstmt, 1, SQL_C_CHAR, buf, sizeof(buf), &ind);
}

预编译方式执行

调用SQLAllocHandle()函数获取句柄,使用SQLPrepare预编译语句,使用SQLBindParameter绑定参数,最后调用SQLExecute执行查询

/*初始化句柄*/
ret = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt);
if (!SQL_SUCCEEDED(ret))
{
	printf("failed to allocate stmt handle");
	exit(1);
}
/*预编译SQL*/
ret = SQLPrepare(hstmt, (SQLCHAR *) "SELECT * FROM testc WHERE c1 = ?", SQL_NTS);
CHECK_STMT_RESULT(ret, "SQLPrepare failed", hstmt);
SQLLEN cbParam1 = SQL_NTS;
/*绑定参数*/
ret = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT,
		SQL_C_CHAR,	/* value type */
		SQL_CHAR,		/* param type */
		20,			/* column size */
		0,			/* dec digits */
		"6",		/* param value ptr */
		0,			/* buffer len */
		&cbParam1		/* StrLen_or_IndPtr */);
CHECK_STMT_RESULT(ret, "SQLBindParameter failed", hstmt);
/*执行*/
ret = SQLExecute(hstmt);
CHECK_STMT_RESULT(ret, "SQLExecute failed", hstmt);
/*获取结果*/
/*获取结果*/
ret = SQLFetch(hstmt);
if (ret == SQL_NO_DATA)
	return;
if (ret == SQL_SUCCESS)
{
char buf[40];
SQLLEN ind;
/*获取列数据*/
	ret = SQLGetData(hstmt, 1, SQL_C_CHAR, buf, sizeof(buf), &ind);
}

使用游标获取结果

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

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

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

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

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

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

示例:

int rc;
int i;
/*关闭自动提交*/
rc = SQLSetConnectAttr(conn, SQL_AUTOCOMMIT, (SQLPOINTER) SQL_AUTOCOMMIT_OFF, 0);
	CHECK_CONN_RESULT(rc, "SQL_AUTOCOMMIT off failed", conn);
/*执行SQL*/
rc = SQLExecDirect(hstmt, (SQLCHAR *) "SELECT 'foo' || g FROM generate_series(1, 3210) g", SQL_NTS);
CHECK_STMT_RESULT(rc, "SQLExecDirect failed", hstmt);
/*获取结果*/
for (;; i++)
{
char buf[40];
	SQLLEN ind;
	rc = SQLFetch(hstmt);
	if (rc == SQL_NO_DATA)
		break;
	if (rc != SQL_SUCCESS)
	{
		char sqlstate[32] = "";
		SQLINTEGER nativeerror;
		SQLSMALLINT textlen;
		SQLGetDiagRec(SQL_HANDLE_STMT, 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", hstmt);
	}

	rc = SQLGetData(hstmt, 1, SQL_C_CHAR, buf, sizeof(buf), &ind);
	CHECK_STMT_RESULT(rc, "SQLGetData failed", hstmt);
}

执行更新

要更改数据(执行一个insert,update或者delete),可以使用SQLExecDirect函数执行完整的SQL,也可以使用预编译的方式绑定参数后再执行。下面的示例将以预编译的方式执行。

删除

rc = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt);
rc = SQLPrepare(hstmt, (SQLCHAR *) "delete from tmptable where c2 = ? ", SQL_NTS);
cbParam1 = SQL_NTS;
rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT,
		SQL_C_CHAR,	/* value type */
		SQL_CHAR,	/* param type */
		20,		/* column size */
		 0,		/* dec digits */
		“testvalue”,		/* param value ptr */
		0,		/* buffer len */
		&cbParam1	/* StrLen_or_IndPtr */);
CHECK_STMT_RESULT(rc, "SQLBindParameter failed", hstmt);
rc = SQLExecute(hstmt);
CHECK_STMT_RESULT(rc, "SQLExecute failed", hstmt);

更新

rc = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt);
rc = SQLPrepare(hstmt, (SQLCHAR *) "update tmptable set c1 = c1+1 where c2 = ? ", SQL_NTS);
cbParam1 = SQL_NTS;
rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT,
		SQL_C_CHAR,	/* value type */
		SQL_CHAR,	/* param type */
		20,		/* column size */
		0,		/* dec digits */
		“testvalue”,		/* param value ptr */
		0,		/* buffer len */
		&cbParam1	/* StrLen_or_IndPtr */);
CHECK_STMT_RESULT(rc, "SQLBindParameter failed", hstmt);
rc = SQLExecute(hstmt);
CHECK_STMT_RESULT(rc, "SQLExecute failed", hstmt);

插入

rc = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt);
rc = SQLPrepare(hstmt, (SQLCHAR *) "INSERT INTO tmptable VALUES (1, ?) ", SQL_NTS);
cbParam1 = SQL_NTS;
rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT,
		SQL_C_CHAR,	/* value type */
		SQL_CHAR,	/* param type */
		20,		/* column size */
		0,		/* dec digits */
		“testvalue”,		/* param value ptr */
		0,		/* buffer len */
		&cbParam1	/* StrLen_or_IndPtr */);
CHECK_STMT_RESULT(rc, "SQLBindParameter failed", hstmt);
rc = SQLExecute(hstmt);
CHECK_STMT_RESULT(rc, "SQLExecute failed", hstmt);

创建或修改数据库对象

要创建、更改或者删除一个类似表或者视图这样的数据库对象, 可以调用SQLExecDirect() 方法.

例如创建表:

HSTMT hstmt = SQL_NULL_HSTMT; //语句句柄
ret = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt);
if (!SQL_SUCCEEDED(ret))
{
	printf("failed to allocate stmt handle");
	return;
}
ret = SQLExecDirect(hstmt, (SQLCHAR *) "create table test(c1 int,c2 int)", SQL_NTS);