关键字:人大金仓、KingbaseES、odbc
概述
在ODBC中如果需要插入多条的数据(如向创建的表中插入一万条数据)等需要大量重复执行DML语句的情况下,会造成操作耗时长,数据库服务器IO的函数占比大等问题。而使用批量执行DML的方法,能够减少向数据库发送插入语句等DML语句报文,较少与服务器之间的IO交互,能提升插入效率,缩短执行时间。
批量操作实现步骤
ODBC驱动默认是不开启批量DML参数的,只有在有性能需要的前提下,开启批量插入的参数,参数项名为BatchInsertSize_Ext。将该参数的值设置为1则开启批量插入,默认不使用批量插入时值为0。
该参数项可以在连接串中配置:
DRIVER={KingbaseES 9 ODBC Driver};SERVER=127.0.0.1;UID=***;PWD=***;DATABASE=database;PORT=54321;BatchInsertSize_Ext=1
或者在配置文件odbc.ini中配置:
[kingbase] | |
Driver | = KingbaseES 9 ODBC Driver |
DATABASE | = database |
DESCRIPTION | = KingbaseES 9 ODBC Driver |
SERVER | = 127.0.0.1 |
UID | = *** |
PASSWORD | = *** |
PORT | = 54321 |
BatchInsertSize_Ext | = 1 |
ODBC中实现批量操作是基于prepare语句实现的,其支持的操作有“insert、update、delete“,具体实现的步骤为:
1. 调用SQLBindParameter函数绑定参数,但是一条语句中,绑定参数个数不能超过32767个;
2. 调用SQLPrepare函数进行预处理,进行参数替换;
3. 调用SQLExecute函数进行语句提交。
使用SQLExecute提交之后:
1.若全部成功,则会返回执行成功的数据行数。
2.若部分成功,遇到执行失败,则返回,并提交能成功变更的数据,以及返回错误信息和影响行数。
3.全部失败,直接返回错误信息。
批量操作实现实例
使用批量操作执行“insert”操作,如下,在使用开启批量操作的参数“BatchInsertSize_Ext=1”的情况下与数据库建立连接,并在此连接的基础下申请语句句柄后便可调用SQLExecDriect函数创建表“tmptable”。而后再依次进行参数绑定、语句预处理、提交等操作。
/*连接串中开启批量执行的参数*/
snprintf(dsn, sizeof(dsn), "DSN=%s;%s", test_dsn, "BatchInsertSize_Ext=1");
/* 初始化 ODBC 的环境资源 */
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
/* 设置 ODBC 的版本 */
SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
/* 申请连接句柄 */
SQLAllocConnect(env, &conn);
/* 使用数据源名建立连接 */
SQLDriverConnect(conn, NULL, (SQLCHAR*)dsn, SQL_NTS, str, sizeof(str), &strl, SQL_DRIVER_COMPLETE);
/* 在连接句柄下申请一个语句句柄 */
SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt);
/*创建一个表用于测试批量操作*/
SQLExecDirect(hstmt, (SQLCHAR*)"CREATE TABLE tmptable(c1 int4 primary key, c2 int4)", SQL_NTS);
/*进行参数的绑定*/
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, array1, 0, ind_array1);
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, array2, 0, ind_array2);
/*进行语句的预处理*/
SQLPrepare(hstmt, (SQLCHAR *)"insert INTO tmptable VALUES(? , ? )", SQL_NTS);
/*提交语句*/
SQLExecute(hstmt);
同样使用批量操作执行“update、delete”操作,与执行“insert”的操作类似,需要根据实际进行参数的绑定以及更改语句。
使用ODBC批量执行“update”:
/*连接串中开启批量执行的参数*/
snprintf(dsn, sizeof(dsn), "DSN=%s;%s", test_dsn, "BatchInsertSize_Ext=1");
/* 初始化 ODBC 的环境资源 */
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
/* 设置 ODBC 的版本 */
SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
/* 申请连接句柄 */
SQLAllocConnect(env, &conn);
/* 使用数据源名建立连接 */
SQLDriverConnect(conn, NULL, (SQLCHAR*)dsn, SQL_NTS, str, sizeof(str), &strl, SQL_DRIVER_COMPLETE);
/* 在连接句柄下申请一个语句句柄 */
SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt);
/*创建一个表用于测试批量操作*/
SQLExecDirect(hstmt, (SQLCHAR*)"CREATE TABLE tmptable(c1 int4 primary key, c2 int4)", SQL_NTS);
/*进行参数的绑定*/
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, array1, 0, ind_array1);
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, array2, 0, ind_array2);
/*进行语句的预处理*/
SQLPrepare(hstmt, (SQLCHAR*)"update tmptable SET c1 = ? WHERE c2 = ? ", SQL_NTS);
/*提交语句*/
SQLExecute(hstmt);
使用ODBC批量执行“delete”:
/*连接串中开启批量执行的参数*/
snprintf(dsn, sizeof(dsn), "DSN=%s;%s", test_dsn, "BatchInsertSize_Ext=1");
/* 初始化 ODBC 的环境资源 */
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
/* 设置 ODBC 的版本 */
SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
/* 申请连接句柄 */
SQLAllocConnect(env, &conn);
/* 使用数据源名建立连接 */
SQLDriverConnect(conn, NULL, (SQLCHAR*)dsn, SQL_NTS, str, sizeof(str), &strl, SQL_DRIVER_COMPLETE);
/* 在连接句柄下申请一个语句句柄 */
SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt);
/*创建一个表用于测试批量操作*/
SQLExecDirect(hstmt, (SQLCHAR*)"CREATE TABLE tmptable(c1 int4 primary key, c2 int4)", SQL_NTS);
/*进行参数的绑定*/
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, array1, 0, ind_array1);
/*进行语句的预处理*/
SQLPrepare(hstmt, (SQLCHAR*)"delete tmptable WHERE c1 = ? ", SQL_NTS);
/*提交语句*/
SQLExecute(hstmt);
参考资料
提供该题目相关内容在产品手册中可以系统学习的位置,例如:




