人大金仓数据库KingbaseES ODBC使用prepare进行增改

53 阅读3分钟

关键字:人大金仓、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);