ほぇ?(#^ω^)ピキピキ
デバッガでトレースしていくと、m_pAccessor のメンバが nullptr で初期化されないまま放置されていた。
で、Accessor クラスは、どこに行った?
おそらく、class template refactoring により、自分自身に継承する形になったようです。
なので、CCommand<CDynamicStringAccessor>::SetAccessor 関数を使用して自分自身を設定する必要がありました。
せっかくなので、使い方のサンプル込みで、紹介です。
#include <iostream> #include <objbase.h> #include <atldbcli.h> int main(int argc, char* argv[] ) { HRESULT hr = CoInitialize(NULL ); if(FAILED(hr)) { std::cerr << "Fail to Initialize COM:" << hr << std::endl; } CDataSource ds; // OLEDBによるODBC接続文字列 hr = ds.OpenFromInitializationString( L"Provider=MSDASQL.1;Password=password;" L"Persist Security Info=True;" L"User ID=username;" L"Data Source=odbc_data_source_name;" L"Extended Properties=\"DSN=data_source_name;UID=username;PWD=password\"" ); CSession ss; CCommand<CDynamicStringAccessor> rs; hr = ss.Open(ds ); hr = rs.Open(ss, "select * from hoge" ); // CCommand<typename T>::m_pAccessor を初期化するコードが欠落しているため // 自分自身を設定する必要がある(どこかのタイミングで混入したバグ対応) // 2023/7/13 修正されたような気がしますが、下記コードは正しくなくなった感じがします。 // 仕様がよくわかりません。 rs.SetAccessor(&rs); hr = rs.MoveNext(); if( FAILED(hr) || hr == DB_S_ENDOFROWSET ) { std::cerr << "Fail to MoveNext: " << hr << std::endl; } // Get the column information ULONG ulColumns = rs.GetColumnCount(); DBTYPE dbtype; rs.GetColumnType( 1, &dbtype ); dbtype &= 0x3FFF; // DBTYPE_BYREF を除去 if( dbtype == DBTYPE_I4 || dbtype == DBTYPE_UI4 || dbtype == DBTYPE_R8 || dbtype == DBTYPE_STR || dbtype == DBTYPE_WSTR || dbtype == DBTYPE_DECIMAL || dbtype == DBTYPE_VARNUMERIC || dbtype == DBTYPE_NUMERIC ) { // よくあるフィールド型 } else { // 対応可能か検討が必要なフィールド型 std::cerr << "Un supported dbtype: " << dbtype << std::endl; } int nMax = 10; while(nMax) { std::string strData; for( DBORDINAL col = 1; col <= ulColumns; col++ ) { DBSTATUS dStatus; DBLENGTH nLength; rs.GetStatus( col, &dStatus ); rs.GetLength( col, &nLength ); if( col > 1 ) { std::cout << ", "; } if( FAILED( dStatus ) ) { std::cout << "<<ERROR>>"; } else if( dStatus == DBSTATUS_S_ISNULL ) { std::cout << "<<NULL>>"; } else { std::cout << rs.GetString(col); } } std::cout << std::endl; hr = rs.MoveNext(); if( FAILED(hr) || hr == DB_S_ENDOFROWSET ) break; --nMax; } rs.Close(); ss.Close(); ds.Close(); CoUninitialize(); return 0; }2023/07/13 追記: バグは修正されたのか、仕様が変わったのか、よくわからない状況になりました。
0 件のコメント:
コメントを投稿