CRecordset::snapshot doesn't work in VS2012 anymore - what's the alternative?

后端 未结 3 581
终归单人心
终归单人心 2021-01-14 09:04

Apparently, in VS2012, SQL_CUR_USE_ODBC is deprecated. [Update: it appears that the cursors library has been removed from VS2012 entirely].

MFC\'s CDatabase doesn\'

3条回答
  •  挽巷
    挽巷 (楼主)
    2021-01-14 09:52

    I found a solution that appears to work. I overrode OpenEx the exact same way VS 2012 has it because we need that to call the child version of AllocConnect since it is not virtual in the parent. I also overrode AllocConnect as mentioned. In the derived version of CDatabase, try the following code:

    MyCDatabase.h

    BOOL OpenEx(LPCTSTR lpszConnectString, DWORD dwOptions = 0);
    void AllocConnect(DWORD dwOptions);
    

    MyCDatabase.cpp

    BOOL MyCDatabase::OpenEx(LPCTSTR lpszConnectString, DWORD dwOptions)
    {
    ENSURE_VALID(this);
    ENSURE_ARG(lpszConnectString == NULL || AfxIsValidString(lpszConnectString));
    ENSURE_ARG(!(dwOptions & noOdbcDialog && dwOptions & forceOdbcDialog));
    
    // Exclusive access not supported.
    ASSERT(!(dwOptions & openExclusive));
    
    m_bUpdatable = !(dwOptions & openReadOnly);
    
    TRY
    {
        m_strConnect = lpszConnectString;
    
        DATA_BLOB connectBlob;
        connectBlob.pbData = (BYTE *)(LPCTSTR)m_strConnect;
        connectBlob.cbData = (DWORD)(AtlStrLen(m_strConnect) + 1) * sizeof(TCHAR);
        if (CryptProtectData(&connectBlob, NULL, NULL, NULL, NULL, 0, &m_blobConnect))
        {
            SecureZeroMemory((BYTE *)(LPCTSTR)m_strConnect, m_strConnect.GetLength() * sizeof(TCHAR));
            m_strConnect.Empty();
        }
    
        // Allocate the HDBC and make connection
        AllocConnect(dwOptions);
        if(!CDatabase::Connect(dwOptions))
            return FALSE;
    
        // Verify support for required functionality and cache info
        VerifyConnect();
        GetConnectInfo();
    }
    CATCH_ALL(e)
    {
        Free();
        THROW_LAST();
    }
    END_CATCH_ALL
    
    return TRUE;
    }
    
    void MyCDatabase::AllocConnect(DWORD dwOptions)
    {
    CDatabase::AllocConnect(dwOptions);
    
    dwOptions = dwOptions | CDatabase::useCursorLib;
    
    // Turn on cursor lib support
    if (dwOptions & useCursorLib)
    {
        ::SQLSetConnectAttr(m_hdbc, SQL_ATTR_ODBC_CURSORS, (SQLPOINTER)SQL_CUR_USE_ODBC, 0);
        // With cursor library added records immediately in result set
        m_bIncRecordCountOnAdd = TRUE;
    }
    }
    

    Please note that you do not want to pass in useCursorLab to OpenEx at first, you need to override it in the hacked version of AllocConnect.

    Also note that this is just a hack but it appears to work. Please test all your code to be sure it works as expected but so far it works OK for me.

提交回复
热议问题