プログラミング言語や環境設定を中心としたパソコン関連の技術メモです。
主にシステム開発中に調べたことをメモしています。TIPS的な位置付けで、気が向いたときにちまちま更新していきます。
VC++、OLEDBでDBアクセス。
「eMbedded  Visual  C++  4.0」+「SQL  Server  2005  Compact  Edition」の構成で
既存ソースがADOアクセスしている部分をOLEDBで地道に書き換えるってなお仕事をいただきましてね。

何とかかんとかやったのですが日本語情報が全然ねーヾ(>_<)ノ
ついでにめんどくせー!(>O<)
いつかまた使うかもしれないのでコードをメモっておきます。
基本的には
1.オブジェクトインスタンスの作成
2.DB接続
3.セッション作成
4.コマンド作成
5.コマンド実行
6.アクセサー作成
7.データ取得
8.解放
みたいな流れになるよーです。
ついでにそれぞれやる前にQueryInterfaceとかなんとか言うのを使って
なんかしてやらないといけない模様。
説明がぼんやりとしていますが、それは私の理解がぼんやりとしているからです。
と言う訳でDB接続してselect文投げるだけのコードφ(--)
たかがそれだけやるのがどれほど面倒くさかったことか・・(つд`)

        DBPROP                                dbprop[1];
        DBPROPSET                        dbpropset[1];
        IDBInitialize                *pIDBInitialize            =  NULL;
        IDBProperties              *pIDBProperties        =  NULL;
        IColumnsInfo                *pIColumnsInfo                =  NULL;
        IDBCreateCommand        *pIDBCrtCmd                          =  NULL;
        ICommandText                *pICmdText                          =  NULL;
        IDBCreateSession  *m_pIDBCreateSession;
        DBBINDING                        *prgBinding                        =  NULL;
        DBCOLUMNINFO                *pDBColumnInfo                =  NULL;
        WCHAR                                *pStringsBuffer                =  NULL;
        BYTE                                *pData                                =  NULL;
        IAccessor*                    pIAccessor                    =  NULL;
        HACCESSOR  hAccessor  =  DB_NULL_HACCESSOR;
        IRowset*                        pIRowset                        =  NULL;
        ICommandProperties  *  pICmdProps                =  NULL;      
        IRowsetPosition  *        pIRowsetPos              =  NULL;
        ULONG              cbRecordCount;  
        ULONG                                ulNumCols;
        DWORD                                dwBindingSize                =  0;
        DWORD                                dwIndex                                =  0;
        DWORD                                dwOffset                        =  0;
        DBOBJECT                        dbObject;
        const  int  COLUMN_ALIGNVAL                      =  8;
        ULONG  cRowsObtained  =  0;
        HROW*                        prghRows          =  NULL;



        //インスタンス作成
        hr  =  CoCreateInstance(  CLSID_SQLSERVERCE_3_0,
                                                NULL,
                                                CLSCTX_INPROC_SERVER,
                                                IID_IDBInitialize,
                                                (LPVOID*)&pIDBInitialize  );


        if  (  FAILED(hr)  )  {
                return(  FALSE  );
        }


        //  Initialize  property  structures      
        VariantInit(&dbprop[0].vValue);

        //  Initialize  a  property  with  name  of  database
        //
        dbprop[0].dwPropertyID                =  DBPROP_INIT_DATASOURCE;
        dbprop[0].dwOptions                        =  DBPROPOPTIONS_REQUIRED;
        dbprop[0].vValue.vt                        =  VT_BSTR;
        dbprop[0].vValue.bstrVal        =  SysAllocString(L"うんちゃらかんちゃら.sdf");
        if(NULL  ==  dbprop[0].vValue.bstrVal)
        {
                hr  =  E_OUTOFMEMORY;
                return(  FALSE  );
        }

        //  Initialize  the  property  set
        //
        dbpropset[0].guidPropertySet  =  DBPROPSET_DBINIT;
        dbpropset[0].rgProperties          =  dbprop;
        dbpropset[0].cProperties          =  sizeof(dbprop)/sizeof(dbprop[0]);

        //Set  initialization  properties.
        //
        hr  =  pIDBInitialize->QueryInterface(IID_IDBProperties,  (void  **)&pIDBProperties);
        if(FAILED(hr))
        {
                return(  FALSE  );
        }

        //  Sets  properties  in  the  Data  Source  and  initialization  property  groups
        //
        hr  =  pIDBProperties->SetProperties(1,  dbpropset);  
        if(FAILED(hr))
        {
                return(  FALSE  );
        }

        //  Initializes  a  data  source  object  
        //
        hr  =  pIDBInitialize->Initialize();
        if(FAILED(hr))
        {
                return(  FALSE  );
        }

        //  Get  IDBCreateSession  interface
        //
            hr  =  pIDBInitialize->QueryInterface(IID_IDBCreateSession,  (void**)&m_pIDBCreateSession);
        if(FAILED(hr))
        {
                return(  FALSE  );
        }
        
        hr  =  m_pIDBCreateSession->CreateSession(NULL,  IID_IDBCreateCommand,(IUnknown**)
                &pIDBCrtCmd);      
        if  (FAILED(hr))      
        {      
                return(  FALSE  );
        }      

        hr  =  pIDBCrtCmd->CreateCommand(NULL,  IID_ICommandText,  (IUnknown**)      
                &pICmdText);      
        if  (FAILED(hr))      
        {      
                return(  FALSE  );
        }      
    
        //  Request  the  ability  to  use  the  IRowsetPosition  interface.      
        dbpropset[0].cProperties          =  1;      
        dbpropset[0].guidPropertySet  =  DBPROPSET_ROWSET;      
        dbpropset[0].rgProperties        =  dbprop;      
    
        dbprop[0].dwPropertyID      =  DBPROP_CANFETCHBACKWARDS;      
        dbprop[0].dwOptions            =  DBPROPOPTIONS_REQUIRED;      
        dbprop[0].vValue.vt            =  VT_BOOL;      
        dbprop[0].vValue.boolVal  =  VARIANT_TRUE;      
    
        //  Set  the  query  text  for  the  command.              
        hr  =  pICmdText->SetCommandText(DBGUID_SQL,  L"select  うんちゃら  from  ほげほげ");        
        if  (FAILED(hr))      
        {      
                return(  FALSE  );
        }      

        hr  =  pICmdText->QueryInterface(IID_ICommandProperties,  (void**)  &pICmdProps);      
        if  (FAILED(hr))      
        {      
                return(  FALSE  );
        }      

        hr  =  pICmdProps->SetProperties(1,  dbpropset);      
        if  (FAILED(hr))      
        {      
                return(  FALSE  );
        }      

        hr  =  pICmdText->Execute(NULL,  IID_IRowset,  NULL,  NULL,      
                (IUnknown**)&pIRowset);  
        if  (FAILED(hr))      
        {      
                return(  FALSE  );
        }

        //  Get  IColumnsInfo  interface
        //
        hr  =  pIRowset->QueryInterface(IID_IColumnsInfo,  (void  **)&pIColumnsInfo);
        if(FAILED(hr))
        {
                return(  FALSE  );
        }

        //  Get  IRowsetPos  interface
        //
        hr  =  pIRowset->QueryInterface(IID_IRowsetPosition,  (void  **)&pIRowsetPos);
        if  (FAILED(hr))      
        {      
                return(  FALSE  );
        }

        //  結果の件数を取得
        hr  =  pIRowsetPos->GetRecordCount(DB_NULL_HCHAPTER,  &cbRecordCount);      
        if  (FAILED(hr))      
        {      
                return(  FALSE  );
        }

        //  Get  the  column  metadata  
        //
        hr  =  pIColumnsInfo->GetColumnInfo(&ulNumCols,  &pDBColumnInfo,  &pStringsBuffer);
        if(FAILED(hr)  ||  0  ==  ulNumCols)
        {
                return(  FALSE  );
        }

        //  Create  a  DBBINDING  array.
        //  The  binding  doesn't  include  the  bookmark  column  (first  column).
        //
        dwBindingSize  =  ulNumCols  -  1;
        prgBinding  =  (DBBINDING*)CoTaskMemAlloc(sizeof(DBBINDING)*dwBindingSize);
        if  (NULL  ==  prgBinding)
        {
                hr  =  E_OUTOFMEMORY;
                return(  FALSE  );
        }

        //  Set  initial  offset  for  binding  position
        //
        dwOffset  =  0;

        //  Prepare  structures  to  create  the  accessor
        //
        for  (dwIndex  =  0;  dwIndex  <  dwBindingSize;  ++dwIndex)
        {        
                prgBinding[dwIndex].iOrdinal        =  pDBColumnInfo[dwIndex  +  1].iOrdinal;
                prgBinding[dwIndex].pTypeInfo        =  NULL;
                prgBinding[dwIndex].pBindExt        =  NULL;
                prgBinding[dwIndex].dwMemOwner        =  DBMEMOWNER_CLIENTOWNED;
                prgBinding[dwIndex].dwFlags                =  0;
                prgBinding[dwIndex].bPrecision        =  pDBColumnInfo[dwIndex  +  1].bPrecision;
                prgBinding[dwIndex].bScale                =  pDBColumnInfo[dwIndex  +  1].bScale;
                prgBinding[dwIndex].dwPart                =  DBPART_VALUE  |  DBPART_STATUS  |  DBPART_LENGTH;
                prgBinding[dwIndex].obLength        =  dwOffset;                                                                          
                prgBinding[dwIndex].obStatus        =  prgBinding[dwIndex].obLength  +  sizeof(ULONG);    
                prgBinding[dwIndex].obValue                =  prgBinding[dwIndex].obStatus  +  sizeof(DBSTATUS);

                switch(pDBColumnInfo[dwIndex  +  1].wType)
                {
                case  DBTYPE_BYTES:
                        //  Set  up  the  DBOBJECT  structure.
                        //
                        dbObject.dwFlags  =  STGM_WRITE;
                        dbObject.iid  =  IID_ISequentialStream;
                        prgBinding[dwIndex].pObject                =  &dbObject;
                        prgBinding[dwIndex].cbMaxLen        =  sizeof(IUnknown*);
                        prgBinding[dwIndex].wType                =  DBTYPE_IUNKNOWN;
                break;

                case  DBTYPE_WSTR:
                        prgBinding[dwIndex].pObject                =  NULL;
                        prgBinding[dwIndex].wType                =  pDBColumnInfo[dwIndex  +  1].wType;
                        prgBinding[dwIndex].cbMaxLen        =  sizeof(WCHAR)*(pDBColumnInfo[dwIndex  +  1].ulColumnSize  +  1);        //  Extra  buffer  for  null  terminator  
                        break;

                default:
                        prgBinding[dwIndex].pObject                =  NULL;
                        prgBinding[dwIndex].wType                =  pDBColumnInfo[dwIndex  +  1].wType;
                        prgBinding[dwIndex].cbMaxLen        =  pDBColumnInfo[dwIndex  +  1].ulColumnSize;  
                        break;
                }

                //  Calculate  new  offset
                //  
                dwOffset  =  prgBinding[dwIndex].obValue  +  prgBinding[dwIndex].cbMaxLen;

                //  Properly  align  the  offset
                //
                dwOffset  =  ROUND_UP(dwOffset,  COLUMN_ALIGNVAL);
        }

        //  Get  IAccessor  interface
        //
        hr  =  pIRowset->QueryInterface(IID_IAccessor,  (void**)&pIAccessor);
        if(FAILED(hr))
        {
                return(  FALSE  );
        }

        //  Create  accessor.
        //
        hr  =  pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA,  
                                                                        dwBindingSize,  
                                                                        prgBinding,
                                                                        0,
                                                                        &hAccessor,
                                                                        NULL);
        if(FAILED(hr))
        {
                return(  FALSE  );
        }

        //  Retrive  a  row
        //
        hr  =  pIRowset->GetNextRows(DB_NULL_HCHAPTER,  0,  1,  &cRowsObtained,  &prghRows);


        //------------------------------------
        //値を取得して色々やる処理を適当に
        //------------------------------------


        //  Clear  Variants
        //
        VariantClear(&dbprop[0].vValue);

        //  Free  allocated  DBBinding  memory
        //
        if  (prgBinding)
        {
                CoTaskMemFree(prgBinding);
                prgBinding  =  NULL;
        }

        //  Free  allocated  column  info  memory
        //
        if  (pDBColumnInfo)
        {
                CoTaskMemFree(pDBColumnInfo);
                pDBColumnInfo  =  NULL;
        }
        
        //  Free  allocated  column  string  values  buffer
        //
        if  (pStringsBuffer)
        {
                CoTaskMemFree(pStringsBuffer);
                pStringsBuffer  =  NULL;
        }

        //  Free  data  record  buffer
        //
        if  (pData)
        {
                CoTaskMemFree(pData);
                pData  =  NULL;
        }

        //  Release  interfaces
        //

        if(pICmdText)
        {
                pICmdText->Release();
        }

        if(pIDBCrtCmd)
        {
                pIDBCrtCmd->Release();
        }

        if(pICmdProps)
        {
                pICmdProps->Release();
        }

        if(pIRowsetPos)
        {
                pIRowsetPos->Release();
        }

        if(pIAccessor)
        {
                pIAccessor->ReleaseAccessor(hAccessor,  NULL);  
                pIAccessor->Release();
        }

        if  (pIColumnsInfo)
        {
                pIColumnsInfo->Release();
        }

        if(pIRowset)
        {
                pIRowset->Release();
        }

        if(pIDBProperties)
        {
                pIDBProperties->Release();
        }

        if(m_pIDBCreateSession)
        {
                m_pIDBCreateSession->Release();
        }

        if(pIDBInitialize)
        {
                pIDBInitialize->Release();
        }
スポンサーリンク
 
このエントリーをはてなブックマークに追加 

category:● VC++  thema:システム開発 - genre:コンピュータ  Posted by ササキマコト