自学内容网 自学内容网

unixODBC编程(三)查询数据库表中的数据

连接数据库成功后,就可以对数据库进行操作了,我们先看一下怎样从数据库表中查询数据。查询数据在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


原文地址:https://blog.csdn.net/tomcoding/article/details/142500583

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!