2010.
11.
22
21:48:33
「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();
}
既存ソースが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();
}