unixODBC编程(四)插入数据
ODBC插入数据也有一定的步骤,我们先来看一下。
1. 分配一个语句句柄,使用SQLAllocHandle()函数,句柄类型为SQL_HANDLE_STMT。
2. 准备语句,使用SQLPrepare()函数。
3. 为绑定的变量赋值。
4. 绑定输入变量,使用SQLBindParameter()函数。
5. 执行语句,使用SQLExecute()函数。
6. 提交执行结果,使用SQLEndTran()函数。
这里只有两个新函数,SQLBindParameter()和SQLEndTran()。看一下他们的原型和参数。
绑定输入变量函数。
SQLRETURN SQLBindParameter(
SQLHSTMT StatementHandle,
SQLUSMALLINT ParameterNumber,
SQLSMALLINT InputOutputType,
SQLSMALLINT ValueType,
SQLSMALLINT ParameterType,
SQLULEN ColumnSize,
SQLSMALLINT DecimalDigits,
SQLPOINTER ParameterValuePtr,
SQLLEN BufferLength,
SQLLEN * StrLen_or_IndPtr);
StatementHandle是一个输入参数,语句句柄。
ParameterNumber是一个输入参数,参数编号,按递增参数顺序按顺序排序,从 1 开始。
InputOutputType是一个输入参数,指示绑定的参数是输入还是输出,这里是SQL_PARAM_INPUT。
ValueType是一个输入参数,指示绑定参数的 C 数据类型。参考下面的表。
ParameterType是一个输入参数,指示绑定参数的 SQL 数据类型。参考下面的表。
ColumnSize是一个输入参数,指示绑定参数列大小,即表的列长度。字符类型的列可以设置长度,其他类型会忽略。
DecimalDigits是一个输入参数,指示绑定参数标记的列的十进制数字位数。其他类型忽略。
ParameterValuePtr是一个输入参数,指向绑定参数数据的缓冲区的指针。
BufferLength是一个输入/输出参数,指示ParameterValuePtr 缓冲区的长度(以字节为单位)。主要限制输出的数据不要超出缓冲区。
StrLen_or_IndPtr是一个输入参数,指向绑定参数长度缓冲区的指针,用作输入的数据长度或指示变量。
ValueType类型对照表
C 类型标识符 | ODBC C typedef | C 类型 |
---|---|---|
SQL_C_CHAR | SQLCHAR * | unsigned char * |
SQL_C_WCHAR | SQLWCHAR * | wchar_t * |
SQL_C_SSHORT | SQLSMALLINT | short int |
SQL_C_USHORT | SQLUSMALLINT | unsigned short int |
SQL_C_SLONG | SQLINTEGER | long int |
SQL_C_ULONG | SQLUINTEGER | unsigned long int |
SQL_C_FLOAT | SQLREAL | FLOAT |
SQL_C_DOUBLE | SQLDOUBLE、SQLFLOAT | Double |
SQL_C_BIT | SQLCHAR | unsigned char |
SQL_C_STINYINT | SQLSCHAR | signed char |
SQL_C_UTINYINT[j] | SQLCHAR | unsigned char |
SQL_C_SBIGINT | SQLBIGINT | _int64 |
SQL_C_UBIGINT | SQLUBIGINT | unsigned _int64 |
SQL_C_BINARY | SQLCHAR * | unsigned char * |
事务提交函数。
SQLRETURN SQLEndTran(
SQLSMALLINT HandleType,
SQLHANDLE Handle,
SQLSMALLINT CompletionType);
HandleType是一个输入参数,句柄类型标识符。 包含SQL_HANDLE_ENV(如果 Handle 是环境句柄 )或SQL_HANDLE_DBC(如果 Handle 是连接句柄)。
Handle是一个输入参数,HandleType 指示的类型句柄,指示事务的范围。
CompletionType是一个输入参数,以下两个值之一:SQL_COMMIT或SQL_ROLLBACK。
看一个实际的例子,在表中插入一条数据,表结构为:
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NOT NULL NUMBER
F1 VARCHAR2(100)
F2 VARCHAR2(200)
F3 VARCHAR2(200)
F4 VARCHAR2(200)
插入语句为insert into test_tab1 (id, f1, f2, f3, f4) values (?, ?, ?, ?, ?),问号表示输入参数,需要在后面绑定变量。实际的代码如下。
#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 conn = 0;
SQLRETURN rc;
SQLLEN ind1;
SQLLEN ind2;
SQLLEN ind3;
SQLLEN ind4;
SQLLEN ind5;
SQLINTEGER id;
char dsn_str[32];
char usrname[32];
char passwd[32];
char sqltxt[512];
char f1[32];
char f2[32];
char f3[32];
char f4[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 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;
}
id = 10;
strcpy(f1, "AAAAAAAAAA");
strcpy(f2, "BBBBBBBBBBBB");
strcpy(f3, "CCCCCCCCCCCCCC");
strcpy(f4, "DDDDDDDDDDDDDDDD");
ind1 = 0;
ind2 = SQL_NTS;
ind3 = SQL_NTS;
ind4 = SQL_NTS;
ind5 = SQL_NTS;
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;
}
rc = SQLBindParameter(stmth, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 100, 0, &f1, 0, &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, 200, 0, &f2, 0, &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, 200, 0, &f3, 0, &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, 200, 0, &f4, 0, &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 data successed ......\n");
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);
}
如果对编程有兴趣,请访问www.tomcoding.com网站,里面有高技术含量的代码和文档下载。