上一节我们看到了插入数据的过程,这一节看一下怎样更新和删除数据库表中的数据。其实在OCI中INSERT、UPDATE和DELETE都叫做更新操作,就是通过SQL语句对数据库表中的数据做出了更改。那么更新和删除表数据,也遵循插入数据时同样的步骤,我们列出来,再复习一遍。
1. 分配一个SQL语句句柄,OCIHandleAlloc()。
2. 准备SQL语句,OCIStmtPrepare()。
3. 为SQL语句绑定要插入的数据,OCIBindByPos()。
4. 执行SQL语句,OCIStmtExecute()。
5. 提交数据库改变,OCITransCommit()。
用到的OCI函数的原型和参数已经在上一节中介绍过了,需要时可以回看一下。
更新和删除数据与插入数据的不同,仅在执行的SQL语句文本不同而已。
还以上一节中创建的表为例,在test_tab中已经插入了一条数据,现在把NAME和ADDR字段的数据都更新成大写,那么SQL语句为UPDATE test_tab SET NAME='AAAAAAAA', ADDR='BBBBBBBBBBBBBBBBBBBB' WHERE ID=1。删除这条数据的SQL语句为DELETE FROM test_tab WHERE ID=1。
在OCI中更新的SQL文本为UPDATE test_tab SET NAME=:1, ADDR=:2 WHERE ID=:3。删除的SQL文本为DELETE FROM test_tab WHERE ID=:1。
不管是更新列表中的占位符还是WHERE条件中的占位符,都要通过绑定函数来与宿主变量建立联系。下面还是通过实际的例子代码来看一下完整的过程。
更新数据源代码。
OCIEnv *envhp = NULL;
OCIError *errhp = NULL;
OCIServer *svrhp = NULL;
OCISession *usrhp = NULL;
OCISvcCtx *svchp = NULL;
OCIStmt *smthp = NULL;
/* 更新一条数据 */
int update_one_row(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 name[32];
char addr[256];
OCIBind *bndp;
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);
}
/* 生成SQL语句文本 */
strcpy(sqltxt, "UPDATE test_tab SET NAME=:1, ADDR=:2 WHERE ID=:3");
slen = strlen(sqltxt);
/* 准备语句 */
if (check_oci_error(errhp,
OCIStmtPrepare(smthp, errhp, (const OraText *)sqltxt, slen,
OCI_NTV_SYNTAX, OCI_DEFAULT)) < 0)
return (-1);
/* 绑定第一个占位符NAME */
if (check_oci_error(errhp,
OCIBindByPos((OCIStmt *)smthp,
(OCIBind **)&bndp,
errhp,
(ub4)1, /* 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)0, /* maxarr_len */
(ub4 *)NULL, /* curelep */
(ub4)OCI_DEFAULT) /* mode */
) < 0)
return (-1);
/* 绑定第二个占位符ADDR */
if (check_oci_error(errhp,
OCIBindByPos((OCIStmt *)smthp,
(OCIBind **)&bndp,
errhp,
(ub4)2, /* 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)0, /* maxarr_len */
(ub4 *)NULL, /* curelep */
(ub4)OCI_DEFAULT) /* mode */
) < 0)
return (-1);
/* 绑定第三个占位符ID */
if (check_oci_error(errhp,
OCIBindByPos((OCIStmt *)smthp,
(OCIBind **)&bndp,
errhp,
(ub4)3, /* 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)0, /* maxarr_len */
(ub4 *)NULL, /* curelep */
(ub4)OCI_DEFAULT) /* mode */
) < 0)
return (-1);
/* 赋值绑定的变量数据 */
strcpy(name, "AAAAAAAA");
strcpy(addr, "BBBBBBBBBBBBBBBBBBBB");
id = 1;
/* 指示符赋值为0,输入非NULL数据 */
ind_name = 0;
ind_addr = 0;
ind_id = 0;
/* 赋值变量的真实数据长度 */
alen_name = strlen(name) + 1;
alen_addr = strlen(addr) + 1;
alen_id = 4;
/* 执行OCI语句 */
if (check_oci_error(errhp,
OCIStmtExecute(svchp,
smthp, /* stmthp */
errhp, /* errhp */
1, /* iters */
0, /* rowoff */
NULL, /* snap_in */
NULL, /* snap_out */
OCI_DEFAULT) /* mode */
) < 0)
return (-1);
/* 提交改变的数据 */
if (check_oci_error(errhp,
OCITransCommit(svchp, errhp, OCI_DEFAULT)) < 0)
return (-1);
return (0);
}
删除数据源代码。
OCIEnv *envhp = NULL;
OCIError *errhp = NULL;
OCIServer *svrhp = NULL;
OCISession *usrhp = NULL;
OCISvcCtx *svchp = NULL;
OCIStmt *smthp = NULL;
/* 删除一条数据 */
int delete_one_row(void)
{
sword rc;
int slen;
sb2 ind_id;
ub2 alen_id;
ub2 rcode_id;
int32_t id;
OCIBind *bndp;
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);
}
/* 生成SQL语句文本 */
strcpy(sqltxt, "DELETE FROM test_tab WHERE ID=:1");
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,
OCIBindByPos((OCIStmt *)smthp,
(OCIBind **)&bndp,
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)0, /* maxarr_len */
(ub4 *)NULL, /* curelep */
(ub4)OCI_DEFAULT) /* mode */
) < 0)
return (-1);
/* 赋值绑定的变量数据 */
id = 1;
/* 指示符赋值为0,输入非NULL数据 */
ind_id = 0;
/* 赋值变量的真实数据长度 */
alen_id = 4;
/* 执行OCI语句 */
if (check_oci_error(errhp,
OCIStmtExecute(svchp,
smthp, /* stmthp */
errhp, /* errhp */
1, /* iters */
0, /* rowoff */
NULL, /* snap_in */
NULL, /* snap_out */
OCI_DEFAULT) /* mode */
) < 0)
return (-1);
/* 提交改变的数据 */
if (check_oci_error(errhp,
OCITransCommit(svchp, errhp, OCI_DEFAULT)) < 0)
return (-1);
return (0);
}