unixODBC编程(三)查询数据库表中的数据
访问www.tomcoding.com网站,学习Oracle内部数据结构,详细文档说明,下载Oracle的exp/imp,DUL,logminer,ASM工具的源代码,学习高技术含量的内容。
连接数据库成功后,就可以对数据库进行操作了,我们先看一下怎样从数据库表中查询数据。查询数据在ODBC中也有几个步骤。
1. 分配一个语句句柄,使用SQLAllocHandle()函数,句柄类型为SQL_HANDLE_STMT。
2. 准备语句,使用SQLPrepare()函数。
3. 执行语句,使用SQLExecute()函数。
4. 绑定输出的变量,使用SQLBindCol()函数。
5. 循环取回结果集数据,使用SQLFetch()函数。
下面看看这几个函数的原型和参数。
准备语句函数。
SQLRETURN SQLPrepare(
SQLHSTMT StatementHandle,
SQLCHAR * StatementText,
SQLINTEGER TextLength);
StatementHandle是一个输入参数,语句句柄。
StatementText是一个输入参数,SQL文本字符串。
TextLength是一个输入参数,SQL文本字符串 StatementText 的长度。
执行语句函数。
SQLRETURN SQLExecute(
SQLHSTMT StatementHandle);
StatementHandle是一个输入参数,语句句柄。
绑定输出变量函数。
SQLRETURN SQLBindCol(
SQLHSTMT StatementHandle,
SQLUSMALLINT ColumnNumber,
SQLSMALLINT TargetType,
SQLPOINTER TargetValuePtr,
SQLLEN BufferLength,
SQLLEN * StrLen_or_IndPtr);
StatementHandle是一个输入参数,语句句柄。
ColumnNumber是一个输入参数,要绑定的结果集列的序号。列从 0 开始递增编号,其中列 0 是书签列。如果没有使用书签列,则列号从 1 开始。
TargetType是一个输入参数,是TargetValuePtr 缓冲区的 C 数据类型。
TargetValuePtr是一个输入/输出参数,指向要绑定到列的数据缓冲区的指针。
BufferLength是一个输入参数,TargetValuePtr 缓冲区的长度(以字节为单位)。
StrLen_or_IndPtr是一个输入/输出参数,指向要绑定到列的长度/指示器缓冲区的指针。
取回结果集中数据的函数。
SQLRETURN SQLFetch(
SQLHSTMT StatementHandle);
StatementHandle是一个输入参数,语句句柄。
现在来看一个例子,连接到数据库后,从user_table中查询表名,表空间名和表的状态。SQL语句为select table_name, tablespace_name, status from user_tables。
#include "stdio.h" #include "stdlib.h" #include "string.h" #include "sql.h" #include "sqlext.h" #include "sqltypes.h" SQLHANDLE envh; /* env handle */ SQLHANDLE dbch; /* connect handle */ SQLHANDLE stmth; /* statement handle */ int main(int argc, char *argv[]){ int conn = 0; SQLRETURN rc; SQLLEN rlen1; SQLLEN rlen2; SQLLEN rlen3; char dsn_str[32]; char usrname[32]; char passwd[32]; char table_name[256]; char ts_name[32]; char status[16]; /* 从命令行参数中输入数据源名称,数据库用户名和密码 */ if (argc < 3) { fprintf(stderr, "usage: %s dsn username password\n", argv[0]); return (-1); } strncpy(dsn_str, argv[1], 32); dsn_str[31] = '\0'; strncpy(usrname, argv[2], 32); usrname[31] = '\0'; strncpy(passwd, argv[3], 32); passwd[31] = '\0'; /* 分配环境句柄 */ rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &envh); if (rc != SQL_SUCCESS) { fprintf(stderr, "Allocate environment handle error.\n"); return (-1); } /* 设置ODBC版本 */ rc = SQLSetEnvAttr(envh, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0); if (rc != SQL_SUCCESS) { fprintf(stderr, "Set ODBC version error.\n"); goto free_exit; } /* 分配连接句柄 */ rc = SQLAllocHandle(SQL_HANDLE_DBC, envh, &dbch); if (rc != SQL_SUCCESS) { fprintf(stderr, "Allocate DB connection handle error.\n"); goto free_exit; } /* 设置连接超时时间 */ rc = SQLSetConnectAttr(dbch, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER)10, 0); if (rc != SQL_SUCCESS) { fprintf(stderr, "Set connection timeout value error.\n"); goto free_exit; } /* 连接到数据库 */ rc = SQLConnect(dbch, (SQLCHAR *)dsn_str, SQL_NTS, (SQLCHAR *)usrname, SQL_NTS, (SQLCHAR *)passwd, SQL_NTS); if (rc != SQL_SUCCESS) { fprintf(stderr, "Connect to DB error.\n"); goto free_exit; } /* 设置连接数据库成功的标志 */ conn = 1; fprintf(stdout, "connect DB ok ......\n"); /* 分配语句句柄 */ rc = SQLAllocHandle(SQL_HANDLE_STMT, dbch, &stmth); if (rc != SQL_SUCCESS) { fprintf(stderr, "Allocate statment handle error.\n"); goto free_exit; } /* 准备SQL语句文本 */ rc = SQLPrepare(stmth, (SQLCHAR *)"select table_name, tablespace_name, status from user_tables", SQL_NTS); if (rc != SQL_SUCCESS) { fprintf(stderr, "Prepare statment error.\n"); goto free_exit; } /* 执行语句 */ rc = SQLExecute(stmth); if (rc != SQL_SUCCESS) { fprintf(stderr, "Execute statment error.\n"); goto free_exit; } /* 绑定第一列的输出变量,类型是C语言的char类型,rlen1是返回的数据长度 */ rc = SQLBindCol(stmth, 1, SQL_C_CHAR, (SQLCHAR *)table_name, 256, &rlen1); if (rc != SQL_SUCCESS) { fprintf(stderr, "Bind column 1 error.\n"); goto free_exit; } /* 绑定第二列输出变量 */ rc = SQLBindCol(stmth, 2, SQL_C_CHAR, (SQLCHAR *)ts_name, 32, &rlen2); if (rc != SQL_SUCCESS) { fprintf(stderr, "Bind column 2 error.\n"); goto free_exit; } /* 绑定第三列输出变量 */ rc = SQLBindCol(stmth, 3, SQL_C_CHAR, (SQLCHAR *)status, 16, &rlen3); if (rc != SQL_SUCCESS) { fprintf(stderr, "Bind column 3 error.\n"); goto free_exit; } while (1) { /* 返回结果集数据 */ rc = SQLFetch(stmth); if (rc == SQL_NO_DATA) { /* 结果集中没有数据了,退出循环 */ break; } else if (rc == SQL_ERROR) { /* 出错,返回 */ fprintf(stderr, "Fetch data error.\n"); goto free_exit; } /* 打印返回的变量值 */ fprintf(stdout, "table_name=%s, tablespace_name=%s, status=%s\n", table_name, ts_name, status); } /* 释放语句句柄 */ SQLFreeHandle(SQL_HANDLE_STMT, stmth); /* 断开数据库连接 */ SQLDisconnect(dbch); /* 释放连接句柄 */ SQLFreeHandle(SQL_HANDLE_DBC, dbch); /* 释放环境句柄 */ SQLFreeHandle(SQL_HANDLE_ENV, envh); return (0); free_exit: if (stmth != NULL) { SQLFreeHandle(SQL_HANDLE_STMT, stmth); } if (conn) { SQLDisconnect(dbch); } if (dbch != NULL) { SQLFreeHandle(SQL_HANDLE_DBC, dbch); } if (envh != NULL) { SQLFreeHandle(SQL_HANDLE_ENV, envh); } return (-1); }
编译程序,需要包含unixODBC的include路径和连接库的路径,比如源文件叫odbc_test.c,编译命令如下。
cc -I$HOME/unixODBC/include -L$HOME/unixODBC/lib -lodbc odbc_test.c

浙公网安备 33010602011771号