BUG: CRecordset Does Not Set HSTMT Attributes for Updates

Last reviewed: January 8, 1998
Article ID: Q178967
The information in this article applies to:
  • The Microsoft Foundation Classes (MFC)
  • Microsoft Visual C++, 32-bit Enterprise Edition, versions 5.0, 5.0sp1, 5.0sp2, 5.0sp3

SYMPTOMS

When updating using the cursor library or when using a cursor that causes MFC to use SQL statements to update, CRecordset errors can occur when using strings containing ODBC escape sequences. For example, the string “{d2fcfefb-6126-11d1-84c1-0020afd6c52f}” may cause a data conversion error because “{d” is the ODBC escape sequence for a date. The error occurs whether the SQLSetStmtOption() attribute SQL_NOSCAN is set to SQL_NOSCAN_ON or SQL_NOSCAN_OFF.

CAUSE

In the CRecordset::PrepareUpdateHstmt() function, CRecordset allocates a handle to use to update m_hstmtUpdate. However, CRecordset does not apply the HSTMT attributes on its default HSTMT, m_hstmt, to m_hstmtUpdate. Therefore any statement attributes set by the user will not be seen in an update.

For example, given the code:

   void CSampleSet::OnSetOptions(HSTMT hstmt)
   {
      CRecordset::OnSetOptions(hstmt);

      SQLSetStmtOption(hstmt, SQL_NOSCAN, SQL_NOSCAN_ON);
   }

updates may fail for fields that contain ODBC escape because m_hstmtUpdate will have the SQL_NOSCAN option turned off. For example you might get a data conversion error from the ODBC driver.

RESOLUTION

It is possible to work around this bug by taking the following steps:

For dynamically linking the MFC library:

  1. Copy the implementations of CRecordset::UpdateInsertDelete() and CRecordset::PrepareUpdateHstmt() to your CRecordset derived class.

  2. If you haven't already implemented the virtual CRecordset::Update() function, copy the MFC implementation of that method.

  3. In the copied CRecordset::PrepareUpdateHstmt(), change the block of code that reads

          if (m_hstmtUpdate == SQL_NULL_HSTMT)
          {
    
             AFX_SQL_SYNC(::SQLAllocStmt(m_pDatabase->m_hdbc, &m_hstmtUpdate));
             if (!Check(nRetCode))
             {
                TRACE0("Error: failure to allocate update statement.\n");
                AfxThrowDBException(nRetCode, m_pDatabase, m_hstmtUpdate);
             }
          }
    
       to the following:
    
          if (m_hstmtUpdate == SQL_NULL_HSTMT)
          {
             AFX_SQL_SYNC(::SQLAllocStmt(m_pDatabase->m_hdbc, &m_hstmtUpdate));
             if (!Check(nRetCode))
             {
                TRACE0("Error: failure to allocate update statement.\n");
                AfxThrowDBException(nRetCode, m_pDatabase, m_hstmtUpdate);
             }
    
             OnSetOptions(m_hstmtUpdate);
          }
    
    
This will ensure that the options set in the virtual function OnSetOptions() are applied to the member m_hstmtUpdate.

For statically linking the MFC library, you can either follow the steps above or you can modify your version of MFC sources directly by following step 3 above in the CRecordset class and rebuilding.

It is highly recommended that developers do not directly modify the MFC source. For more information on rebuilding the MFC static library, see the README.TXT file in the MFC\SRC directory.

STATUS

Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. We are researching this bug and will post new information here in the Microsoft Knowledge Base as it becomes available.

REFERENCES

For more information on ODBC escape sequences, see Chapter 8 and Appendix C, ODBC Programmers Reference.


Additional query words: scalar functions
Keywords : MfcDatabase
Technology : odbc
Version : WINDOWS:5.0,5.0sp1,5.0sp2,5.0sp3; WINNT:5.0,5.0sp1,5.0sp2,5.0sp3
Platform : WINDOWS winnt
Issue type : kbbug
Solution Type : kbpending


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: January 8, 1998
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.