关键字:人大金仓、KingbaseES、ODBC
概述
使用prepare来执行SQL语句,可以提高查询效率和安全。prepare语句为一种预处理机制,能够将SQL语句和参数分开,从而避免SQL注入攻击,同时减少重复编译SQL语句的次数,提高数据库查询的效率。
Prepare执行SQL语句
ODBC中使用prepare来执行SQL语句与直接执行SQL语句的调用方法有所不同,直接执行SQL语句的方法为直接调用SQLExecDirect接口将语句发送到数据源进行执行,使用prepare来执行SQL需经历三个步骤:
- 将应用程序的缓冲区绑定到SQL语句中的参数,该步骤中用的接口为SQLBindParameter,其语法为:
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 :参数的类型。
ValueType :参数的 C 数据类型。
ParameterType :SQL数据类型。
ColumnSize:相应参数标记的列或表达式的大小。
DecimalDigits:相应参数标记的列或表达式的十进制数字。
ParameterValuePtr:指向参数数据的缓冲区的指针。
BufferLength :ParameterValuePtr 缓冲区的长度(以字节为单位)。
StrLen_or_IndPtr :指向参数长度缓冲区的指针。
- 将SQL语句发送到数据源进行准备,使用到的函数为SQLPrepare,其语法为:
SQLRETURN SQLPrepare(
SQLHSTMT StatementHandle
SQLCHAR * StatementText,
SQLINTEGER TextLength);
StatementHandle :语句句柄。
StatementText :SQL文本字符串。
TextLength :以字符表示的 *StatementText 的长度。
- 使用参数标记变量的当前值执行已准备的语句,使用到的函数为SQLExecute,其语法为:
SQLRETURN SQLExecute(
SQLHSTMT StatementHandle);
StatementHandle:语句句柄。
Prepare插入与更新
按照上诉章节所述,使用prepare来执行对数据库表的数据插入,在数据库中创建有一张表“stu(id int, score int)”。应用参数调用SQLBindparameter以指定参数的ODBC C数据类型和SQL数据类型,并将缓冲区绑定到每个参数。应用程序调用SQLPrepare将SQL语句发送到数据源进行准备,在SQL语句中可包含一个或多个参数标记,并且对于要包含参数标记的位置,应用程序会将问好(?)嵌入到SQL字符串中。对于每行数据,应用程序会将数据值分配给每个参数,并调用SQLExecute执行。
如下示例中,共绑定两个参数,在调用SQLPrepare时按照绑定顺序来依次替换到语句中的“?”,既第一个“?”在替换之后的值为“Id”,第二个“?”在替换之后的值为“Score”。
Prepare插入示例:
HSTMT hstmt = SQL_NULL_HSTMT;
SQLSMALLINT Id, Score;
SQLLEN cbId, cbScore;
SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt);
//绑定参数
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &Id, 0, &cbId);
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_CHAR, 0, 0, &Score, 0, &cbScore);
//使用prepare插入数据
SQLPrepare(hstmt, (SQLCHAR *)"insert into stu values(?, ?)", SQL_NTS);
Id = 1;
Score = 99;
SQLExecute(hstmt);
Id = 2;
Score = 98;
SQLExecute(hstmt);
//释放句柄
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
//释放句柄
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
Prepare更新示例:
HSTMT hstmt = SQL_NULL_HSTMT;
SQLSMALLINT Id, Score;
SQLLEN cbId, cbScore;
SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt);
//绑定参数
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &Id, 0, &cbId);
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_CHAR, 0, 0, &Score, 0, &cbScore);
//使用prepare更新数据
SQLPrepare(hstmt, (SQLCHAR *)"update stu set id = ? where score = ?", SQL_NTS);
Id = 3;
Score = 99;
SQLExecute(hstmt);
//释放句柄
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);