Microsoft KB Archive/166756: Difference between revisions

From BetaArchive Wiki
(importing KB archive)
 
m (Text replacement - ">" to ">")
Line 111: Line 111:
     catch( CDBException* e )
     catch( CDBException* e )
     {
     {
         AfxMessageBox( e->m_strError );
         AfxMessageBox( e->m_strError );
         e->Delete();
         e->Delete();
     }
     }
     rs.Close();
     rs.Close();
Line 128: Line 128:
<li>Change all RFX_Date() calls for date parameters in your recordset's DoFieldExchange() to calls to RFX_Date2().</li>
<li>Change all RFX_Date() calls for date parameters in your recordset's DoFieldExchange() to calls to RFX_Date2().</li>
<li><p>In your new RFX_Date2() implementation, comment out the following lines, which appear under the CFieldExchange::BindParam case:</p>
<li><p>In your new RFX_Date2() implementation, comment out the following lines, which appear under the CFieldExchange::BindParam case:</p>
<pre class="codesample">      if (pFX-&gt;m_prs-&gt;IsParamStatusNull(nField - 1))
<pre class="codesample">      if (pFX->m_prs->IsParamStatusNull(nField - 1))
       {
       {
           pts = NULL;
           pts = NULL;
Line 136: Line 136:
                         </pre></li>
                         </pre></li>
<li><p>To reduce the amount of code, you may want to remove all of the cases from the select statement except the case for CFieldExchange::BindParam, and add the following lines to the top of your replacement function: <span class="kbd userinput"> </span></p>
<li><p>To reduce the amount of code, you may want to remove all of the cases from the select statement except the case for CFieldExchange::BindParam, and add the following lines to the top of your replacement function: <span class="kbd userinput"> </span></p>
<pre class="codesample">      if( CFieldExchange::BindParam != pFX-&gt;m_nOperation ) {
<pre class="codesample">      if( CFieldExchange::BindParam != pFX->m_nOperation ) {
           RFX_Date(pFX, szName, value);
           RFX_Date(pFX, szName, value);
           return;
           return;

Revision as of 19:54, 20 July 2020

Article ID: 166756

Article Last Modified on 11/21/2006



APPLIES TO

  • Microsoft Foundation Class Library 4.2, when used with:
    • Microsoft Visual C++ 5.0 Enterprise Edition
    • Microsoft Visual C++ 6.0 Enterprise Edition
    • Microsoft Visual C++ 5.0 Professional Edition
    • Microsoft Visual C++ 6.0 Professional Edition
    • Microsoft Visual C++ 6.0 Standard Edition



This article was previously published under Q166756

SYMPTOMS

When you set a previously Null date parameter to no longer be Null, using either CRecordset::SetParamNull() or CRecordset::SetFieldNull(), it may cause a subsequent call to CRecordset::Requery() to generate the following exception:

Invalid string or buffer length

CAUSE

During a call to CRecordset::Open, no memory is allocated for a Null date field. However, CRecordset::Requery expects the memory to exist.

RESOLUTION

Create a replacement for the RFX_Date function which always allocates memory for the date field. See the MORE INFORMATION section.

STATUS

Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article.

This problem was corrected in Microsoft Visual C++ .NET.


MORE INFORMATION

This problem only occurs with the version of RFX_Date that takes a CTime argument.

Steps to Reproduce Behavior

The following code displays the problem for a predefined query named Query1, which takes one date parameter:

    CMySet rs;
    try
    {
        rs.SetParamNull( 0, TRUE );
        rs.Open( CRecordset::snapshot, "{Call Query1(?)}" );
        rs.m_paramDate = CTime( 1996, 10, 13, 0, 0, 0 );
        rs.SetParamNull( 0, FALSE );
        rs.Requery();
    }
    catch( CDBException* e )
    {
        AfxMessageBox( e->m_strError );
        e->Delete();
    }
    rs.Close();
                

Steps to Replace the RFX_Date Function

The following steps detail one method of making the needed changes in RFX_Date:

  1. Copy the implementation of RFX_Date() (DEVSTUDIO\VC\MFC\SRC\DBRFX.CPP) into a new .cpp file, and rename the function to something such as RFX_Date2(). Create a header file for the .cpp file and include that in your recordset .cpp file. Be sure to type:

          #include "stdafx.h"
                                

    at the top of your new .cpp file, and include the .cpp file in your project.

  2. Change all RFX_Date() calls for date parameters in your recordset's DoFieldExchange() to calls to RFX_Date2().
  3. In your new RFX_Date2() implementation, comment out the following lines, which appear under the CFieldExchange::BindParam case:

           if (pFX->m_prs->IsParamStatusNull(nField - 1))
           {
               pts = NULL;
               *plLength = SQL_NULL_DATA;
           }
           else
                            
  4. To reduce the amount of code, you may want to remove all of the cases from the select statement except the case for CFieldExchange::BindParam, and add the following lines to the top of your replacement function:

           if( CFieldExchange::BindParam != pFX->m_nOperation ) {
               RFX_Date(pFX, szName, value);
               return;
           }



Additional query words: kbVC500bug kbVC600bug kbmfc kbdatabase kbodbc

Keywords: kbbug kbfix KB166756