数据库:关于BULK INSERT 学习笔记(2)

(书接上回)

数据库:关于BULK INSERT 学习笔记(1)_wenluderen的专栏-CSDN博客

***

上回完成外围的准备工作, 下面就是准备一个Sql语句,

**

甲:

得到一个语句的句柄,

ret = SQLAllocHandle(SQL_HANDLE_STMT, L_hDbc, &hStmt_yuju);//基于设备句柄 得到语句句柄

**

乙:

ODBC学习笔记—SQLSetStmtAttr_不上进的程序员-CSDN博客

**

ret = SQLSetStmtAttr(hStmt_yuju, SQL_ATTR_ROW_BIND_TYPE, (SQLPOINTER)sizeof(s_m_g), 0);//

**

SQL_ATTR_ROW_BIND_TYPE---》当 SQLFetch , SQLFetchScroll 被使用时,确定绑定方向.

列方向绑定用 SQL_BIND_BY_COLUMN.

感觉是数据传递的方向。

丙:

ret = SQLSetStmtAttr(hStmt_yuju, SQL_ATTR_PARAM_BIND_TYPE, (SQLPOINTER)sizeof(s_m_g), SQL_IS_INTEGER);

**

动态参数的绑定方向

SQL_ATTR_PARAM_BIND_TYPE-----》SQL_PARAM_BIND_BY_COLUMN 默认值,以列为方向 。

丁:

ret = SQLSetStmtAttr(hStmt_yuju, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER)(long)ROW_ARRAY_SIZE, SQL_IS_INTEGER);

**

SQL_ATTR_PARAMSET_SIZE------------->指定每个参数的取值个数. 数组元素的个数。每个数组元素对应数据库里面一行数据。

**

戊:

定义个一个数组,并且用0初始化

 SQLUSMALLINT ParamStatusArray[ROW_ARRAY_SIZE] = { 0 };

(typedef unsigned short  SQLUSMALLINT;)

(//#define ROW_ARRAY_SIZE 1000//每次插入的行数)

己:

设定状态数组
    ret = SQLSetStmtAttr(hStmt_yuju, SQL_ATTR_ROW_STATUS_PTR, ParamStatusArray, 0);//SQL_ATTR_ROW_STATUS_PTR-->当 SQLFetch 或 SQLFetchScroll时行状态描述数组.

庚:

SQL_ATTR_ROW_BIND_OFFSET_PTR-->替换列绑定指针,非空
    SQLINTEGER nBindOffset = 0;//typedef long            SQLINTEGER;
    ret = SQLSetStmtAttr(hStmt_yuju, SQL_ATTR_ROW_BIND_OFFSET_PTR, (SQLPOINTER)&nBindOffset, 0);

辛:

准备SQL语句
    SQLTCHAR sql[] = _T("Insert into ashare_ordwth  (rec_num, date, time, reff, acc, stock, bs, price, qty, status, owflag, ordrec, firmid, branchid, checkord) Values(?, ?, ?, ?, ?,?,?, ?, ?, ?, ?, ?, ?, ?, ?)");
    //ashare_ordwth  是表的名字

癸:

绑定SQL语句的参数
    //参数1:句柄
    //参数2:参数序号从1开始
    //参数3:入参  出参标识
    //参数4:字段的C数据标识符
    //参数5:字段的Sql数据标识符
    //参数6:数据类型使用的最大位数,或数据的精度
    //参数7:如果是浮点是,则对应的字段精度
    //参数8:参数值的缓冲区
    //参数9:XX
     //参数10:XX

    SQLBindParameter(hStmt_yuju, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, sizeof(s_m_g_array[0].rec_num), 0, &s_m_g_array[0].rec_num, sizeof(s_m_g_array[0].rec_num), &s_m_g_array[0].rec_numInd);
    SQLBindParameter(hStmt_yuju, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(s_m_g_array[0].date) - 1, 0, &s_m_g_array[0].date, sizeof(s_m_g_array[0].date), &s_m_g_array[0].dateInd);
    SQLBindParameter(hStmt_yuju, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(s_m_g_array[0].time) - 1, 0, &s_m_g_array[0].time, sizeof(s_m_g_array[0].time), &s_m_g_array[0].timeInd);
    SQLBindParameter(hStmt_yuju, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(s_m_g_array[0].reff) - 1, 0, &s_m_g_array[0].reff, sizeof(s_m_g_array[0].reff), &s_m_g_array[0].reffInd);
    SQLBindParameter(hStmt_yuju, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(s_m_g_array[0].acc) - 1, 0, &s_m_g_array[0].acc, sizeof(s_m_g_array[0].acc), &s_m_g_array[0].accInd);
    SQLBindParameter(hStmt_yuju, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(s_m_g_array[0].stock) - 1, 0, &s_m_g_array[0].stock, sizeof(s_m_g_array[0].stock), &s_m_g_array[0].stockInd);
    SQLBindParameter(hStmt_yuju, 7, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(s_m_g_array[0].bs) - 1, 0, &s_m_g_array[0].bs, sizeof(s_m_g_array[0].bs), &s_m_g_array[0].bsInd);
    SQLBindParameter(hStmt_yuju, 8, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(s_m_g_array[0].price) - 1, 0, &s_m_g_array[0].price, sizeof(s_m_g_array[0].price), &s_m_g_array[0].priceInd);
    SQLBindParameter(hStmt_yuju, 9, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(s_m_g_array[0].qty) - 1, 0, &s_m_g_array[0].qty, sizeof(s_m_g_array[0].qty), &s_m_g_array[0].qtyInd);
    SQLBindParameter(hStmt_yuju, 10, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(s_m_g_array[0].status) - 1, 0, &s_m_g_array[0].status, sizeof(s_m_g_array[0].status), &s_m_g_array[0].statusInd);
    SQLBindParameter(hStmt_yuju, 11, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(s_m_g_array[0].owflag) - 1, 0, &s_m_g_array[0].owflag, sizeof(s_m_g_array[0].owflag), &s_m_g_array[0].owflagInd);
    SQLBindParameter(hStmt_yuju, 12, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(s_m_g_array[0].ordrec) - 1, 0, &s_m_g_array[0].ordrec, sizeof(s_m_g_array[0].ordrec), &s_m_g_array[0].ordrecInd);
    SQLBindParameter(hStmt_yuju, 13, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(s_m_g_array[0].firmid) - 1, 0, &s_m_g_array[0].firmid, sizeof(s_m_g_array[0].firmid), &s_m_g_array[0].firmidInd);
    SQLBindParameter(hStmt_yuju, 14, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(s_m_g_array[0].branchid) - 1, 0, &s_m_g_array[0].branchid, sizeof(s_m_g_array[0].branchid), &s_m_g_array[0].branchidInd);
    SQLBindParameter(hStmt_yuju, 15, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_BINARY, sizeof(s_m_g_array[0].checkord), 0, &s_m_g_array[0].checkord, sizeof(s_m_g_array[0].checkord), &s_m_g_array[0].checkordInd);

***********************

金:

用法类似于SQLSetEnvAttr,该函数是设置连接的各项属性用的
    //参数1:  SQLHDBC     ConnectionHandle,
    //参数2:    SQLINTEGER     Attribute,
    //参数3: SQLPOINTER     ValuePtr,
    //参数4:    SQLINTEGER     StringLength
    SQLSetConnectAttr(L_hDbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, 0);
    //SQL_AUTOCOMMIT_OFF = 驱动程序使用手动提交模式,应用程序必须使用 SQLEndTran 显式提交或回滚事务。

 木:

SQLPrepare 准备SQL字符串以执行。 是一种典型的空间换时间的算法优化。
    //ODBC中的一个API函数,用来创建SQL语句。
    //参数1:StatementHandle SQL语句句柄
    //参数2:StatementText SQL语句
    //参数3:TextLength SQL字符串长度
    ret = SQLPrepare(hStmt_yuju, sql, SQL_NTS);

水:

给卡车装货, 前文说到, BULK INSERT 是把一堆数据整理好,码放整齐,放入卡车,一次性拉入超市。这样速度快。
    int rec_num = 1;
    for (int i = 0; i < ROW_ARRAY_SIZE; i++)// 给数据赋值
    {
        s_m_g_array[i].rec_num = rec_num++;
        s_m_g_array[i].ordrecInd = 0;

        strcpy((char*)s_m_g_array[i].date, "20150120");
        s_m_g_array[i].dateInd = SQL_NTS;

        strcpy((char*)s_m_g_array[i].time, "13:20:10");
        s_m_g_array[i].timeInd = SQL_NTS;

        strcpy((char*)s_m_g_array[i].reff, "1234567890");
        s_m_g_array[i].reffInd = SQL_NTS;

        strcpy((char*)s_m_g_array[i].acc, "0000011111");
        s_m_g_array[i].accInd = SQL_NTS;

        strcpy((char*)s_m_g_array[i].stock, "123456");
        s_m_g_array[i].stockInd = SQL_NTS;

        strcpy((char*)s_m_g_array[i].bs, "B");
        s_m_g_array[i].bsInd = SQL_NTS;

        strcpy((char*)s_m_g_array[i].price, "1.000");
        s_m_g_array[i].priceInd = SQL_NTS;

        strcpy((char*)s_m_g_array[i].qty, "1000");
        s_m_g_array[i].qtyInd = SQL_NTS;

        strcpy((char*)s_m_g_array[i].status, "R");
        s_m_g_array[i].statusInd = SQL_NTS;

        strcpy((char*)s_m_g_array[i].owflag, "ORD");
        s_m_g_array[i].owflagInd = SQL_NTS;

        strcpy((char*)s_m_g_array[i].ordrec, "1");
        s_m_g_array[i].ordrecInd = SQL_NTS;

        strcpy((char*)s_m_g_array[i].firmid, "123");
        s_m_g_array[i].firmidInd = SQL_NTS;

        strcpy((char*)s_m_g_array[i].branchid, "20201");
        s_m_g_array[i].branchidInd = SQL_NTS;

        ::memset(s_m_g_array[i].checkord, 0, sizeof(s_m_g_array[i].checkord));
        s_m_g_array[i].checkordInd = sizeof(s_m_g_array[i].checkord);
    }

火:

执行语句,并检查错误,如果没有错误就提交
    ret = SQLExecute(hStmt_yuju);

if (ret == SQL_ERROR)
    {
        //wchar_t
        // SQLCHAR 
        //typedef unsigned char   SQLCHAR;
        SQLWCHAR msg[128];
        SQLWCHAR state[128];
        SQLINTEGER error_id;
        SQLSMALLINT text;
        SQLGetDiagRec(SQL_HANDLE_STMT, hStmt_yuju, 1, state, &error_id, msg, 128, &text);
        printf("db Insert fail, sqlstate=%s, errormsg=%s\n", state, msg);

        SQLEndTran(SQL_HANDLE_DBC, L_hDbc, SQL_ROLLBACK);

        system("pause");
        return 0;//返回 就不在提交事务,这个程序写很严谨啊
    }
    else if (ret == SQL_SUCCESS_WITH_INFO)
    {
        SQLWCHAR msg[128];
        SQLWCHAR state[128];
        SQLINTEGER error_id;
        SQLSMALLINT text;
        SQLGetDiagRec(SQL_HANDLE_STMT, hStmt_yuju, 1, state, &error_id, msg, 128, &text);
        printf("warning msg=%s\n", msg);
    }
    //SQLEndTran 针对与连接关联的所有语句的所有活动操作请求提交或回滚操作。 
    //SQLEndTran 还可以请求对与环境关联的所有连接执行提交或回滚操作。
    SQLEndTran(SQL_HANDLE_DBC, L_hDbc, SQL_COMMIT);//SQL_COMMIT--提交事务
    printf("写入事物已经提交\n");

土:

释放语句句柄
    if (hStmt_yuju)
    {
        ret = SQLFreeHandle(SQL_HANDLE_STMT, hStmt_yuju);
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值