VC++實現批量大容量快速插入SqlServer資料庫
阿新 • • 發佈:2019-01-02
1. 概述
使用c++訪問資料庫的方法很多,由於我訪問的是sqlserver資料庫,於是上MSDN查了一下有哪些訪問技術,主要有以下幾種:- ODBC
- OLEDB
- ADO
1.1 ODBC(Open Database Connectivity)
ODBC是微軟弄出來的一個可以訪問各種資料庫的介面。ODBC存在時間比較長,是一個比較穩定的介面。它既然能夠訪問各種介面,所以它是一個最小公共集的介面。這個接口裡面可能會缺少某些資料庫的特定功能。 ODBC只是一個介面,想要使用ODBC必須提供驅動。 sqlserver 提供SQL Server Native Client ODBC driver來支援ODBC介面。1.2 OLEDB
2. 使用ODBC插入資料
ODBC插入資料速度快捷的方法主要有兩種: 1. SQLBulkOperations-
#include <windows.h>
- #include <sqlext.h>
- #include <stdio.h>
- #include <time.h>
- SQLHENV henv = NULL;
- SQLHDBC hdbc = NULL;
- SQLHSTMT hstmt = NULL;
- SQLRETURN retcode;
- #define COUNT (100000)
- #define ROW_ARRAY_SIZE 1000
- typedefstruct{
- SQLINTEGER rec_num;
- SQLINTEGER rec_numInd;
-
SQLCHAR date[9];
- SQLINTEGER dateInd;
- SQLCHAR time[9];
- SQLINTEGER timeInd;
- SQLCHAR reff[11];
- SQLINTEGER reffInd;
- SQLCHAR acc[11];
- SQLINTEGER accInd;
- SQLCHAR stock[7];
- SQLINTEGER stockInd;
- SQLCHAR bs[2];
- SQLINTEGER bsInd;
- SQLCHAR price[9];
- SQLINTEGER priceInd;
- SQLCHAR qty[9];
- SQLINTEGER qtyInd;
- SQLCHAR status[2];
- SQLINTEGER statusInd;
- SQLCHAR owflag[4];
- SQLINTEGER owflagInd;
- SQLCHAR ordrec[9];
- SQLINTEGER ordrecInd;
- SQLCHAR firmid[6];
- SQLINTEGER firmidInd;
- SQLCHAR branchid[6];
- SQLINTEGER branchidInd;
- SQLSCHAR checkord[16];
- SQLINTEGER checkordInd;
- } ORDWTH;
- typedefstruct{
- SQLINTEGER id;
- SQLCHAR date[20];
- SQLCHAR abbr[10];
- //
- SQLINTEGER idInd;
- SQLINTEGER dateInd;
- SQLINTEGER abbrInd;
- } Test;
- Test test_array[ROW_ARRAY_SIZE];
- ORDWTH ordwth_array[ROW_ARRAY_SIZE];
- int rec_num = 1;
- void main()
- {
- retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
- retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);
- retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
- retcode = SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);
- retcode = SQLConnect(hdbc, (SQLCHAR*) "ctp2_lx", SQL_NTS, (SQLCHAR*)"sa", SQL_NTS, (SQLCHAR*)"123456", SQL_NTS);
- if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
- {
- }
- else
- {
- SQLCHAR msg[128];
- SQLCHAR state[128];
- SQLINTEGER error_id;
- SQLSMALLINT text;
- SQLGetDiagRec(SQL_HANDLE_DBC, hdbc, 1, state, &error_id, msg, 128, &text);
- printf("db connect fail, sqlstate=%s, errormsg=%s\n", state, msg);
- system("pause");
- return;
- }
- retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
- printf("Inserting...\n");
- time_t begin;
- time(&begin);
- //設定SQL_ATTR_ROW_ARRAY_SIZE屬性,bulk的長度
- SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)ROW_ARRAY_SIZE, 0);
- SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_BIND_TYPE, (SQLPOINTER)sizeof(ORDWTH), 0);
- SQLUSMALLINT ParamStatusArray[ROW_ARRAY_SIZE] = { 0 };
- //設定狀態陣列
- retcode = SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_STATUS_PTR, ParamStatusArray, 0);
- SQLINTEGER nBindOffset = 0;
- SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_BIND_OFFSET_PTR, (SQLPOINTER)&nBindOffset, 0);
- retcode = SQLSetStmtAttr(hstmt, SQL_ATTR_CONCURRENCY, (SQLPOINTER)SQL_CONCUR_ROWVER, 0);
- retcode = SQLSetStmtAttr(hstmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER)SQL_CURSOR_DYNAMIC, 0);
- //進行一次查詢,得到result set
- retcode = SQLExecDirect(hstmt, (SQLCHAR*)"select rec_num, date, time, reff, acc, stock, bs, price, qty, status, owflag, ordrec, firmid, branchid, checkord from ashare_ordwth", SQL_NTS);
- //retcode = SQLExecDirect(hstmt, (SQLCHAR*)"select id, date, abbr from test", SQL_NTS);
- retcode = SQLFetchScroll(hstmt, SQL_FETCH_NEXT, 0);
- /*SQLBindCol(hstmt, 1, SQL_C_SHORT, &test_array[0].id, 0, &test_array[0].idInd);
- SQLBindCol(hstmt, 2, SQL_C_CHAR, &test_array[0].date, 20, &test_array[0].dateInd);
- SQLBindCol(hstmt, 3, SQL_C_CHAR, &test_array[0].abbr, 10, &test_array[0].abbrInd);*/
- retcode = SQLBindCol(hstmt, 1, SQL_C_LONG, &ordwth_array[0].rec_num, 0, &ordwth_array[0].rec_numInd);
- SQLBindCol(hstmt, 2, SQL_C_CHAR, &ordwth_array[0].date, sizeof(ordwth_array[0].date), &ordwth_array[0].dateInd);
- SQLBindCol(hstmt, 3, SQL_C_CHAR, &ordwth_array[0].time, sizeof(ordwth_array[0].time), &ordwth_array[0].timeInd);
- SQLBindCol(hstmt, 4, SQL_C_CHAR, &ordwth_array[0].reff, sizeof(ordwth_array[0].reff), &ordwth_array[0].reffInd);
- SQLBindCol(hstmt, 5, SQL_C_CHAR, &ordwth_array[0].acc, sizeof(ordwth_array[0].acc), &ordwth_array[0].accInd);
- SQLBindCol(hstmt, 6, SQL_C_CHAR, &ordwth_array[0].stock, sizeof(ordwth_array[0].stock), &ordwth_array[0].stockInd);
- SQLBindCol(hstmt, 7, SQL_C_CHAR, &ordwth_array[0].bs, sizeof(ordwth_array[0].bs), &ordwth_array[0].bsInd);
- SQLBindCol(hstmt, 8, SQL_C_CHAR, &ordwth_array[0].price, sizeof(ordwth_array[0].price), &ordwth_array[0].priceInd);
- SQLBindCol(hstmt, 9, SQL_C_CHAR, &ordwth_array[0].qty, sizeof(ordwth_array[0].qty), &ordwth_array[0].qtyInd);
- SQLBindCol(hstmt, 10, SQL_C_CHAR, &ordwth_array[0].status, sizeof(ordwth_array[0].status), &ordwth_array[0].statusInd);
- SQLBindCol(hstmt, 11, SQL_C_CHAR, &ordwth_array[0].owflag, sizeof(ordwth_array[0].owflag), &ordwth_array[0].owflagInd);
- SQLBindCol(hstmt, 12, SQL_C_CHAR, &ordwth_array[0].ordrec, sizeof(ordwth_array[0].ordrec), &ordwth_array[0].ordrecInd);
- SQLBindCol(hstmt, 13, SQL_C_CHAR, &ordwth_array[0].firmid, sizeof(ordwth_array[0].firmid), &ordwth_array[0].firmidInd);
- SQLBindCol(hstmt, 14, SQL_C_CHAR, &ordwth_array[0].branchid, sizeof(ordwth_array[0].branchid), &ordwth_array[0].branchidInd);
- SQLBindCol(hstmt, 15, SQL_C_BINARY, &ordwth_array[0].checkord, sizeof(ordwth_array[0].checkord), &ordwth_array[0].checkordInd);
- //關閉auto commit
- SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_IS_INTEGER);
- for (int j = 0; j < COUNT / ROW_ARRAY_SIZE; j++)
- {
- for (int i = 0; i < ROW_ARRAY_SIZE; i++)
- {
- ordwth_array[i].rec_num = rec_num++;
- ordwth_array[i].ordrecInd = 0;
- strcpy((char*)ordwth_array[i].date, "20150120");
- ordwth_array[i].dateInd = SQL_NTS;
- strcpy((char*)ordwth_array[i].time, "13:20:10");
- ordwth_array[i].timeInd = SQL_NTS;
- strcpy((char*)ordwth_array[i].reff, "1234567890"