BUG: SQLGetDescField to Get Table Name Does Not Work with Firehose Cursor and/or Parameter (274829)



The information in this article applies to:

  • Microsoft Data Access Components 2.1
  • Microsoft Data Access Components 2.5
  • Microsoft Data Access Components 2.6
  • Microsoft Data Access Components 2.7

This article was previously published under Q274829

SYMPTOMS

The Microsoft ODBC driver for SQL Server may fail to retrieve the table name with the SQLGetDescField function when a "firehose" cursor or a prepared statement with parameter markers is used.

The following table lists the conditions and the SQL Server version against which this behavior is observed:

ConditionSQL Server 7.0SQL Server 2000
Firehose + ParameterDoesn't workDoesn't work
Firehose + No ParameterDoesn't workDoesn't work
Non-Firehose + ParameterDoesn't workWorks
Non-Firehose + No ParameterWorksWorks

STATUS

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

MORE INFORMATION

Steps to Reproduce Behavior

  1. Create a Win32 console application and add following code to it:
    // Start of code.
    #include <windows.h>
    #include <stdio.h>
    #include <sql.h>
    #include <odbcinst.h>
    #include <sqlext.h>
    #include "odbcss.h"
    #include <iostream>
     
    using namespace std;
     
    
    void main()
    {
     
        const int  MAX_STR_LEN = 256;
     SQLHENV   hEnv;
     SQLHDBC   hConn;
     SQLHSTMT  hStmt;
     SQLRETURN  nRet;
     SQLHDESC  hDescIRD;
     SQLINTEGER  iResultDesc;
     SQLINTEGER  iTableDesc;
     SQLCHAR   szTableName[MAX_STR_LEN];
     char   szNum[] = "CA";
     SQLINTEGER   nIndicator = SQL_NTS;
     
    
      // Allocate environment.
      nRet = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv);
     
      // Set the environment attributes. Setting the odbc version must be the first thing done.
      nRet = SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, NULL);
     
      // Allocate connection.
      nRet = SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hConn);
     
      //Change the Connection string accordingly.
      nRet = SQLDriverConnect(hConn, NULL, (SQLCHAR*)"DSN=DSN NAME;UID=User ID;PWD=Password;", SQL_NTS,NULL, SQL_NTS, NULL, SQL_DRIVER_NOPROMPT);
     
     
      // Allocate a statement handle.
      nRet = SQLAllocHandle(SQL_HANDLE_STMT, hConn, &hStmt);
     
      // Force a non Firehose cursor
      nRet = SQLSetStmtAttr(hStmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER)SQL_CURSOR_KEYSET_DRIVEN, SQL_IS_UINTEGER);
      nRet = SQLSetStmtAttr(hStmt, SQL_ATTR_CONCURRENCY, (SQLPOINTER)SQL_CONCUR_VALUES ,SQL_IS_UINTEGER);
      nRet = SQLSetStmtAttr(hStmt, SQL_SOPT_SS_DEFER_PREPARE, (SQLPOINTER)SQL_DP_ON ,SQL_IS_UINTEGER);
      
     
      // Prepare some SQL with a "WHERE" clause.
      nRet = SQLPrepare(hStmt, (SQLCHAR*)"SELECT * from Authors WHERE state =?", SQL_NTS);
      
     
      nRet = SQLBindParameter(hStmt,1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,20,0,
       &szNum,sizeof(szNum),&nIndicator);
     
    
     // nRet = SQLExecute(hStmt);
     
    
      // Clear the memory for debugging.
      ZeroMemory(szTableName, MAX_STR_LEN);
     
      // Get handle to IRD.
      nRet = SQLGetStmtAttr(hStmt, SQL_ATTR_IMP_ROW_DESC, &hDescIRD, sizeof(SQLHDESC), &iResultDesc);
     
      // Try getting the table name directly from the IRD for first column.
      nRet = SQLGetDescField(hDescIRD, 1, SQL_DESC_BASE_TABLE_NAME, szTableName, MAX_STR_LEN, &iTableDesc);
     
      cout << "Table name: " << szTableName << endl;
      
    }
    // End of code.
    					
  2. Change the connection information, and then compile and run this code against SQL Server 7.0. The result is that no table name metadata is retrieved.
  3. Comment the call to SQLSetStmtAttr to change the cursor type, and then compile and run the code. No table name metadata is retrieved.
  4. Change the connection information to connect to SQL Server 2000, and then compile and run the code. The table name is displayed.
  5. Comment the call to SQLSetStmtAttr to get the default firehose cursor, and then compile and run the code against SQL Server 2000. The code does not display any metadata.

Modification Type:MajorLast Reviewed:5/12/2003
Keywords:kbbug kbnofix KB274829