ODBC
Vastbase数据库通过提供ODBC驱动为使用C/C++语言的应用程序提供访问Vastbase的接口。但同时也兼容openGauss的ODBC驱动,可以通过openGauss的ODBC驱动访问Vastbase。
Vastbase ODBC主要接口
Vastbase ODBC 驱动由具有建立和管理与Vastbase 数据库连接、执行SQL语句和对结果集进行储存管理的若干功能类组成。
SQLConnect
与特定数据库的连接(会话)。在连接上下文中执行SQL 语句并返回结果。
示例:
SQLConnect(V_OD_hdbc, // 连接句柄,通过SQLAllocHandle获得 (SQLCHAR*) "Test", // 要连接数据源的名称 SQL_NTS, // ServerName的长度 (SQLCHAR*) "userName", // 数据源中数据库用户名 SQL_NTS, // UserName的长度 (SQLCHAR*) "password", // 数据源中数据库用户密码 SQL_NTS); // Authentication的长度
SQLAllocHandle
用于分配环境、连接、语句或描述符的句柄,包括连接句柄、语句句柄等。
SQLAllocHandle(SQL_HANDLE_DBC, // 由SQLAllocHandle分配的句柄类型 V_OD_Env, // 将要分配的新句柄的类型 &V_OD_hdbc); // 输出参数:一个缓冲区的指针,此缓冲区以新分配的数据结构存放返回的句柄
SQLSetConnectAttr
设置控制连接各方面的属性。
SQLSetConnectAttr(V_OD_hdbc, // 连接句柄 SQL_ATTR_AUTOCOMMIT, // 设置属性 SQL_AUTOCOMMIT_ON, // 指向对应Attribute的值。依赖于Attribute的值,ValuePtr是32位无符号整型值或指向以空结束的字符串。 0); // 如果ValuePtr指向字符串或二进制缓冲区,这个参数是*ValuePtr长度,如果ValuePtr指向整型,忽略StringLength
设置ODBC驱动
安装ODBC驱动前需要先装好openGauss数据库或Vastbase数据库和unixODBC,并配置环境变量。
安装openGauss或Vastbase
按照安装说明安装openGauss或Vastbase,并配置环境变量(根据实际情况修改路径):
export GAUSSHOME="/usr/local/vastbase"
export PATH="/usr/local/vastbase/bin:$PATH"
export LD_LIBRARY_PATH="/usr/local/vastbase/lib:$LD_LIBRARY_PATH"
export PGDATA="/home/vastbase/data"
export PGPORT="5432"
export PGDATABASE="vastbase"
安装unixODBC
要使用驱动,必须先安装unixODBC。获取unixODBC源码包参考地址为:http://sourceforge.net/projects/unixodbc/files/unixODBC/2.3.0/unixODBC-2.3.0.tar.gz/downloa[d。](http://sourceforge.net/projects/unixodbc/files/unixODBC/2.3.0/unixODBC-2.3.0.tar.gz/download。)
目前不支持unixODBC-2.2.1版本。以unixODBC-2.3.0版本为例,在客户端执行如下命令安装unixODBC。默认安装到”/usr/local”目录下,生成数据源文件到 “/usr/local/etc”目录下,库文件生成在”/usr/local/lib”目录。
tar -zxvf unixODBC-2.3.0.tar.gz
cd unixODBC-2.3.0
#修改configure文件(如果不存在,那么请修改configure.ac),找到LIB_VERSION
#将它的值修改为"1:0:0",这样将编译出*.so.1的动态库,与psqlodbcw.so的依赖关系相同。
vim configure
./configure --enable-gui=no
#如果要在鲲鹏服务器上编译,请追加一个configure参数:--build=aarch64-unknown-linux-gnu
make
make install
替换客户端驱动程序
1.解压ODBC驱动包;
2.将解压路径下odbc/lib目录下的psqlodbcw.la和psqlodbcw.so拷贝到”/usr/local/lib”目录下,或者将odbc/lib目录的绝对路径加入LD_LIBRARY_PATH环境变量;
3.将解压后lib目录下的库拷贝到”/usr/local/lib”目录下,或者将lib目录的绝对路径加入LD_LIBRARY_PATH环境变量。
配置数据源
1.配置ODBC驱动文件。在”/usr/local/etc/odbcinst.ini”文件中添加以下内容。
vim /usr/local/etc/odbcinst.ini
[GaussMPP] # 驱动器名称,对应数据源DSN中的驱动名
Driver64=/usr/local/lib/psqlodbcw.so # 驱动动态库的路径
setup=/usr/local/lib/psqlodbcw.so # 驱动安装路径,与Driver64中动态库的路径一致
2.配置数据源文件。该步骤并不是必须的,取决于获取连接的方式,详见下章”连接数据库”小节。在”/usr/local/etc/odbc.ini”文件中添加以下内容。
[Test] # 数据源的名称。
Description=Test # 数据源说明
Driver=GaussMPP # 驱动名,对应odbcinst.ini中的DriverName
Servername=127.0.0.1 # 服务器的IP地址
Database=vastbase # 要连接的数据库的名称
Username=vastbase # 数据库用户名称
Password= Aa@123456 # 数据库用户密码
Port=5432 # 服务器的端口号
Sslmode=allow # 开启SSL模式:disable 否, allow 可能 ,prefer 可能,requrie 是,verify-ca 是,verify-full 是
配置环境变量
vim ~/.bashrc
# 在配置文件中追加以下内容。
export LD_LIBRARY_PATH=/usr/local/lib/:$LD_LIBRARY_PATH
export ODBCSYSINI=/usr/local/etc
export ODBCINI=/usr/local/etc/odbc.ini
# 执行如下命令使配置生效
source ~/.bashrc
测试数据源配置
上述配置中该数据源的DSN为Test,可以通过isql来验证配置是否正确。命令如下。
isql -v Test
如果数据源配置中未指定用户名和密码,则用isql测试连接时需要指定用户密码:
isql -v Test vastbase Aa@123456
如果显示以下信息,表示配置正确,连接成功。
使用ODBC连接数据库
连接数据库
获取ODBC连接
获取连接有两种方法。
1.通过调用SQLConnect()函数连接到数据库:
SQLHENV V_OD_Env; // 环境句柄
SQLHDBC V_OD_hdbc; // 连接句柄
SQLRETURN retcode; // 返回值
SQLINTEGER V_OD_erg; //调用 接口返回值
/* 1.分配环境句柄 */
V_OD_erg = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&V_OD_Env);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
printf("Error AllocHandle\n");
exit(0);
}
/* 2.设置ODBC环境属性(版本信息)*/
SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
/* 3.分配连接句柄 */
V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
exit(0);
}
/* 4.设置连接属性 */
SQLSetConnectAttr(V_OD_hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON, 0);
/* 5. 连接数据源,这里的“userName”与“password”分别表示连接数据库的用户名和用户密码,请根据实际情况修改。
如果odbc.ini文件中已经配置了用户名密码,那么这里可以留空("")。 但是不建议这么做,因为一旦odbc.ini权限管理不善,将导致数据库用户密码泄露. */
V_OD_erg = SQLConnect(V_OD_hdbc, (SQLCHAR*) "Test", SQL_NTS, (SQLCHAR*) "vastbase", SQL_NTS, (SQLCHAR*) "Aa@123456", SQL_NTS);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
printf("Error SQLConnect %d\n",V_OD_erg);
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
exit(0);
}
printf("Connected !\n");
2.通过调用SQLDriverConnect()函数连接到数据库:
SQLHENV V_OD_Env; // 环境句柄
SQLHDBC V_OD_hdbc; // 连接句柄
SQLRETURN retcode; // 返回值
SQLINTEGER V_OD_erg; //调用 接口返回值
/* 1.分配环境句柄 */
V_OD_erg = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&V_OD_Env);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
printf("Error AllocHandle\n");
exit(0);
}
/* 2.设置ODBC环境属性(版本信息)*/
SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
/* 3.分配连接句柄 */
V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
exit(0);
}
/* 4.设置连接属性 */
SQLSetConnectAttr(V_OD_hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON, 0);
/* 5. 连接数据源 */
V_OD_erg = SQLDriverConnect(V_OD_hdbc, NULL, (SQLCHAR*)"Driver=GaussMPP;Servername=127.0.0.1;Port=5432;Database=postgres;UserName=vastbase;Password=Aa@123456", SQL_NTS, str, sizeof(str), &strl,SQL_DRIVER_COMPLETE);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
printf("Error SQLConnect %d\n",V_OD_erg);
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
exit(0);
}
printf("Connected !\n");
关闭ODBC连接
关闭连接时调用SQLDisconnect()函数关闭数据库连接:
rc = SQLDisconnect(V_OD_hdbc);
If (!SQL_SUCCEEDED(rc))
{
printf("SQLDisconnect failed");
fflush(stdout);
exit(1);
}
rc = SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
if (!SQL_SUCCEEDED(rc))
{
printf("SQLFreeHandle failed");
fflush(stdout);
exit(1);
}
V_OD_hdbc = NULL;
rc = SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
if (!SQL_SUCCEEDED(rc))
{
printf("SQLFreeHandle failed");
fflush(stdout);
exit(1);
}
V_OD_Env= NULL;
连接参数
名称 | 缩写 | 类型 | 定义 |
Description | string | 数据源说明 | |
Servicename | string | 数据源服务主机名或IP | |
Port | int | 数据库端口 | |
Username | string | 数据库用户 | |
Password | string | 数据库用户密码 | |
UseDeclareFetch | B6 | bool | 是否使用Declare和Fetch |
Fetch | A7 | int | 批量读取的最大行数 |
Socket | A8 | int | Socket buffer size |
ReadOnly | A0 | bool | 数据库是否只读 |
MaxVarcharSize | B0 | int | Varchar的最大长度 |
KeepaliveTime | D1 | int | TCP KEEPALIVE设置:空闲时间 |
KeepaliveInterval | D2 | int | TCP KEEPALIVE设置:间隔 |
连接参数可以在连接串中指定:
ret = SQLDriverConnect(conn, NULL, (SQLCHAR*)"Driver=PostgreSQL;Servername=192.168.114.28;Port=5411;Database=atlasdb;
UserName=atlasdb;Password=atlasdb;ReadOnly=Yes;Fetch=200", SQL_NTS, str, sizeof(str), &strl, SQL_DRIVER_COMPLETE);
执行SQL语句并处理结果
向数据库发出执行SQL的请求时,需要使用语句句柄,并调用SQLExecDirect或SQLExecute发出查询,服务端执行完成后查询的结果将保存在语句句柄中。
执行查询
直接执行
调用SQLAllocHandle()函数获取句柄,调用SQLExecDirect()函数执行查询。
HSTMT V_OD_hstmt = SQL_NULL_HSTMT; //语句句柄
ret = SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
if (!SQL_SUCCEEDED(ret))
{
printf("failed to allocate stmt handle");
return;
}
/*执行语句*/
ret = SQLExecDirect(V_OD_hstmt, (SQLCHAR *) "select * from test_stu", SQL_NTS);
/*获取结果*/
ret = SQLFetch(V_OD_hstmt);
if (ret == SQL_NO_DATA)
return;
if (ret == SQL_SUCCESS)
{
char buf[40];
SQLLEN ind;
/*获取列数据*/
ret = SQLGetData(V_OD_hstmt, 1, SQL_C_CHAR, buf, sizeof(buf), &ind);
}
预编译方式执行
调用SQLAllocHandle()函数获取句柄,使用SQLPrepare预编译语句,使用SQLBindParameter绑定参数,最后调用SQLExecute执行查询
/*初始化句柄*/
ret = SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
if (!SQL_SUCCEEDED(ret))
{
printf("failed to allocate stmt handle");
exit(1);
}
/*预编译SQL*/
ret = SQLPrepare(V_OD_hstmt, (SQLCHAR *) "SELECT * FROM test_stu WHERE id = ?", SQL_NTS);
CHECK_STMT_RESULT(ret, "SQLPrepare failed", V_OD_hstmt);
SQLLEN cbParam1 = SQL_NTS;
/*绑定参数*/
ret = SQLBindParameter(V_OD_hstmt, 1, SQL_PARAM_INPUT,
SQL_C_SLONG, /* value type */
SQL_INTEGER, /* param type */
20, /* column size */
0, /* dec digits */
"1", /* param value ptr */
0, /* buffer len */
&cbParam1 /* StrLen_or_IndPtr */);
CHECK_STMT_RESULT(ret, "SQLBindParameter failed", V_OD_hstmt);
/*执行*/
ret = SQLExecute(V_OD_hstmt);
CHECK_STMT_RESULT(ret, "SQLExecute failed", V_OD_hstmt);
/*获取结果*/
/*获取结果*/
ret = SQLFetch(V_OD_hstmt);
if (ret == SQL_NO_DATA)
return;
if (ret == SQL_SUCCESS)
{
char buf[40];
SQLLEN ind;
/*获取列数据*/
ret = SQLGetData(V_OD_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(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);
}
执行更新
要更改数据(执行一个insert,update或者delete),可以使用SQLExecDirect函数执行完整的SQL,也可以使用预编译的方式绑定参数后再执行。下面的示例将以预编译的方式执行。
删除
rc = SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
rc = SQLPrepare(V_OD_hstmt, (SQLCHAR *) "delete from test_stu where id= ? ", SQL_NTS);
cbParam1 = SQL_NTS;
rc = SQLBindParameter(V_OD_hstmt, 1, SQL_PARAM_INPUT,
SQL_C_SLONG, /* value type */
SQL_INTEGER, /* param type */
20, /* column size */
0, /* dec digits */
“1”, /* param value ptr */
0, /* buffer len */
&cbParam1 /* StrLen_or_IndPtr */);
CHECK_STMT_RESULT(rc, "SQLBindParameter failed", V_OD_hstmt);
rc = SQLExecute(V_OD_hstmt);
CHECK_STMT_RESULT(rc, "SQLExecute failed", V_OD_hstmt);
更新
rc = SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
rc = SQLPrepare(V_OD_hstmt, (SQLCHAR *) "update stu_id set name = ‘Lisa’ where id = ? ", SQL_NTS);
cbParam1 = SQL_NTS;
rc = SQLBindParameter(V_OD_hstmt, 1, SQL_PARAM_INPUT,
SQL_C_SLONG, /* value type */
SQL_INTEGER, /* param type */
20, /* column size */
0, /* dec digits */
“100”, /* param value ptr */
0, /* buffer len */
&cbParam1 /* StrLen_or_IndPtr */);
CHECK_STMT_RESULT(rc, "SQLBindParameter failed", V_OD_hstmt);
rc = SQLExecute(V_OD_hstmt);
CHECK_STMT_RESULT(rc, "SQLExecute failed", V_OD_hstmt);
插入
rc = SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
rc = SQLPrepare(V_OD_hstmt, (SQLCHAR *) "INSERT INTO test_stu VALUES (2, ?) ", SQL_NTS);
cbParam1 = SQL_NTS;
rc = SQLBindParameter(V_OD_hstmt, 1, SQL_PARAM_INPUT,
SQL_C_CHAR, /* value type */
SQL_CHAR, /* param type */
20, /* column size */
0, /* dec digits */
“Jennifer”, /* param value ptr */
0, /* buffer len */
&cbParam1 /* StrLen_or_IndPtr */);
CHECK_STMT_RESULT(rc, "SQLBindParameter failed", V_OD_hstmt);
rc = SQLExecute(V_OD_hstmt);
CHECK_STMT_RESULT(rc, "SQLExecute failed", V_OD_hstmt);
创建或修改数据库对象
要创建、更改或者删除一个类似表或者视图这样的数据库对象, 可以调用SQLExecDirect() 方法.
例如创建表:
HSTMT V_OD_hstmt = SQL_NULL_HSTMT; //语句句柄
ret = SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
if (!SQL_SUCCEEDED(ret))
{
printf("failed to allocate stmt handle");
return;
}
ret = SQLExecDirect(V_OD_hstmt, (SQLCHAR *) "create table test(c1 int,c2 int)", SQL_NTS);
调用存储过程
下面的例子展示了如何调用存储过程:
/*获取语句句柄*/
rc = SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
/*预编译SQL,调用函数时使用{call funcname(?,...)} */
SQLPrepare(V_OD_hstmt, (SQLCHAR *) "{ call length(?) }", SQL_NTS);
cbParams[paramno] = SQL_NTS;
/*绑定参数 */
rc = SQLBindParameter(V_OD_hstmt, paramno, 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 */
&cbParams[paramno] /* StrLen_or_IndPtr */);
CHECK_STMT_RESULT(rc, "SQLBindParameter failed", V_OD_hstmt);
/*执行*/
rc = SQLExecute(V_OD_hstmt);
CHECK_STMT_RESULT(rc, "SQLExecute failed", V_OD_hstmt);
处理大数据类型
二进制类型
Vastbase提供两种不同的方法存储二进制数据。二进制数据可以使用二进制数据类型BYTEA存储在表中,或者使用大对象特性以一种特殊的格式将二进制数据存储在一个独立的表中,然后通过在表中保存一个类型为 OID 的值来引用该表。
为了判断哪种方法比较合适,必须理解每种方法的局限。 BYTEA数据类型并不适合存储非常大数量的二进制数据。虽然类型为BYTEA的字段可以存储最多 1G 字节的二进制数据,但是这样它会要求巨大的内存(RAM)来处理这样巨大的数据。用于存储二进制数据的大对象方法更适合存储非常大的数据,但也有自己的局限,具体来说,删除一个引用大数据的行时并不会删除大对象,删除大对象需要单独操作。大对象还有一些安全性的问题,因为连接到数据库的任何用户都可以查看或修改任何大对象,即使他们没有权限查看或修改包含大对象引用的行。
BYTEA
使用BYTEA类型存储二进制数据,例如:
CREATE TABLE lo_test_tab (id int, img bytea);
插入记录
/*二进制数据*/
char param1[20] = { 1, 2, 3, 4, 5, 6, 7, 8 };
SQLLEN cbParam1;
/*分配语句句柄*/
rc = SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
if (!SQL_SUCCEEDED(rc))
{
printf("failed to allocate stmt handle");
exit(1);
}
/*预编译SQL*/
rc = SQLPrepare(V_OD_hstmt, (SQLCHAR *) "INSERT INTO lo_test_tab VALUES (1, ?)", SQL_NTS);
CHECK_STMT_RESULT(rc, "SQLPrepare failed", V_OD_hstmt);
/*绑定参数*/
cbParam1 = 8;
rc = SQLBindParameter(V_OD_hstmt, 1, SQL_PARAM_INPUT,
SQL_C_BINARY, /* value type */
SQL_LONGVARBINARY, /* param type */
200, /* column size */
0, /* dec digits */
param1, /* param value ptr */
0, /* buffer len */
&cbParam1 /* StrLen_or_IndPtr */);
CHECK_STMT_RESULT(rc, "SQLBindParameter failed", V_OD_hstmt);
/* 执行*/
rc = SQLExecute(V_OD_hstmt);
CHECK_STMT_RESULT(rc, "SQLExecute failed", V_OD_hstmt);
在这里,SQLBindParameter时指定参数类型为SQL_LONGVARBINARY,再将参数值的指针(char *类型)传入函数,即可将二进制数据写入。
读取记录
char buf[100];
SQLLEN ind;
/*分配句柄*/
rc = SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
/*执行查询*/
SQLExecDirect(V_OD_hstmt, (SQLCHAR *) "SELECT id, img FROM lo_test_tab WHERE id = 1", SQL_NTS);
/*获取结果*/
rc = SQLFetch(V_OD_hstmt);
CHECK_STMT_RESULT(rc, "SQLFetch failed", V_OD_hstmt);
/*读取数据*/
rc = SQLGetData(V_OD_hstmt, 2, SQL_C_BINARY, buf, sizeof(buf), &ind);
CHECK_STMT_RESULT(rc, "SQLGetData failed", V_OD_hstmt);
字符串类型
Vastbase中TEXT类型与VARCHAR类型都是可变长的字符串类型,区别在于VARCHAR类型通过VARCHAR(n)中的n来限制最大长度,而TEXT类型没有。TEXT类型与VARCHAR类型几乎没有性能差别,TEXT类型最多可存储1G数据。
使用TEXT类型存储数据时,可用getString(),getCharacterStream(),setString(), setCharacterStream()来进行读写。
例如:
CREATE TABLE images (id int, msg text);
插入记录
str=”text value for test”;
SQLLEN cbParam1 = SQL_NTS;
/*分配语句句柄*/
rc = SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
if (!SQL_SUCCEEDED(rc))
{
printf("failed to allocate stmt handle");
exit(1);
}
/*预编译SQL*/
rc = SQLPrepare(V_OD_hstmt, (SQLCHAR *) "INSERT INTO images VALUES (1, ?)", SQL_NTS);
CHECK_STMT_RESULT(rc, "SQLPrepare failed", V_OD_hstmt);
/*绑定参数*/
cbParam1 = 8;
rc = SQLBindParameter(V_OD_hstmt, 1, SQL_PARAM_INPUT,
SQL_C_CHAR, /* value type */
SQL_CHAR, /* param type */
200, /* column size */
0, /* dec digits */
str, /* param value ptr */
0, /* buffer len */
&cbParam1 /* StrLen_or_IndPtr */);
CHECK_STMT_RESULT(rc, "SQLBindParameter failed", V_OD_hstmt);
/* 执行*/
rc = SQLExecute(V_OD_hstmt);
CHECK_STMT_RESULT(rc, "SQLExecute failed", V_OD_hstmt);
读取记录
char buf[100];
SQLLEN ind;
/*分配句柄*/
rc = SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
/*执行查询*/
SQLExecDirect(V_OD_hstmt, (SQLCHAR *) "SELECT id, img FROM images WHERE id = 1", SQL_NTS);
/*获取结果*/
rc = SQLFetch(V_OD_hstmt);
CHECK_STMT_RESULT(rc, "SQLFetch failed", V_OD_hstmt);
/*读取数据*/
rc = SQLGetData(V_OD_hstmt, 2, SQL_C_CHAR, buf, sizeof(buf), &ind);
CHECK_STMT_RESULT(rc, "SQLGetData failed", V_OD_hstmt);