Microsoft KB Archive/259477

From BetaArchive Wiki

Article ID: 259477

Article Last Modified on 8/27/2007



APPLIES TO

  • Microsoft Data Access Components 2.5
  • Microsoft Data Access Components 2.5 Service Pack 1
  • Microsoft Data Access Components 2.6



This article was previously published under Q259477

SYMPTOMS

When you attempt to use the ODBC Unicode Cursor Library from a Unicode-enabled ODBC application using Microsoft Data Access Components (MDAC) 2.5, the following warning may be returned by SQLGetDiagRecW after a successful connection using SQLConnectW:

DIAG [01000] [Microsoft][ODBC Driver Manager] Cursor library not used. Load failed (0)

The above message is not an error, because the SQLConnectW call returns SQL_SUCCESS_WITH_INFO, not SQL_ERROR. The message can also be seen in an ODBC trace of the application's activity. This problem can occur with any ODBC driver, because the error is coming directly from the ODBC driver manager.

RESOLUTION

To avoid this problem, do not use ODBC cursors in a Unicode environment.

STATUS

Microsoft has confirmed that this is a problem in the Microsoft products that are listed at the beginning of this article.

MORE INFORMATION

The ODBC functions SQLSetConnectAttr and SQLSetConnectAttrW (the Unicode version) can be used to specify how cursors are to be supported for a particular connection. To specify the cursor support for a connection, call one of these functions with the SQL_ATTR_ODBC_CURSORS attribute. There are three options available for the specified connection handle:

  • SQL_CUR_USE_IF_NEEDED
  • SQL_CUR_USE_ODBC
  • SQL_CUR_USE_DRIVER

SQLConnectW is one of the Unicode ODBC API calls that is used to establish a connection to a predefined Data Source. When this function is called, the cursor library is loaded if the SQLSetConnectAttr is set appropriately.

There are specific requirements for coding a Unicode application using ODBC. This information is provided the the ODBC Programmer's Reference under the chapter that discusses "Programming Considerations". The ODBC Programmer's reference is available from the Platform SDK, which can be obtained from the following Microsoft Developer Network (MSDN) Web site:

The ODBC Programmer's Reference is also available on the CD release of the MSDN Library.

The following code sample can be used to replicate the problem and also illustrates some of the Unicode ODBC application requirements.

Steps to Reproduce Behavior

#define _UNICODE
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sql.h>
#include <sqlext.h>
#include <sqlucode.h>
#include <odbcss.h>

void main()
{      

SQLHENV         henv;
SQLHDBC         hdbc;
SQLHSTMT        hstmt;
SQLRETURN       retcode,retcode1;
SQLINTEGER      NativeError;
SQLSMALLINT     i, MsgLen;

/* Convert the strings... */ 
WCHAR wszDSN[] = L"TestSQL";
WCHAR wszUID[] = L"sa";
WCHAR wszPWD[] = L"";
WCHAR wszSqlState[SQL_SQLSTATE_SIZEW] = L"";
WCHAR wszMsg[200] = L"";

/* Allocate environment handle. */ 
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);

if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) 
{
   /* Set the ODBC version environment attribute. */ 
   retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0); 

   if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) 
   {
      /* Allocate connection handle. */ 
      retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); 

      if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) 
      {
         /* Set client side cursor library to load... */ 
         retcode = SQLSetConnectAttr(hdbc, SQL_ATTR_ODBC_CURSORS, (void*)SQL_CUR_USE_ODBC,0);
         
         /* Connect to data source. */ 
         retcode = SQLConnectW(hdbc, wszDSN, SQL_NTS,
                  wszUID, SQL_NTS, NULL, 0);

         if ((retcode == SQL_SUCCESS_WITH_INFO) || (retcode == SQL_SUCCESS)) 
         {
            // Get the status records.
            i = 1;
            while ((retcode1 = SQLGetDiagRecW(SQL_HANDLE_DBC, hdbc, i, wszSqlState, &NativeError,
                        wszMsg, sizeof(wszMsg), &MsgLen)) == SQL_SUCCESS ||
                retcode1 ==  SQL_SUCCESS_WITH_INFO)
            {
                printf("SQLState: %S\n",wszSqlState);
                printf("NativeError: %u\n",NativeError);
                printf("Message: %S\n", wszMsg);
                i++;
            }
         }

         if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
         {
            /* Allocate statement handle. */ 
            retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); 

            if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) 
            {
                /* Process data. */ 
                  ;
                  ;

               retcode = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
            }
            retcode = SQLDisconnect(hdbc);
         }
         retcode = SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
      }
   }
   retcode = SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
}
                


Additional query words: UNICODE Cursor SQLConnectW SQLGetDiagRecW

Keywords: kbprb KB259477