田口と申します。

OLE DBの使い方で質問があります。

Oracleに対して、OLE DBを使用してアクセスするプログラムを作成している
のですが、Oracle用のOLE DB Providerで、MSの MSDAORA とOracleの 
OraOLEDB で行の登録更新の動作が異なり、解決策が見出せず苦戦しており
ます。OLE DBは今回初めて使用するためまだよく理解していません。どなた
か、ご教授願えないでしょうか。

テーブルに、列名:AAA 型:varchar2(5)の列があります(5バイトの文字列)。
この列に5バイトの文字列を登録更新しようとすると、MSDAORAでは問題ない
のですが、OraOLEDBだとエラーとなってしまいます。
行の登録更新には、CRowsetクラスのInsert()とSetData()を使用しているの
ですが、これらが、DB_E_ERRORSOCCURRED (0x80040E21)を返してきます。
5バイト以下の文字列の登録更新ではエラーとなりません。列のサイズと同
じサイズの文字列を登録更新しようとすると、エラーとなってしまいます。

いろいろ調べてはみたのですが、解決できませんでした。
OraOLEDBの問題なのか、私のコーディングの問題なのか...
多分後者でしょう、私のOLE DBの使い方が未熟なんだと思います。
OLE DBの使い方でプロパティの設定など、まだ足らないところがあるのでしょ
うか?
よろしくお願いします。

#include <atlbase.h>
#include <atldbcli.h>
#include <atldbsch.h>
#include <comdef.h>

class CTestTable
{
public:
    char m_AAA[6];

    BEGIN_COLUMN_MAP(CTestTable)
        COLUMN_ENTRY(1, m_AAA);
    END_COLUMN_MAP()
};
void main()
{
    CoInitialize(NULL);
    HRESULT hr;
    CDataSource dbSource;
    CSession dbSession;
    CCommand <CAccessor<CTestTable> > dbTable;
    
    // OraOLEDB
    hr = dbSource.OpenFromInitializationString(
          (BSTR)CComBSTR(L"Provider=OraOLEDB.Oracle.1; \
                Password=aaa;User ID=bbb;Data Source=ccc"));    
    // MSDAORA
//    hr = dbSource.OpenFromInitializationString(
//            (BSTR)CComBSTR(L"Provider=MSDAORA.1; \
//                Password=aaa;User ID=bbb;Data Source=ccc"));
    hr = dbSession.Open(dbSource);

    CDBPropSet PropSet(DBPROPSET_ROWSET);
    PropSet.AddProperty(DBPROP_CANFETCHBACKWARDS, true);
    PropSet.AddProperty(DBPROP_CANSCROLLBACKWARDS, true);
    PropSet.AddProperty(DBPROP_IRowsetChange, true);
    PropSet.AddProperty(DBPROP_UPDATABILITY, \
        DBPROPVAL_UP_CHANGE | DBPROPVAL_UP_INSERT | \
        DBPROPVAL_UP_DELETE);

    hr = dbTable.Open(dbSession, "select aaa from test", &PropSet);
    strcpy(dbTable.m_AAA, "12345");     
    hr = dbTable.Insert();  // <-- DB_E_ERRORSOCCURREDとなる

    dbTable.Close();
    dbSession.Close();
    dbSource.Close();
    CoUninitialize();
}