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號