4

どうやら、VS2012では、SQL_CUR_USE_ODBCは非推奨になっています。[更新:カーソルライブラリがVS2012から完全に削除されたようです]。

MFCのCDatabaseはそれを使用しなくなりました(VS2010および以前のバージョンのMFCのデフォルトでしたが)が、代わりにSQL_CUR_USE_DRIVERを使用します。

残念ながら、SQL_CUR_USE_DRIVERはJet ODBCドライバーでは正しく機能しません(Accessデータベースとやり取りしています)。ドライバーは当初、位置操作をサポートすると主張しますが(位置の更新はサポートしません)、実際にデータベースにクエリを実行しようとすると、MFCライブラリがデータベースとの読み取り専用の対話にドロップダウンするまで、すべての同時実行モデルは失敗します(これは実行されません)。私たちのために飛ぶために)。

質問

  • これは、開発者にJetベースのデータソースから離れてSQL Express(または同様のもの)に移行することを強制するMSの最新の試みですか?
  • VS2012バージョンのMFC/ODBCを介してAccessデータベースと対話するために使用する必要がある別のモダリティはありますか?(1)

参照: http ://social.msdn.microsoft.com/Forums/kk/vcmfcatl/thread/acd84294-c2b5-4016-b4d9-8953f337f30c


更新:さまざまなオプションを見ると、カーソルライブラリがVS2012のODBCライブラリから削除されているようです。Jetが位置の更新を正しくサポートしていないという事実(2)と相まって、「スナップショット」モードが使用できなくなります。基になるテーブルに主キーがある限り、「ダイナセット」をサポートしているように見えます。キーなしのテーブルは、「dynaset」モード(3)と互換性がありません。つまり、VS 2010を使い続けるか、テーブルを変更して自動番号などを含めて、レコードセットにダイナセットモードを使用できるようにpkeyを確実に使用できるようにすることができます。


(1)たとえば、CRecordsetに別のオープンタイプを使用する必要がありますか?現在、CRecordset::snapshotを使用しています。しかし、スナップショット、ダイナミック、ダイナセットのさまざまなモードを実際に理解したことはありません。「各試行」のクイックセットは、アクセスデータベースへの更新可能なインターフェイスを取得できませんでした...
(2)最初に照会されたときに要求しますが、以前にサポートすると主張したすべての同時実行モードに対してエラーを返します
(3) Jetはそれをまったくサポートしていないので(テストからわかることから)、「動的」も出ています。

4

3 に答える 3

4

うまくいくように見える解決策を見つけました。親では仮想ではないため、AllocConnectの子バージョンを呼び出す必要があるため、VS2012とまったく同じ方法でOpenExをオーバーライドしました。また、前述のようにAllocConnectを無効にしました。CDatabaseの派生バージョンで、次のコードを試してください。

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;
}
}

最初はuseCursorLabをOpenExに渡したくないことに注意してください。ハッキングされたバージョンのAllocConnectでは、それをオーバーライドする必要があります。

また、これは単なるハックですが、機能しているように見えることにも注意してください。すべてのコードをテストして、期待どおりに機能することを確認してください。ただし、これまでのところ、問題なく機能しています。

于 2013-02-21T22:10:30.557 に答える
2

他の誰かがこの問題に遭遇した場合、これが答えのようです:

ODBCをAccessデータベースに接続するには、CDatabasemydbを使用して接続します。mydb.OpenEx(..、0)。これにより、カーソルライブラリをロードしないようにシステムに要求します。

次に、レコードセットには、dynasetCMyRecordsetmyrsを使用します。myrs.Open(CRecordset :: dynaset、...)。

最後に、ダイナセット(キーセット)を使用するには、テーブルに主キーがあることを確認する必要があります。

于 2012-10-04T17:41:19.080 に答える
0

CDatabaseを派生させ、 OpenExをオーバーライドします。派生クラスで、へCMyDatabaseの呼び出しを置き換えます。明らかに、関数は目的のパラメーターを使用してSQLSetConnectOptionを呼び出す必要があります。AllocConnectMyAllocConnectMyAllocConnect

// Turn on cursor lib support
if (dwOptions & useCursorLib)
{
    AFX_SQL_SYNC(::SQLSetConnectOption(m_hdbc, SQL_ODBC_CURSORS, SQL_CUR_USE_ODBC));
    // With cursor library added records immediately in result set
    m_bIncRecordCountOnAdd = TRUE;
}

次に、すべてのクエリCMyDatabaseの代わりにクラスを使用します。CDatabase

于 2012-10-04T06:37:42.110 に答える