ODBC支持数组插入,操作起来也很简单,与插入单条数据相似,只是在执行SQLExecute()函数之前,要设置几个语句句柄的属性,在绑定参数时传入的是数组名称而不是单个变量名称而已。先看看要设置哪几个语句句柄属性。
第一个要告诉语句使用那种数组类型,一般会使用列数组,就是数组中的数据是多行中的同一列数据,属性名称是SQL_ATTR_PARAM_BIND_TYPE,属性值是SQL_PARAM_BIND_BY_COLUMN。使用函数SQLSetStmtAttr(),具体操作如下。
SQLSetStmtAttr(stmth, SQL_ATTR_PARAM_BIND_TYPE, SQL_PARAM_BIND_BY_COLUMN, 0);
第二个要告诉语句插入数组的大小,就是一共要插入多少行数据,属性名称是SQL_ATTR_PARAMSET_SIZE,属性值是插入数据的条数,比如插入10条数据,操作如下。
SQLSetStmtAttr(stmth, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER)10, 0);
第三个要告诉语句,执行成功后返回的每行的状态,属性名称是SQL_ATTR_PARAM_STATUS_PTR,属性值是一个SQLUSMALLINT类型的数组,执行语句后,数组中每个元素代表一行的状态,比如定义数组为status[10],操作如下。
SQLSetStmtAttr(stmth, SQL_ATTR_PARAM_STATUS_PTR, status, 0);
第四个要告诉语句,执行语句后,成功插入了多少条数据,不是每条数据都能插入成功,比如插入10条数据,成功处理了8条,那么这个值就返回8。属性名称是SQL_ATTR_PARAMS_PROCESSED_PTR,属性值是一个SQLUINTEGER类型的变量,注意不是数组,比如这个变量名称为num_processed,操作如下。
SQLSetStmtAttr(stmth, SQL_ATTR_PARAMS_PROCESSED_PTR, &num_processed, 0);
在绑定参数变量时,要定义两个数组,一个是参数数组,一个是长度和指示变量数组。比如绑定一个整数,定义数组名称为id,长度和指示变量数组为len_ind1,那么绑定操作如下。
SQLINTEGER id[10];
SQLLEN len_ind1[10];
SQLBindParameter(stmth, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, id, 0, len_ind1);
下面看一个例子,用数组插入10条数据,还是用前面测试过的表进行操作。
#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 i;
int conn = 0;
SQLRETURN rc;
SQLUINTEGER num_processed;
SQLLEN ind1[10];
SQLLEN ind2[10];
SQLLEN ind3[10];
SQLLEN ind4[10];
SQLLEN ind5[10];
SQLUSMALLINT status[10];
SQLINTEGER id[10];
char dsn_str[32];
char usrname[32];
char passwd[32];
char sqltxt[512];
char f1[10][32];
char f2[10][32];
char f3[10][32];
char f4[10][32];
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);
}
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;
}
sprintf(sqltxt,
"insert into my_test_tab1 (id, f1, f2, f3, f4) values (?, ?, ?, ?, ?)");
rc = SQLPrepare(stmth, (SQLCHAR *)sqltxt, SQL_NTS);
if (rc != SQL_SUCCESS) {
fprintf(stderr, "Prepare statment error.\n");
goto free_exit;
}
/* 设置语句属性为列数组绑定 */
rc = SQLSetStmtAttr(stmth, SQL_ATTR_PARAM_BIND_TYPE, SQL_PARAM_BIND_BY_COLUMN, 0);
if (rc != SQL_SUCCESS) {
fprintf(stderr, "Set statement attribute error.\n");
goto free_exit;
}
/* 设置数组大小为10,本次插入10条数据 */
rc = SQLSetStmtAttr(stmth, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER)10, 0);
if (rc != SQL_SUCCESS) {
fprintf(stderr, "Set statement attribute error.\n");
goto free_exit;
}
/* 设置返回的每一条结果状态数组 */
rc = SQLSetStmtAttr(stmth, SQL_ATTR_PARAM_STATUS_PTR, status, 0);
if (rc != SQL_SUCCESS) {
fprintf(stderr, "Set statement attribute error.\n");
goto free_exit;
}
/* 设置执行语句后返回的成功处理条数 */
rc = SQLSetStmtAttr(stmth, SQL_ATTR_PARAMS_PROCESSED_PTR, &num_processed, 0);
if (rc != SQL_SUCCESS) {
fprintf(stderr, "Set statement attribute error.\n");
goto free_exit;
}
/* 设置要插入的数据,为每个数组元素赋值 */
for (i=0; i<10; i++) {
id[i] = i + 11;
sprintf(f1[i], "%dAAAAAAAAAA", i);
sprintf(f2[i], "%dBBBBBBBBBBBB", i);
sprintf(f3[i], "%dCCCCCCCCCCCCCC", i);
sprintf(f4[i], "%dDDDDDDDDDDDDDDDD", i);
ind1[i] = 0;
ind2[i] = SQL_NTS;
ind3[i] = SQL_NTS;
ind4[i] = SQL_NTS;
ind5[i] = SQL_NTS;
}
/* 第一个参数,ColumnSize设为0,SQL_INTEGER类型这个值会被忽略 */
rc = SQLBindParameter(stmth, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER,
0, 0, id, 0, ind1);
if (rc != SQL_SUCCESS) {
fprintf(stderr, "Bind column 1 error.\n");
goto free_exit;
}
/* 第二个参数,ColumnSize为31,BufferLength为32,相差的一个字节用于存放字符串结束符NULL */
rc = SQLBindParameter(stmth, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,
31, 0, f1, 32, ind2);
if (rc != SQL_SUCCESS) {
fprintf(stderr, "Bind column 2 error.\n");
goto free_exit;
}
rc = SQLBindParameter(stmth, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,
31, 0, f2, 32, ind3);
if (rc != SQL_SUCCESS) {
fprintf(stderr, "Bind column 3 error.\n");
goto free_exit;
}
rc = SQLBindParameter(stmth, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,
31, 0, f3, 32, ind4);
if (rc != SQL_SUCCESS) {
fprintf(stderr, "Bind column 4 error.\n");
goto free_exit;
}
rc = SQLBindParameter(stmth, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,
31, 0, f4, 32, ind5);
if (rc != SQL_SUCCESS) {
fprintf(stderr, "Bind column 5 error.\n");
goto free_exit;
}
/* 执行语句 */
rc = SQLExecute(stmth);
if (rc != SQL_SUCCESS) {
fprintf(stderr, "Execute statment error.\n");
goto free_exit;
}
/* 提交改变 */
rc = SQLEndTran(SQL_HANDLE_DBC, dbch, SQL_COMMIT);
if (rc != SQL_SUCCESS) {
fprintf(stderr, "End Transaction error.\n");
goto free_exit;
}
/* 打印成功处理的条数 */
fprintf(stdout, "Insert %d rows data successed ......\n", num_processed);
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);
}
一些Oracle内部存储的资料和一些Oracle工具源代码,高技术含量的内容,请访问www.tomcoding.com网站。