首页 > 解决方案 > 在 Azure 服务器上的 SQLExecute 之前使用 SQLSetStmtAttr 时出错

问题描述

情况:

我有一个带有两个数据库的 Azure 数据库服务器。我将第二个表作为外部表连接到第一个表,如下所示

问题:

当我现在尝试使用 ODBC 从第二个表中进行选择时,我得到 SQLState: 4200 和 NativeError: 8624 以及以下消息:“查询处理器无法生成查询计划。有关详细信息,请联系客户支持服务。”

这只发生在我在 SQLExecute 语句之前执行 SQLSetStmtAttr 时。
任何想法如何在 SQLExecute 语句之前执行 SQLSetStmtAttr 时避免此错误?

我有一个旧应用程序,不想将 SQLSetStmtAttr 移动到另一个位置。

代码:

#include <windows.h>  
#include <sqlext.h>
#include <string>
#include <iostream>
  
int main() {  
   SQLHENV henv;  
   SQLHDBC hdbc;  
   SQLHSTMT hstmt;  
   SQLRETURN retcode;  
  
   SQLCHAR OutConnStr[255];  
   SQLSMALLINT OutConnStrLen;  
  
   HWND desktopHandle = GetDesktopWindow();
   retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);  
   if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
      retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);   
      if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
         retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
         if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
            SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);  
            retcode = SQLDriverConnect(
               hdbc,   
               desktopHandle,   
               (SQLCHAR*)"DSN=[ODBC Servername];Uid=[Username];Pwd=[Password];Database=Databasename;",   
               _countof("DSN=[ODBC Servername];Uid=[Username];Pwd=[Password];Database=Databasename;"),  
               OutConnStr,  
               255,   
               &OutConnStrLen,  
               SQL_DRIVER_PROMPT );  
            if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {                 
               retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
           
            std::string statement = "select name FROM <ExternalTable>";
            SQLSetStmtAttr (hstmt, SQL_ATTR_ROW_ARRAY_SIZE,reinterpret_cast <SQLPOINTER> (static_cast <SQLULEN> (2)), sizeof 2);
            SQLPrepare (hstmt, (SQLCHAR *) sql.data(), sql.length());

            SQLRETURN excecuteRetCode = SQLExecute(hstmt);   
            if (excecuteRetCode == SQL_SUCCESS || excecuteRetCode == SQL_SUCCESS_WITH_INFO)
                int i = 0;
            else {
                SQLLEN numRecs = 0;
                SQLGetDiagField(SQL_HANDLE_STMT, hstmt, 0, SQL_DIAG_NUMBER, &numRecs, 0, 0);
                int i = 1;
                std::string msg;
                msg.reserve (SQL_MAX_MESSAGE_LENGTH);
                SQLRETURN   diagRecReturn;
                SQLSMALLINT msgLen;
                SQLCHAR     SqlState[6];
                SQLINTEGER  NativeError;  
                while (i <= numRecs && (diagRecReturn = SQLGetDiagRec(SQL_HANDLE_STMT, hstmt, i, SqlState, &NativeError,  
                         (SQLCHAR *) msg.data (), msg.capacity (), &msgLen)) != SQL_NO_DATA)
                {  
                   i++;
                }  
            }
               if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
                  SQLFreeHandle(SQL_HANDLE_STMT, hstmt);  
               }  
  
               SQLDisconnect(hdbc);  
            }  
  
            SQLFreeHandle(SQL_HANDLE_DBC, hdbc);  
         }  
      }  
      SQLFreeHandle(SQL_HANDLE_ENV, henv);  
   }  
}

标签: c++sqlazureodbcazure-sql-database

解决方案


推荐阅读