Visual C++中使用OLE DB读写SQL Server简明指南
作者: 来源: 添加时间:2006-5-24 13:32:54以上就是写数据库的全部代码了,是不是很简单呢?下面再来读的。
// 先用与上面代码中一样的步骤获取pICommand,pICommandText。此处省略
HRESULT hResult = pICommandText->SetCommandText( DBGUID_DBSQL, ( LPCOLESTR )_T("SELECT Volume FROM 2005_1 WHERE ID = @@IDENTITY") ); //取我们刚刚添加的那一条记录
if( FAILED( hResult ) )
{
return;
}
LONG lAffected;
EAutoReleasePtr pIRowset;
hResult = pICommand->Execute( NULL, IID_IRowset, NULL, &lAffected, ( IUnknown** )&pIRowset );
if( FAILED( hResult ) )
{
return;
}
EAutoReleasePtr pIAccessor;
hResult = pIRowset->QueryInterface( IID_IAccessor, ( void** )&pIAccessor );
if( FAILED( hResult ) )
{
return;
}
// 一个根据表中各字段的数值类型而定义的结构,用于存储返回的各字段的值
struct CLoadLastFromDB
{
DBSTATUS dwdsVolume;
DWORD dwLenVolume;
float fVolume;
};
// 此处我们只查询了一个字段。如果要查询多个字段,CLoadLastFromDB中要添加相应的字段定义,下面的dbBinding也要相应扩充。dbBinding[].iOrdinal要分别指向各个字段,dbBinding[].wType要根据字段类型赋合适的值。
DBBINDING dbBinding[1];
dbBinding[0].iOrdinal = 1; // Volume 字段的位置,从 1 开始
dbBinding[0].obValue = offsetof( CLoadLastFromDB, fVolume );
dbBinding[0].obLength = offsetof( CLoadLastFromDB, dwLenVolume );
dbBinding[0].obStatus = offsetof( CLoadLastFromDB, dwdsVolume );
dbBinding[0].pTypeInfo = NULL;
dbBinding[0].pObject = NULL;
dbBinding[0].pBindExt = NULL;
dbBinding[0].dwPart = DBPART_VALUE | DBPART_STATUS | DBPART_LENGTH;
dbBinding[0].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
dbBinding[0].eParamIO = DBPARAMIO_NOTPARAM;
dbBinding[0].cbMaxLen = 0;
dbBinding[0].dwFlags = 0;
dbBinding[0].wType = DBTYPE_R4; // float就是DBTYPE_R4,int就是DBTYPE_I4。参见MSDN
dbBinding[0].bPrecision = 0;
dbBinding[0].bScale = 0;
HACCESSOR hAccessor = DB_NULL_HACCESSOR;
DBBINDSTATUS dbs[1];
hResult = pIAccessor->CreateAccessor( DBACCESSOR_ROWDATA, 1, dbBinding, sizeof( CLoadLastDataFromDB ), &hAccessor, dbs );
if( FAILED( hResult ) )
{
return;
}
ASSERT( dbs[0] == DBBINDSTATUS_OK );
ULONG uRowsObtained = 0;
HROW hRows[1]; // 这里我们只查询了最新的那一条记录
HROW* phRows = hRows;
CLoadLastFromDB rmd;
hResult = pIRowset->GetNextRows( NULL, 0, 1, &uRowsObtained, &phRows );
if( SUCCEEDED( hResult ) && uRowsObtained != 0U )
{
hResult = pIRowset->GetData( phRows[0], hAccessor, &rmd );
if( FAILED( hResult ) )
{
ASSERT( FALSE );
}
ASSERT( rmd.dwdsVolume == DBSTATUS_S_OK );
// rmd.fVolume 就是我们要取的值
}
pIRowset->ReleaseRows( uRowsObtained, phRows, NULL, NULL, NULL );
pIAccessor->ReleaseAccessor( hAccessor, NULL );
pIAccessor.Release( );
pIRowset.Release( );
读操作也完成了,是不是仍然很简单呢?下面我们再来看看最麻烦的二进制数据(text、ntext、image等)的读写。要实现BLOB数据的读写,我们需要一个辅助的类,定义如下:
class CSequentialStream : public ISequentialStream // BLOB 数据访问类
{
public:
CSequentialStream( );
virtual ~CSequentialStream( );
virtual BOOL Seek( ULONG uPosition );
virtual BOOL Clear( );
virtual ULONG GetLength( ) { return m_uBufferUsed; };
virtual operator void* const( ) { return m_pBuffer; };
STDMETHODIMP_( ULONG ) AddRef( ) { return ++ m_uRefCount; };
STDMETHODIMP_( ULONG ) Release( ) { ASSERT( m_uRefCount != 0U ); -- m_uRefCount; if( m_uRefCount == 0U ) { delete this; } return m_uRefCount; };
STDMETHODIMP QueryInterface( REFIID riid, LPVOID* ppv );
STDMETHODIMP Read( void __RPC_FAR* pv, ULONG cb, ULONG __RPC_FAR* pcbRead );
STDMETHODIMP Write( const void __RPC_FAR* pv, ULONG cb, ULONG __RPC_FAR* pcbWritten );
void ResetPosition( ) { m_uPosition = 0U; };
HRESULT PreAllocBuffer( ULONG uSize );
private:
ULONG m_uRefCount; // reference count
void* m_pBuffer; // buffer
ULONG m_uBufferUsed; // buffer used
ULONG m_uBufferSize; // buffer size
ULONG m_uPosition; // current index position in the buffer
};
第 2 页,共 2 页 [1] [2]
站内搜索