当前位置: 首页 > news >正文

OCI编程基础篇(九) 查询数据

访问www.tomcoding.com网站,学习Oracle内部数据结构,详细文档说明,下载Oracle的exp/imp,DUL,logminer,ASM工具的源代码,学习高技术含量的内容。

查询数据是OCI程序中的一个常用的操作,它不会对数据库的数据产生改变,操作的步骤也与更新操作的步骤有区别,用到了不一样的函数。下面先看一下查询操作的步骤。

1. 分配OCI语句句柄,用到函数OCIHandleAlloc()

2. 准备SQL语句,用到函数OCIStmtPrepare()

3. 定义每个查询字段输出变量,用到函数OCIDefineByPos()

4. 执行OCI语句,用到函数OCIStmtExecute()

5. 取回查询结果,用到函数OCIStmtFetch()

下面看一下用到的新函数原型和参数。

第一个函数,定义输出变量函数。

sword OCIDefineByPos ( OCIStmt *stmtp,
    OCIDefine **defnpp,
    OCIError   *errhp,
    ub4            position,
    void           *valuep,
    sb4            value_sz,
    ub2            dty,
    void           *indp,
    ub2           *rlenp,
    ub2           *rcodep,
    ub4           mode );

stmtp是一个输入/输出参数,是分配的查询语句句柄。

defnpp是一个输入/输出参数,是跟查询列表中的字段对应的定义句柄,存放本字段相关的信息,如果不需要,可以赋值为NULL

errhp是一个输入/输出参数,是错误句柄,用于获取错误码和错误信息文本。

position是一个输入参数,是查询列表中字段的位置,从1开始计算。

valuep是一个输入/输出参数,指向输出变量的地址或一个输出数组的地址。

value_sz是一个输入参数,指定valuep存储缓冲区的大小,以字节计算。

dty是一个输入参数,是查询列表中字段的数据类型,与绑定函数中的定义一致。

indp是一个输入参数,是指示变量指针,如果查询的字段返回值为NULL,指示变量返回值为-1

rlenp是一个输入/输出参数,是返回结果的字段值的实际大小。

rcodep是一个输出参数,返回字段级别的错误码。

mode是一个输入参数,指示定义函数的模式,一般取值为OCI_DEFAULT

第二个函数,取回查询结果函数。

sword OCIStmtFetch ( OCIStmt *stmtp,
    OCIError *errhp,
    ub4         nrows,
    ub2         orientation,
    ub4         mode );

stmtp是一个输入参数,查询语句的OCI句柄。

errhp是一个输入参数,错误句柄,用于返回错误码和错误信息文本。

nrows是一个输入参数,希望取回的数据条数。

orientation是一个输入参数,获取数据的方向,取值为OCI_FETCH_NEXT,获取下一条数据。

mode是一个输入参数,取值为OCI_DEFAULT

我们还是通过一个实际的例子来看看这些函数的用法,还是使用前面创建的表test_tab,从里面查询数据的SQL语句为SELECT ID, NAME, ADDR FROM test_tab。其中ID, NAME, ADDR就是查询列表字段。下面看看用OCI程序怎样操作。

 

OCIEnv       *envhp = NULL;
OCIError     *errhp = NULL;
OCIServer    *svrhp = NULL;
OCISession   *usrhp = NULL;
OCISvcCtx    *svchp = NULL;
OCIStmt      *smthp = NULL;/* 查询数据 */
int select_data(void){sword rc;int slen;sb2 ind_id;sb2 ind_name;sb2 ind_addr;ub2 alen_id;ub2 alen_name;ub2 alen_addr;ub2 rcode_id;ub2 rcode_name;ub2 rcode_addr;int32_t id;char id_str[64];char name[32];char addr[256];OCIDefine *defp;char sqltxt[1024];/* 分配OCI语句句柄 */rc = OCIHandleAlloc((void *)envhp,(void **)&smthp,OCI_HTYPE_STMT,0,(void **)NULL);if (rc != OCI_SUCCESS) {fprintf(stderr, "OCIHandleAlloc() - allocate statement handle error !\n");return (-1);}/* 生成查询语句文本 */strcpy(sqltxt, "SELECT ID, NAME, ADDR FROM test_tab");slen = strlen(sqltxt);/* 准备语句 */if (check_oci_error(errhp,OCIStmtPrepare(smthp, errhp, (const OraText *)sqltxt, slen,OCI_NTV_SYNTAX, OCI_DEFAULT)) < 0)return (-1);/* 定义第一个字段ID的输出变量 */if (check_oci_error(errhp,OCIDefineByPos((OCIStmt *)smthp,(OCIDefine **)&defp,errhp,(ub4)1, /* position */(void *)&id, /* valuep */(sb4)4, /* value_sz */(ub2)SQLT_INT, /* dty */(void *)&ind_id, /* indp */(ub2 *)&alen_id, /* alenp */(ub2 *)&rcode_id, /* column return code pointer */(ub4)OCI_DEFAULT) /* mode */) < 0)return (-1);/* 定义第二个字段NAME的输出变量 */if (check_oci_error(errhp,OCIDefineByPos((OCIStmt *)smthp,(OCIDefine **)&defp,errhp,(ub4)2, /* position */(void *)name, /* valuep */(sb4)30, /* value_sz */(ub2)SQLT_STR, /* dty */(void *)&ind_name, /* indp */(ub2 *)&alen_name, /* alenp */(ub2 *)&rcode_name, /* column return code pointer */(ub4)OCI_DEFAULT) /* mode */) < 0)return (-1);/*定义第三个字段ADDR的输出变量 */if (check_oci_error(errhp,OCIDefineByPos((OCIStmt *)smthp,(OCIDefine **)&defp,errhp,(ub4)3, /* position */(void *)addr, /* valuep */(sb4)200, /* value_sz */(ub2)SQLT_STR, /* dty */(void *)&ind_addr, /* indp */(ub2 *)&alen_addr, /* alenp */(ub2 *)&rcode_addr, /* column return code pointer */(ub4)OCI_DEFAULT) /* mode */) < 0)return (-1);/* 执行OCI语句,注意在查询语句执行时,iters要设置为0 */if (check_oci_error(errhp,OCIStmtExecute(svchp,smthp, /* stmthp */errhp, /* errhp */0, /* iters */0, /* rowoff */NULL, /* snap_in */NULL, /* snap_out */OCI_DEFAULT) /* mode */) < 0)return (-1);while (1) {if ((rc = check_oci_error(errhp,OCIStmtFetch(smthp, errhp, 1,OCI_FETCH_NEXT, OCI_DEFAULT))) < 0)return (-1);/* 返回的结果集中没有数据了,退出循环 */if (rc == OCI_NO_DATA)break;if (ind_id == -1)sprintf(id_str, "NULL");elsesprintf(id_str, "%d", id);if (ind_name == -1)sprintf(name, "NULL");if (ind_addr == -1)sprintf(addr, "NULL");fprintf(stdout, "ID=%s, NAME=%s, ADDR=%s\n", id_str, name, addr);}return (0); }

 

如果查询语句中有WHERE条件,那么条件字段会用占位符表示,通过绑定函数来关联占位符和条件变量值。比如查询ID=1的数据,那么OCI程序中的语句文本为SELECT ID, NAME, ADDR FROM test_tab WHERE ID=:1。占位符:1通过OCIBindByPos()函数来绑定数值。

 

http://www.sczhlp.com/news/11833/

相关文章:

  • rust学习笔记之小练习:泛型、trait
  • 线程中并发的安全面试题
  • 法国农业部如何利用Elastic技术监控商业捕鱼业
  • 机械手弧焊电源气体流量优化方法
  • nginx配置https访问
  • CSP-J/S资源链接1
  • nvm 报错 The system cannot find the file specified
  • 闭包 知识点初探
  • 检测和修复恶意软件在服务器中的活动
  • 10.权重衰退 [跟着沐神-动手学深度学习]
  • QKV在transformer中的作用(一)
  • 还在手写 RAG?用 Sealos 一键部署 Dify,轻松打造 AI 知识库问答机器人
  • endpoint与ingress-nginx的区别
  • PO、VO、BO、DTO、DAO、POJO傻傻分不清楚
  • 2025/08/14 模拟赛总结
  • 题解:洛谷 P4401 [IOI 2007] Miners 矿工配餐
  • 【译】NGINX 推出对 ACME 协议的原生支持
  • 优德普SAP一体化平台有哪些功能?宁波SAP实施优德普
  • vue源码工程运行报错解决
  • 实时动画版本,动态展示 QPSK 与 16QAM 在调制过程中的“星座点跃迁”过程
  • Linux使用Remmina连接远程Windows桌面
  • Python:如何处理WRF投影(LCC, 兰伯特投影)?
  • 主事件循环运行机制
  • 【自学嵌入式:stm32单片机】TIM编码器接口
  • edu 104 G(高维dp + 容斥 + 前缀和优化)
  • mysql 8.4.6开启审计(使用Percona审计插件不成功)
  • Streamlit实战
  • 21Java基础之集合进阶(二)
  • ARM服务器UOS系统升级OpenSSH源码安装
  • 思通数科 AI 视频监控:以核心价值驱动安防行业智能化升级