1.OCIBindByName和OCIBindByPos
OCI提供了两种方法来绑定参数到SQL语句中的占位符:OCIBindByPos和OCIBindByName。
1.OCIBindByName函数原型:
OCIBindByName( OCIStmt *stmtp, OCIBind bindpp, OCIError *errhp, const text *placeholder, sb4 placeh_len, dvoid *valuep, sb4 value_sz, ub2 dty, dvoid *indp, ub2 *alenp, ub2 *rcodep, ub4 maxarr_len, ub4 *curelep, ub4 mode )
讯享网
- 通过占位符的名称绑定参数到SQL语句中的占位符位置。
- 占位符的名称由参数"placeholder"指定。
- 参数"placeh_len"指定占位符的名称长度。
- 其他参数的含义:
- valuep: 指向数据的指针。
- value_sz: 数据的大小。
- dty: 数据的类型。
- indp: 指示数据的指针,用于处理空值或者处理绑定变量为数组时的偏移量。
- alenp: 数据的实际长度。
- rcodep: 返回代码的指针。
- maxarr_len: 绑定变量为数组时,表示数组的最大长度。
- curelep: 绑定变量为数组时,表示已填充的数组元素个数。
- mode: 绑定模式。
2.OCIBindByPos函数原型:
讯享网OCIBindByPos( OCIStmt *stmtp, OCIBind bindpp, OCIError *errhp, ub4 position, dvoid *valuep, sb4 value_sz, ub2 dty, dvoid *indp, ub2 *alenp, ub2 *rcodep, ub4 maxarr_len, ub4 *curelep, ub4 mode )
- 通过占位符的位置绑定参数到SQL语句中的占位符位置。
- 参数"position"指定了占位符的位置,从1开始计数。
- 其他参数的含义与OCIBindByName类似。
这两个函数的作用是将应用程序中的变量或者数据与SQL语句中的占位符相关联。OCIBindByName通过占位符的名称进行绑定,而OCIBindByPos通过占位符的位置进行绑定。这两种方法可以根据具体的需求来选择使用。
3.OCIBindByName 示例:
OCIStmt *stmt; OCIBind *bind; int id = 100; // 准备语句 OCIStmtPrepare(stmt, err, (text *)"SELECT name FROM employees WHERE emp_id = :empid", -1, OCI_NTV_SYNTAX, OCI_DEFAULT); // 通过名称绑定变量 OCIBindByName(stmt, &bind, err, (text *)":empid", -1, &id, sizeof(int), SQLT_INT, NULL, NULL, NULL, 0, NULL, OCI_DEFAULT); // 执行语句 OCIStmtExecute(svchp, stmt, err, 1, 0, NULL, NULL, OCI_DEFAULT); // 获取结果 char name[50]; OCIStmtFetch2(stmt, err, 1, OCI_FETCH_NEXT, 0, OCI_DEFAULT); // 从绑定变量中取值 OCIString *result; OCIAttrGet(bind, OCI_HTYPE_BIND, &result, NULL, OCI_ATTR_VALUE, err); printf("Name: %s\n", OCIStringPtr(result));
说明:
- 以上示例通过名称绑定了一个变量
:empid,并将其值设置为100。 - 语句准备阶段,使用了一个带有参数的SELECT语句,其中的
:empid就是绑定的变量。 - 在执行语句后,通过OCIStmtFetch2函数获取结果集的下一行。
- 使用OCIAttrGet函数从绑定变量中获取值,并以字符串形式打印输出。
4.OCIBindByPos 示例:
讯享网OCIStmt *stmt; OCIBind *bind; int id = 100; // 准备语句 OCIStmtPrepare(stmt, err, (text *)"SELECT name FROM employees WHERE emp_id = ?", -1, OCI_NTV_SYNTAX, OCI_DEFAULT); // 通过位置绑定变量 OCIBindByPos(stmt, &bind, err, 1, &id, sizeof(int), SQLT_INT, NULL, NULL, NULL, 0, NULL, OCI_DEFAULT); // 执行语句 OCIStmtExecute(svchp, stmt, err, 1, 0, NULL, NULL, OCI_DEFAULT); // 获取结果 char name[50]; OCIStmtFetch2(stmt, err, 1, OCI_FETCH_NEXT, 0, OCI_DEFAULT); // 从绑定变量中取值 OCIString *result; OCIAttrGet(bind, OCI_HTYPE_BIND, &result, NULL, OCI_ATTR_VALUE, err); printf("Name: %s\n", OCIStringPtr(result));
说明:
- 以上示例通过位置绑定了一个变量,将其值设置为100。
- 语句准备阶段,使用了一个带有参数的SELECT语句,其中的?表示绑定变量的位置。
- 在执行语句后,通过OCIStmtFetch2函数获取结果集的下一行。
- 使用OCIAttrGet函数从绑定变量中获取值,并以字符串形式打印输出。
Note:
1.无论使用OCIBindByName还是OCIBindByPos,结果都是一样的。关键区别在于绑定变量的方式:OCIBindByName是通过名称绑定变量,而OCIBindByPos是通过位置绑定变量。
2.冒号后+名字和问号(:empid 或者 ?)都可以表示占位符。
2.OCI连接Oracle数据库的流程
#include <stdio.h> #include <oci.h> void check_error(OCIError *err, sword status) { text error_msg[512]; sb4 error_code; if (status != OCI_SUCCESS) { OCIErrorGet(err, 1, NULL, &error_code, error_msg, sizeof(error_msg), OCI_HTYPE_ERROR); printf("Error: %d - %s\n", error_code, error_msg); exit(1); } } int main() { OCIEnv *env; OCIError *err; OCIServer *srv; OCISession *ses; OCISvcCtx *svc; sword status; // 初始化OCI环境 status = OCIEnvCreate(&env, OCI_THREADED | OCI_OBJECT, NULL, NULL, NULL, NULL, 0, NULL); check_error(err, status); // 分配错误句柄 status = OCIHandleAlloc(env, (dvoid )&err, OCI_HTYPE_ERROR, 0, NULL); check_error(err, status); // 初始化服务器句柄 status = OCIHandleAlloc(env, (dvoid )&srv, OCI_HTYPE_SERVER, 0, NULL); check_error(err, status); // 初始化会话句柄 status = OCIHandleAlloc(env, (dvoid )&ses, OCI_HTYPE_SESSION, 0, NULL); check_error(err, status); // 创建服务器上下文 status = OCIServerAttach(srv, err, (text *)"<db_name>", strlen("<db_name>"), OCI_DEFAULT); check_error(err, status); // 设置会话句柄的服务器属性 status = OCIAttrSet(ses, OCI_HTYPE_SESSION, srv, 0, OCI_ATTR_SERVER, err); check_error(err, status); // 设置会话句柄的用户名和密码属性 status = OCIAttrSet(ses, OCI_HTYPE_SESSION, (text *)"<username>", strlen("<username>"), OCI_ATTR_USERNAME, err); check_error(err, status); status = OCIAttrSet(ses, OCI_HTYPE_SESSION, (text *)"<password>", strlen("<password>"), OCI_ATTR_PASSWORD, err); check_error(err, status); // 创建服务器上下文句柄 status = OCIHandleAlloc(env, (dvoid )&svc, OCI_HTYPE_SVCCTX, 0, NULL); check_error(err, status); // 设置服务器上下文句柄的会话属性 status = OCIAttrSet(svc, OCI_HTYPE_SVCCTX, ses, 0, OCI_ATTR_SESSION, err); check_error(err, status); // 开始会话 status = OCISessionBegin(svc, err, ses, OCI_CRED_RDBMS, OCI_DEFAULT); check_error(err, status); printf("Connected to Oracle database\n"); // 关闭会话 status = OCISessionEnd(svc, err, ses, OCI_DEFAULT); check_error(err, status); // 断开服务器连接 status = OCIServerDetach(srv, err, OCI_DEFAULT); check_error(err, status); // 释放句柄和环境 OCIHandleFree(svc, OCI_HTYPE_SVCCTX); OCIHandleFree(ses, OCI_HTYPE_SESSION); OCIHandleFree(srv, OCI_HTYPE_SERVER); OCIHandleFree(err, OCI_HTYPE_ERROR); OCIHandleFree(env, OCI_HTYPE_ENV); return 0; }
3.指示器变量
指示器变量是用来处理数据库 NULL 值的变量。当执行 SELECT 或者 FETCH 语句时,如果不使用指示器变量并且列返回的值为 NULL 时,会显示错误信息。指示器变量必须采用 short 类型定义,并且指示器变量必须跟在宿主变量后面。
指示器变量的语法如下所示:
讯享网:host_variable [INDICATOR] :indicator_variable
在使用指示器变量后,可以检测出返回的列是否为 NULL:
- 当指示器变量返回 -1 时,表示数据库返回 NULL 值。
- 当指示器变量返回 0 时,表示列值被赋给了输出宿主变量。
- 当指示器变量返回的值大于 0 时,表示将被截断列值付给了输出宿主变量,并且指示器变量存放着数据库列值的实际长度。
- 当指示器变量返回值为 -2 时,表示被截断列值付给了输出宿主变量,但是实际长度不能确定。
指示器变量-OceanBase 嵌入式 SQL 预编译器-OceanBase文档中心-分布式数据库使用文档

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/121217.html