ODBC带参数调用SQLExecute()返回SQL_NEED_DATA问题咨询
问题描述
ODBC数据库编程场景下,无参数调用SQLExecute()可正常执行成功,完成参数绑定后调用该接口会返回SQL_NEED_DATA,已确认SQLPrepare()、SQLBindParameter()接口自身均返回执行成功,问题复现代码如下:
ret = SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt); SQLSetStmtAttr(hStmt, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER)3, 0); SQLCHAR* SQLToExe3 = (SQLCHAR*) "INSERT INTO student VALUES(?,?,?)" ; ret = SQLPrepare(hStmt, SQLToExe3, SQL_NTS); Test(ret); SQLCHAR SNOInput[SNO_Len]="2030211892", SNameInput[SName_Len]="zhangxun", SDepartInput[SDepart_Len]="CS"; SQLLEN SNOLen,SNameLen2,SDepartLen2; ret = SQLBindParameter(hStmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 20, 0, SNOInput, SNO_Len, &SNOLen); ret = SQLBindParameter(hStmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 20, 0, SNameInput, SName_Len, &SNameLen2); ret = SQLBindParameter(hStmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 20, 0, SDepartInput, SNO_Len, &SDepartLen2); ret = SQLExecute(hStmt);// SQLExecute return SQL_INVALID_HANDLE
根因分析
代码存在两个明确问题,直接触发异常返回:
- 三个参数绑定对应的长度指示变量
SNOLen、SNameLen2、SDepartLen2定义后未赋值,指向的内存为随机野值。SQLBindParameter最后一个参数是长度/指示符缓冲区指针,ODBC驱动执行SQLExecute()时会读取该缓冲区的值判断参数处理方式:如果读到的值为SQL_DATA_AT_EXEC预留值,驱动会判定该参数需要在执行阶段通过SQLPutData逐块传入,因此直接返回SQL_NEED_DATA等待应用提交数据,不会直接执行语句。 - 第三个字段
SDepartInput绑定参数时,缓冲区长度参数错误传入SNO_Len,与该字段实际分配的缓冲区长度SDepart_Len不匹配,存在内存越界访问风险,极端场景下会触发句柄无效类错误。
修复方法
- 初始化三个长度指示变量,由于绑定的是C风格以
\0结尾的字符串,可直接赋值为SQL_NTS,告知驱动自动识别字符串长度,也可填入对应字符串的实际字节长度。 - 修正第三个参数绑定的缓冲区长度传参,替换为匹配
SDepartInput缓冲区的SDepart_Len。
修复后的核心代码片段:
SQLCHAR SNOInput[SNO_Len]="2030211892", SNameInput[SName_Len]="zhangxun", SDepartInput[SDepart_Len]="CS"; SQLLEN SNOLen = SQL_NTS, SNameLen2 = SQL_NTS, SDepartLen2 = SQL_NTS; ret = SQLBindParameter(hStmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 20, 0, SNOInput, SNO_Len, &SNOLen); ret = SQLBindParameter(hStmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 20, 0, SNameInput, SName_Len, &SNameLen2); ret = SQLBindParameter(hStmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 20, 0, SDepartInput, SDepart_Len, &SDepartLen2); ret = SQLExecute(hStmt);
内容的提问来源于stack exchange,提问作者DoGoodDeeds
相关产品推荐
相关产品推荐

