GBase 8a
运维管理
文章

通过ODBC连接GBase8a集群

发表于2025-09-27 08:10:4121次浏览3个评论

ODBC全称Open Database Connectivity(开放数据库互连),是微软公司开放服务结构(WOSA,Windows Open Services Architecture)中有关数据库的一个组成部分,它建立了一组规范,并提供了一组对数据库访问的标准API。GBase8a也实现了ODBC接口。

ODBC连接集群代码例子:

#include <unistd.h>
#include <stdio.h>
#include <sql.h>
#include <sqlext.h>
#include <stdlib.h>
#include <string.h>

#define FAIL 1

#define ok_stmt(statement, call)                                                 \
	do                                                                           \
	{                                                                            \
		SQLRETURN rc = (call);                                                   \
		print_diag(rc, SQL_HANDLE_STMT, (statement), #call, __FILE__, __LINE__); \
		if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)                    \
			return FAIL;                                                         \
	} while (0)

#define ok_con(con, call)                                                 \
	do                                                                    \
	{                                                                     \
		SQLRETURN rc = (call);                                            \
		print_diag(rc, SQL_HANDLE_DBC, (con), #call, __FILE__, __LINE__); \
		if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)             \
			return FAIL;                                                  \
	} while (0)

#define ok_env(environ, call)                                                 \
	do                                                                        \
	{                                                                         \
		SQLRETURN rc = (call);                                                \
		print_diag(rc, SQL_HANDLE_ENV, (environ), #call, __FILE__, __LINE__); \
		if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)                 \
			return FAIL;                                                      \
	} while (0)

#define ok_con(con, call)                                                 \
	do                                                                    \
	{                                                                     \
		SQLRETURN rc = (call);                                            \
		print_diag(rc, SQL_HANDLE_DBC, (con), #call, __FILE__, __LINE__); \
		if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)             \
			return FAIL;                                                  \
	} while (0)

char *connStr = "DRIVER=/usr/lib64/libgsodbc8.so;"  //可以是ODBC库文件的绝对路径,也可以是/etc/odbcinst.ini文件中的驱动名称
                "UID=gbase;PWD=gbase20110531;PORT=5258;"
				"SERVER={192.168.105.102};"
				"DATABASE=test;";

SQLHDBC hdbc;
SQLHENV henv;

void print_diag(SQLRETURN rc, SQLSMALLINT htype, SQLHANDLE handle, const char *text, const char *file, int line)
{
	if (rc != SQL_SUCCESS)
	{
		SQLCHAR sqlstate[6], message[SQL_MAX_MESSAGE_LENGTH];
		SQLINTEGER native_error;
		SQLSMALLINT length;
		SQLRETURN drc;
		/** @todo map rc to SQL_SUCCESS_WITH_INFO, etc */
		printf("# %s = %d\n", text, rc);
		/** @todo Handle multiple diagnostic records. */
		drc = SQLGetDiagRec(htype, handle, 1, sqlstate, &native_error, message, SQL_MAX_MESSAGE_LENGTH - 1, &length);
		if (SQL_SUCCEEDED(drc))
			printf("# [%6s] %*s in %s on line %d\n", sqlstate, length, message, file, line);
		else
			printf("# Did not get expected diagnostics from SQLGetDiagRec() = %d in file %s on line %d\n", drc, file, line);
	}
}

int print_select(SQLHSTMT hstmt, char *sql)
{
	int num_cols = 0;
	int i = 0;
	int buff_len = 1024;
	int val_len = 0;
	SQLSMALLINT col_type, tnum = 0;
	unsigned char *buff = (unsigned char *)malloc(buff_len);
	SQLExecDirect(hstmt, sql, SQL_NTS);
	ok_stmt(hstmt, SQLNumResultCols(hstmt, &tnum));
	num_cols = tnum;
	for (i = 1; i <= num_cols; i++)
	{
		ok_stmt(hstmt, SQLDescribeCol(hstmt, i, buff, buff_len,
									  NULL, NULL, NULL, NULL, NULL));
		printf("|%s\t", buff);
	}
	printf("\n");
	for (i = 1; i <= num_cols; i++)
	{
		printf("--------");
	}
	printf("\n");
	while (SQL_SUCCESS == SQLFetch(hstmt))
	{
		for (i = 1; i <= num_cols; i++)
		{
			col_type = 0;
			memset(buff, 0, buff_len);
			val_len = 0;
			ok_stmt(hstmt, SQLGetData(hstmt, i, SQL_C_CHAR, buff, (SQLLEN)buff_len, (SQLLEN *)&val_len));
			printf("|%s\t", buff);
		}
		printf("\n");
	}
	free(buff);
	return 0;
}

int demo_select(char *sql_select)
{
	SQLHSTMT hstmt;
	printf("exec sql:\n\t%s\n", sql_select);
	ok_con(hdbc, SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt));
	printf("select result:\n");
	print_select(hstmt, sql_select);
	return 0;
}

int main(int argc, char **argv)
{
	char *sql_select = "select '这是测试' as x";
	ok_env(henv, SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv));  
	ok_env(henv, SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0));
	ok_env(henv, SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc));
	ok_con(hdbc, SQLDriverConnect(hdbc, NULL, connStr, SQL_NTS, NULL, 0, NULL, 0));
	if(argc==2)
		demo_select(argv[1]);
	else
		demo_select(sql_select);
	return 0;
}


 

评论

登录后才可以发表评论
GBase用户21143发表于 10个月前
优秀啊!
GBase用户21182发表于 10个月前
楼主辛苦啦
曾浩轩发表于 2个月前
厉害了