unxODBC编程(六)数组插入
访问www.tomcoding.com网站,学习Oracle内部数据结构,详细文档说明,下载Oracle的exp/imp,DUL,logminer,ASM工具的源代码,学习高技术含量的内容。
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网站。

浙公网安备 33010602011771号