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

ops/2024/12/23 4:37:06/

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


http://www.ppmy.cn/ops/119645.html

相关文章

Mybatis-Plus新花样(一)

一. ActiveRecord Active Record(活动记录)&#xff0c;是一种领域模型模式&#xff0c;特点是一个模型类对应关系型数据库中的一个表&#xff0c;而模型类的一个实例对应表中的一行记录。 在MyBatisPlus中&#xff0c;AR模式即在实体类中封装了对数据库的访问&#xff0c;而不…

Java五子棋

目录 一&#xff1a;案例要求&#xff1a; 二&#xff1a;代码&#xff1a; 三&#xff1a;结果&#xff1a; 一&#xff1a;案例要求&#xff1a; 实现一个控制台下五子棋的程序。用一个二维数组模拟一个15*15路的五子棋棋盘&#xff0c;把每个元素赋值位“┼”可以画出棋…

【leetcode】121.买卖股票的最佳时机

思路&#xff1a; 找到后面与前面的差值最大即可。 代码&#xff1a; int maxProfit(int* prices, int pricesSize) {int i 0, j 0;//i是后一个最大的&#xff0c;j是前面最小的int max 0, temp 0;//表示最大值for (i 1; i < pricesSize; i){if (prices[j] < pr…

【Linux-基础IO】如何理解Linux下一切皆文件磁盘的介绍

目录 如何理解Linux系统上一切皆文件 1.物理角度认识磁盘 2.对磁盘的存储进行逻辑抽象 磁盘寻址 3.磁盘中的寄存器 如何理解Linux系统上一切皆文件 计算机中包含大量外设&#xff0c;操作系统想要管理好这些外设&#xff0c;就必须对这些外设进行先描述再组织&#xff0c…

css的背景background属性

CSS的background属性是一个简写属性&#xff0c;它允许你同时设置元素的多个背景相关的子属性。使用这个属性可以简化代码&#xff0c;使其更加清晰和易于维护。background属性可以设置不同的子属性。 background子属性 定义背景颜色 使用background-color属性 格式&#x…

k8s搭建一主三从的mysql8集群---无坑

一&#xff0c;环境准备 1.1 k8s集群服务器 ip角色系统主机名cpumem192.168.40.129mastercentos7.9k8smaster48192.168.40.130node1centos7.9k8snode148192.168.40.131node2centos7.9k8snode248192.168.40.132node3centos7.9k8snode348 k8s集群操作请参考《K8s安装部署&…

【开源免费】基于SpringBoot+Vue.JS校园资料分享平台(JAVA毕业设计)

本文项目编号 T 059 &#xff0c;文末自助获取源码 \color{red}{T059&#xff0c;文末自助获取源码} T059&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

强化-导数

只有当导数在一个区间内不变号时&#xff0c;才能得到函数单调的结论&#xff0c;若只知道导数在一点的符号&#xff0c;是不能得到函数单调的结果的。 高阶导函数