📄 axrecordset.cpp
字号:
if FAILED( hr )
ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Move"), hr);
if ( !IsBOF() && !IsEOF() )
DoFieldExchange(FALSE);
}
// Method: MoveFirst
// Desc: Sets the record pointer to the first record in the recordset.
//
// Args: none
//
// Return: void
//
void CAxRecordset::MoveFirst()
{
VALID_ADO_OBJECT(m_piRecordset);
if ( _IsEmpty() )
return;
HRESULT hr = m_piRecordset->MoveFirst();
if FAILED( hr )
ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::MoveFirst"), hr);
DoFieldExchange(FALSE);
}
// Method: MoveLast
// Desc: Sets the record pointer to the last record in the recordset.
//
// Args: none
//
// Return: void
//
void CAxRecordset::MoveLast()
{
VALID_ADO_OBJECT(m_piRecordset);
if ( _IsEmpty() )
return;
HRESULT hr = m_piRecordset->MoveLast();
if FAILED( hr )
ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::MoveLast"), hr);
DoFieldExchange(FALSE);
}
// Method: MoveNext
// Desc: Sets the record pointer to the next record in the recordset.
// If the record pointer is on the last record before a call to
// MoveNext, the record pointer is moved beyond the last record
// and the EOF property is set to true.
//
// Args: none
//
// Return: void
//
void CAxRecordset::MoveNext()
{
VALID_ADO_OBJECT(m_piRecordset);
// if ( _IsEmpty() || IsEOF() )
// if ( IsEOF() )
// return;
HRESULT hr = m_piRecordset->MoveNext();
if FAILED( hr )
ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::MoveNext"), hr);
if ( !IsEOF() )
DoFieldExchange(FALSE);
}
// Method: MovePrevious
// Desc: Sets the record pointer to the previous record in the recordset.
// If the record pointer is on the first record before a call to
// MovePrevious, the record pointer is moved to a position before
// the first record and the BOF property is set to true.
//
// Args: none
//
// Return: void
//
void CAxRecordset::MovePrevious()
{
VALID_ADO_OBJECT(m_piRecordset);
// if ( _IsEmpty() || IsBOF() )
// return;
HRESULT hr = m_piRecordset->MovePrevious();
if FAILED( hr )
ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::MovePrevious"), hr);
if ( !IsBOF() )
DoFieldExchange(FALSE);
}
// Method: NextRecordset
// Desc: Not supported in this version of AxLib
//
void CAxRecordset::NextRecordset()
{
}
// Method: Open
// Desc: The first version of the Open method accepts a CAxCommand object
// whereby a stored procedure is used to return recordset results.
// A derived CAxRecordset object must exist and be initialized before
// calling the Open method. If the method fails, a CAxException is
// thrown.
//
// Args:
// pCmd: Reference to a CAxCommand object.
// cType: Cursor type to use, default is adOpenForwardOnly
// cLocat: Cursor location, default is adUseClient
// lType: Lock type to use, default is adLockOptimistic
// nOptions: Command options, default is adCmdUnspecified
//
// Return: void
//
void CAxRecordset::Open(CAxCommand* pCmd,
CursorTypeEnum eCursorType,
CursorLocationEnum eCursorLocation,
LockTypeEnum eLockType,
long nOptions)
{
if ( m_piRecordset == NULL )
{
HRESULT hr = Create();
if FAILED ( hr )
ThrowAxException(AXLIB_ERROR_INIT, _T("CAxRecordset::Open"), hr);
}
VALID_ADO_OBJECT(m_piRecordset);
VARIANT vNull, vCmd;
HRESULT hr = S_OK;
vNull.vt = VT_ERROR;
vNull.scode = DISP_E_PARAMNOTFOUND;
vCmd.vt = VT_DISPATCH;
vCmd.pdispVal = pCmd->m_piCommand;
//Capture references to controlling objects
m_pConnection = pCmd->ActiveConnection();
m_pCommand = pCmd;
m_piConnection = m_pConnection->_GetActiveConnection();
//Create command object's parameters (one time only) and Update
//Note: v1.2.0 now calls the _CreateParameters method from within the
//CAxCommand::Create method
m_pCommand->_UpdateParameters();
CursorTypeEnum ct = (m_eCursorType == -2) ? eCursorType : m_eCursorType;
LockTypeEnum lt = (m_eLockType == -2) ? eLockType : m_eLockType;
CursorLocation(eCursorLocation);
hr = m_piRecordset->Open(vCmd, vNull, ct, lt, nOptions);
if FAILED( hr )
ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Open"), hr);
hr = m_piRecordset->get_Fields(&m_pFields);
if FAILED( hr )
ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Open"), hr);
DoFieldExchange(FALSE);
}
// Method: Open
// Desc: The second version of the Open method uses a source argument in
// place of a CAxCommand object. A typical source statement would
// be "SELECT * From Accounts ORDER By AccountID"
//
// v1.1.1: Added call to CursorLocation
//
// Args:
// szSource: Valid SQL Source statement
// pConnection: Reference to an existing CAxConnection object
// cType: Cursor type to use, default is adOpenForwardOnly
// cLocat: Cursor location, default is adUseClient
// lType: Lock type to use, default is adLockOptimistic
// nOptions: Command options, default is adCmdUnspecified
//
// Return: void
//
void CAxRecordset::Open(LPCTSTR szSource, CAxConnection *pConnection,
CursorTypeEnum eCursorType,
CursorLocationEnum eCursorLocation,
LockTypeEnum eLockType,
long nOptions)
{
if ( m_piRecordset == NULL )
{
HRESULT hr = Create();
if FAILED ( hr )
ThrowAxException(AXLIB_ERROR_INIT, _T("CAxRecordset::Open"), hr);
}
VALID_ADO_OBJECT(m_piRecordset);
HRESULT hr = S_OK;
if ( szSource != NULL )
m_strSourceString = szSource;
if ( pConnection != NULL )
m_piConnection = pConnection->_GetActiveConnection();
ASSERT( !m_strSourceString.IsEmpty() );
ASSERT( m_piConnection != NULL );
hr = m_piRecordset->put_Source(m_strSourceString.AllocSysString());
if FAILED( hr )
{
m_piRecordset->Release();
m_piRecordset = NULL;
ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Open"), hr);
}
hr = m_piRecordset->putref_ActiveConnection((ADOConnection*)m_piConnection);
if FAILED( hr )
{
m_piRecordset->Release();
m_piRecordset = NULL;
ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Open"), hr);
}
CursorTypeEnum ct = (m_eCursorType == -2) ? eCursorType : m_eCursorType;
LockTypeEnum lt = (m_eLockType == -2) ? eLockType : m_eLockType;
CursorLocation(eCursorLocation);
hr = m_piRecordset->Open(_variant_t(szSource), _variant_t(m_piConnection),
ct, lt, nOptions);
if FAILED( hr )
{
m_piRecordset->Release();
m_piRecordset = NULL;
ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Open"), hr);
}
hr = m_piRecordset->get_Fields(&m_pFields);
if FAILED( hr )
{
m_piRecordset->Release();
m_piRecordset = NULL;
ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Open"), hr);
}
DoFieldExchange(FALSE);
}
// Method: Requery
// Desc: The Requery method re-executes the command that was used to
// originally open the recordset. If the recordset was opened
// using a command object (i.e. CAxCommand), Requery is used to
// update the recordset after changing one or more parameter
// values of the command.
//
// Args:
// eExecuteOption: Execute option, default is adOptionUnspecified
// adOptionUnspecified = -1,
// adAsyncExecute = 0x10,
// adAsyncFetch = 0x20,
// adAsyncFetchNonBlocking = 0x40,
// adExecuteNoRecords = 0x80
//
// Return: void
//
void CAxRecordset::Requery(ExecuteOptionEnum eExecuteOption)
{
VALID_ADO_OBJECT(m_piRecordset);
if ( m_pCommand )
m_pCommand->_UpdateParameters();
HRESULT hr = m_piRecordset->Requery(eExecuteOption);
if FAILED( hr )
ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Requery"), hr);
DoFieldExchange(FALSE);
}
// Method: Resync
// Desc: The Resync method is used to resychronize the the records
// with the data provider. Resync is typically used when the
// recordset was opened using a Static or Forward only cursor
// and the client application needs to check is any other users
// have made changes.
//
// Args:
// eAffectRecords: Affect records options, default is adAffectAll
// adAffectCurrent = 1,
// adAffectGroup = 2,
// adAffectAll = 3,
// adAffectAllChapters = 4
//
// eResyncValues: Resync option, default is adResyncAllValues
// adResyncUnderlyingValues = 1,
// adResyncAllValues = 2
//
// Return: void
//
void CAxRecordset::Resync(AffectEnum eAffectRecords,
ResyncEnum eResyncValues)
{
VALID_ADO_OBJECT(m_piRecordset);
HRESULT hr = m_piRecordset->Resync(eAffectRecords, eResyncValues);
if FAILED( hr )
ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Resync"), hr);
}
// Method: Save
// Desc: Saves the recordset to a file. The AxLib version differs
// from ADO in that a file name is used as the destination
// argument rather than a variant. Therefore, only saving
// to a file is supported.
//
// Args:
// lpszFileName: File name to save recordset data to.
// ePersistFormat: Persist format option, default is adPersistADTG
// adPersistADTG = 0,
// adPersistXML = 1
//
// Return: void
//
void CAxRecordset::Save(LPCTSTR lpszFileName,
PersistFormatEnum ePersistFormat)
{
#if _MSC_VER == 1200
_bstr_t bstrFileName(lpszFileName);
HRESULT hr = m_piRecordset->Save(bstrFileName, ePersistFormat);
#else
#ifdef _UNICODE
_variant_t varFile(lpszFileName);
#else
_variant_t varFile(M2W(lpszFileName));
#endif
HRESULT hr = m_piRecordset->Save(varFile, ePersistFormat);
#endif
if FAILED( hr )
ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Save"), hr);
}
// Method: Supports
// Desc: Determines if the data provider supports a certain
// functionality.
//
// Args:
// eCursorOption: Cursor option to validate
// adHoldRecords = 0x100,
// adMovePrevious = 0x200,
// adAddNew = 0x1000400,
// adDelete = 0x1000800,
// adUpdate = 0x1008000,
// adBookmark = 0x2000,
// adApproxPosition = 0x4000,
// adUpdateBatch = 0x10000,
// adResync = 0x20000,
// adNotify = 0x40000,
// adFind = 0x80000
//
// Return: If the data provider supports the indicated option true,
// otherwise false.
//
bool CAxRecordset::Supports(CursorOptionEnum eCursorOption)
{
VALID_ADO_OBJECT(m_piRecordset);
VARIANT_BOOL vSucceeded;
HRESULT hr = m_piRecordset->Supports(eCursorOption, &vSucceeded);
if FAILED( hr )
ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Supports"), hr);
return ( vSucceeded != 0 );
}
// Method: Update
// Desc: Posts changes made to the recordset back to the server. The
// Update method calls the virtual function DoFieldExchange in
// the derived CAxRecordset object to write individual field
// data back to the data provider.
//
// Args: none
//
// Return: void
//
void CAxRecordset::Update()
{
VALID_ADO_OBJECT(m_piRecordset);
_variant_t vNames(DISP_E_PARAMNOTFOUND, VT_ERROR);
_variant_t vValues(DISP_E_PARAMNOTFOUND, VT_ERROR);
DoFieldExchange(TRUE);
//Use 'adResyncUnderlyingValues' on Resync to avoid errors on compound
//Recordsets (i.e. INNER/OUTER Joins of tables)
HRESULT hr = S_OK;
if ( Supports(adResync) )
{
if FAILED( m_piRecordset->Resync(adAffectCurrent, adResyncUnderlyingValues) )
{
hr = m_piRecordset->Resync(adAffectCurrent, adResyncAllValues);
if FAILED( hr )
ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Update"), hr);
}
}
if ( Supports(adUpdate) )
{
hr = m_piRecordset->Update(vNames, vValues);
if FAILED( hr )
ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Update"), hr);
}
}
///////////////////////////////////////////////////////////////
// Properties
// Method: AbsolutePage
// Desc: Sets/Returns the current page in the record set.
// Call method with no argument to return current setting.
//
// Args: nPage
// Page to set active. Page value must be between
// 1 and the total page count. Page count is
// returned by the PageCount() method.
//
// Return: Current page or PositionEnum value.
// adPosUnknown = -1,
// adPosBOF = -2,
// adPosEOF = -3
//
long CAxRecordset::AbsolutePage(long nPageNum)
{
VALID_ADO_OBJECT(m_piRecordset);
HRESULT hr = S_OK;
if ( nPageNum < 0 || nPageNum > PageCount() )
ThrowAxException(AXLIB_ERROR_INVALID_POS, _T("CAxRecordset::AbsolutePage"));
if ( nPageNum > 0 )
{
hr = m_piRecordset->put_AbsolutePage((PositionEnum)nPageNum);
if FAILED( hr )
ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::AbsolutePage"), hr);
}
PositionEnum pageNum;
hr = m_piRecordset->get_AbsolutePage(&pageNum);
if FAILED( hr )
ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::AbsolutePage"), hr);
return ((PositionEnum)pageNum);
}
// Method: AbsolutePage
// Desc: Sets/Returns the current record position.
// Call method with no argument to return current setting.
//
// Args: nPosition
// Position to set the current record. Position is 1' based.
// Position is between 1 and the record count. Record count
// is returned by the RecordCount() method.
//
// Return: Current record position (ordinal value) or PositionEnum value.
// adPosUnknown = -1,
// adPosBOF = -2,
// adPosEOF = -3
//
long CAxRecordset::AbsolutePosition(long nPosition)
{
VALID_ADO_OBJECT(m_piRecordset);
HRESULT hr = S_OK;
_variant_t* pvtBookmark = NULL;
if ( _IsEmpty() )
return ( 0L );
if ( nPosition < 0 || nPosition > RecordCount() )
ThrowAxException(AXLIB_ERROR_INVALID_POS, _T("CAxRecordset::AbsolutePosition"));
if ( nPosition > 0 )
{
pvtBookmark = Bookmark();
hr = m_piRecordset->put_AbsolutePosition(PositionEnum(nPosition));
if FAILED( hr )
{
if ( pvtBookmark->vt != VT_EMPTY )
m_piRecordset->put_Bookmark(*pvtBookmark);
ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::AbsolutePosition"), hr);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -