microsoft activex data objects 2.5 (ado) - documentation.help · object represents a folder of...

3516
ActiveX Data Objects 2.5 Start Page

Upload: others

Post on 14-Sep-2019

106 views

Category:

Documents


1 download

TRANSCRIPT

  • ActiveXDataObjects2.5StartPage

  • ADOVersion2.5Purpose

    MicrosoftActiveXDataObjects(ADO)enableyourclientapplicationstoaccessandmanipulatedatafromadatabaseserverthroughanOLEDBprovider.Itsprimarybenefitsareeaseofuse,highspeed,lowmemoryoverhead,andasmalldiskfootprint.ADOsupportskeyfeaturesforbuildingclient/serverandWeb-basedapplications.

  • RDS

    ADOalsofeaturesRemoteDataService(RDS),bywhichyoucanmovedatafromaservertoaclientapplicationorWebpage,manipulatethedataontheclient,andreturnupdatestotheserverinasingleroundtrip.

  • ADOMD

    MicrosoftActiveXDataObjects(Multidimensional)(ADOMD)provideseasyaccesstomultidimensionaldatafromlanguagessuchasMicrosoftVisualBasic,MicrosoftVisualC++,andMicrosoftVisualJ++.ADOMDextendsMicrosoftActiveXDataObjects(ADO)toincludeobjectsspecifictomultidimensionaldata,suchastheCubeDefandCellsetobjects.WithADOMDyoucanbrowsemultidimensionalschema,queryacube,andretrievetheresults.

    LikeADO,ADOMDusesanunderlyingOLEDBprovidertogainaccesstodata.ToworkwithADOMD,theprovidermustbeamultidimensionaldataprovider(MDP)asdefinedbytheOLEDBforOLAPspecification.MDPspresentdatainmultidimensionalviewsasopposedtotabulardataproviders(TDPs)thatpresentdataintabularviews.RefertothedocumentationforyourOLAPOLEDBproviderformoredetailedinformationonthespecificsyntaxandbehaviorssupportedbyyourprovider.

  • ADOX

    MicrosoftActiveXDataObjectsExtensionsforDataDefinitionLanguageandSecurity(ADOX)isanextensiontotheADOobjectsandprogrammingmodel.ADOXincludesobjectsforschemacreationandmodification,aswellassecurity.Becauseitisanobject-basedapproachtoschemamanipulation,youcanwritecodethatwillworkagainstvariousdatasourcesregardlessofdifferencesintheirnativesyntaxes.

    ADOXisacompanionlibrarytothecoreADOobjects.Itexposesadditionalobjectsforcreating,modifying,anddeletingschemaobjects,suchastablesandprocedures.Italsoincludessecurityobjectstomaintainusersandgroupsandtograntandrevokepermissionsonobjects.

  • MainComponentsofADO2.5

    Programmer'sGuide

    AnintroductiontousingADO,RDS,ADOMD,andADOX.

    Programmer'sReference

    ThissectionoftheADOdocumentationcontainstopicsforeachADO,RDS,ADOMD,andADOXobject,collection,property,dynamicproperty,method,event,andenumeration.

  • Feedback

    YoucansendfeedbackaboutADOdocumentationorsamplesdirectlytotheADOdocumentationteam.

    SeeAlso

    ADOTechnicalArticlesOLEDB

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

    mailto:[email protected]:[email protected]

  • ADO2.5Programmer'sGuide

  • ADOProgrammer'sGuideForanintroductiontotheMicrosoftActiveXDataObjects(ADO)Programmer'sGuide,seethefollowingtopics:

    IntroductionWhat'sNewinADOPrerequisitesTheADOFamilyofLibrariesTheRoleofADOinMicrosoftDataAccessADOTaskTableADOTechnologyTable

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5Programmer'sGuide

  • IntroductionTheADOProgrammer'sGuidehasbeencreatedtoassistdeveloperswhoarenewtoADObygivingthemathoroughintroductiontothetechnology.ThisguidedescribesthelibrariesoftheADOfamilyandusessamplecodeinavarietyoflanguagestoexplainhowtousethelibraries,bestpracticesforusingthelibraries,andtipsandtricksformaximizingtheperformanceofyourADOapplication.

    TheADOProgrammer'sGuidecontainsthefollowingsectionsandchapters:

    SectionI:ActiveXDataObjects(ADO)Chapter1:ADOFundamentalsChapter2:GettingDataChapter3:ExaminingDataChapter4:EditingDataChapter5:UpdatingandPersistingDataChapter6:ErrorHandlingChapter7:HandlingADOEventsChapter8:UnderstandingCursorsandLocksChapter9:DataShapingChapter10:RecordsandStreams

    SectionII:RemoteDataService(RDS)Chapter11:RDSFundamentalsChapter12:RDSTutorialChapter13:RDSUsageandSecurity

    SectionIII:ActiveXDataObjects(Multidimensional)(ADOMD)Chapter14:ADOMDFundamentals

    SectionIV:ActiveXDataObjectsExtensionsforDataDefinitionLanguageandSecurity(ADOX)

    Chapter15:ADOXFundamentalsSectionV:Appendixes

    AppendixA:ProvidersAppendixB:ADOErrorsAppendixC:ProgrammingwithADOAppendixD:ADOSamples

  • ADOGlossary

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5Programmer'sGuide

  • What'sNewinADOThefollowingnewfeaturesandenhanceddocumentationareincludedintheADO2.5release.ThislistcoversADO,ADOMD,andADOX.

    NewFeatures

    RecordsandStreams

    ThisreleaseofADOintroducestheRecordobject,whichcanrepresentandmanagethingslikedirectoriesandfilesinafilesystem,andfoldersandmessagesinane-mailsystem.ARecordcanalsorepresentarowinaRecordset,althoughRecordandRecordsetobjectshavedifferentmethodsandproperties.

    ThenewStreamobjectprovidesthemeanstoread,write,andmanagethebinarystreamofbytesortextthatcompriseafileormessagestream.

    URLUsage

    ThisreleasealsointroducestheuseofUniformResourceLocators(URLs),asanalternativetoconnectionstringsandcommandtext,tonamedatastoreobjects.URLsmaybeusedwiththeexistingConnectionandRecordsetobjects,aswellaswiththenewRecordandStreamobjects.

    Withthisrelease,ADOsupportsOLEDBprovidersthatrecognizetheirownURLschemes.Forexample,theOLEDBProviderforInternetPublishing,whichaccessestheWindows2000filesystem,recognizestheexistingHTTPscheme.

    SpecialFieldsforDocumentSourceProviders

    Aspecialclassofproviders,calleddocumentsourceproviders,managefoldersanddocuments.WhenaRecordobjectrepresentsadocument,oraRecordsetobjectrepresentsafolderofdocuments,thedocumentsourceproviderpopulatesthoseobjectswithauniquesetoffieldsthatdescribecharacteristicsofthedocument.ThesefieldsconstitutearesourceRecordorRecordset.

  • NewReferenceTopics

    Thefollowingnewpropertiesareincludedinthisrelease.

    Property Description

    Charset IndicatesthecharactersetintowhichthecontentsofatextStreamobjectshouldbetranslated.

    EOS Indicateswhetherthecurrentpositionisattheendofthestream.

    LineSeparator IndicatesthebinarycharactertobeusedasthelineseparatorintextStreamobjects.

    Mode IndicatestheavailablepermissionsformodifyingdatainaConnection,Record,orStreamobject.

    ParentURL IndicatesanabsoluteURLstringthatpointstotheparentRecordofthecurrentRecordobject.

    Position IndicatesthecurrentpositionwithinaStreamobject.RecordType IndicatesthetypeofRecordobject.Size Indicatesthesizeofthestreaminnumberofbytes.

    Source IndicatestheentityrepresentedbytheRecordobject.

    State

    Indicatesforallapplicableobjectswhetherthestateoftheobjectisopenorclosed.

    Indicatesforallapplicableobjectsexecutinganasynchronousmethod,whetherthecurrentstateoftheobjectisconnecting,executing,orretrieving.

    Type IndicatesthetypeofdatacontainedintheStreamobject(binaryortext).

    Thefollowingnewmethodsareincludedinthisrelease.

    Method Description

    CopyRecord Copiesafileordirectory,anditscontents,toanotherlocation.Copiesthespecifiednumberofcharactersorbytes

  • CopyTo (dependingonType)intheStreamobjecttoanotherStreamobject.

    DeleteRecord Deletesafileordirectory,andallitssubdirectories.

    FlushForcesthecontentsoftheStreamobjectremainingintheADObuffertotheunderlyingobjectwithwhichtheStreamobjectisassociated.

    GetChildrenReturnsaRecordsetwhoserowsrepresentthefilesandsubdirectoriesinthedirectoryrepresentedbythisRecord.

    LoadFromFile LoadsthecontentsofanexistingfileintoaStreamobject.

    MoveRecord Movesafile,oradirectoryanditscontents,toanotherlocation.

    Open OpensanexistingRecordobject,orcreatesanewfileordirectory.

    Open OpensaStreamobjecttomanipulatestreamsofbinaryortextdata.

    Read ReadsaspecifiednumberofbytesfromabinaryStreamobject.

    ReadText ReadsspecifiednumberofcharactersfromatextStreamobject.SaveToFile SavesthebinarycontentsofaStreamtoafile.SetEOS Setsthepositionthatistheendofthestream.

    SkipLine SkipsoneentirelinewhenreadingatextStreamobject.Write WritesbinarydatatoaStreamobject.WriteText WritesaspecifiedtextstringtoaStreamobject.

    NewandEnhancedDocumentation

    CodeExampleTopics

    TheexampleshavebeenexpandedtocontaincodeexampleswritteninMicrosoftVisualC++®andMicrosoftVisualJ++®.Youcancopyandpastethesecodeexamplesintoyoureditor.

  • ProviderTopics

    AnewtopicisincludedthatexplainshowtouseADOwiththeOLEDBProviderforInternetPublishing.

    ProgrammingwithADO

    ThisnewsectioncontainstipsandtricksforusingADOwithvariousprogramminglanguages.ItcontainstheexistingsyntaxindexesfortheVisualC++ExtensionsforADOandADO/WFC,aswellasnewinformationspecifictodevelopersusingMicrosoftVisualBasic®,MicrosoftVisualBasic®ScriptingEdition,MicrosoftJScript®,MicrosoftVisualC++,orMicrosoftVisualJ++.

    ©1998-2002MicrosoftCorporation.Allrightsreserved.

  • ADO2.5Programmer'sGuide

  • PrerequisitesTheADOProgrammer'sGuidewillproveusefultodeveloperswithawidevarietyofbackgrounds.Ataminimum,readersshouldhaveanintermediatelevelofexperienceindevelopingapplicationswithMicrosoftVisualBasic,becausemostoftheexamplesintheguidearewritteninthislanguage.OtherexamplesarewritteninMicrosoftVisualC++;Java;VisualBasic,ScriptingEdition(VBScript);andMicrosoftJScript.

    BecauseADOisusedforaccessingdatafromavarietyofsources,readersmightalsoneedsomeunderstandingoffundamentalrelationaldatabasemanagementsystemconcepts,onlineanalyticalprocessing(OLAP)concepts,andbasicfamiliaritywiththeInternetandInternetprotocols.

    ADOisapartoftheMicrosoftDataAccess(UDA)strategy.(FormoreinformationaboutUDA,see"TheRoleofADOinMicrosoftDataAccess,"laterinthischapter.)Assuch,itinteroperateswiththeOLEDBtechnology.OLEDBisbasedontheMicrosoftComponentObjectModel(COM).Therefore,familiaritywithCOMcanalsobeusefulforunderstandingsomeofthemoreadvancedconceptsinADO.

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5Programmer'sGuide

  • TheADOFamilyofLibrariesThreemajorlibrariesmakeuptheADOfamily:ADO(includingRDS),ADOMD,andADOX.

  • ADO

    ADOenablesyourclientapplicationstoaccessandmanipulatedatafromadatabaseserverthroughanOLEDBprovider.TheprimarybenefitsofADOareeaseofuse,highspeed,lowmemoryoverhead,andasmalldiskfootprint.ADOsupportskeyfeaturesforbuildingclient/serverandWeb-basedapplications.

    ADOalsofeaturesRemoteDataService(RDS),bywhichyoucanmovedatafromaservertoaclientapplicationorWebpage,manipulatethedataontheclient,andreturnupdatestotheserverinasingleroundtrip.

  • ADOMD

    MicrosoftActiveXDataObjects(Multidimensional)(ADOMD)provideseasyaccesstomultidimensionaldatafromlanguagessuchasMicrosoftVisualBasic,MicrosoftVisualC++,andMicrosoftVisualJ++.ADOMDextendsADOtoincludeobjectsspecifictomultidimensionaldata,suchastheCubeDefandCellsetobjects.WithADOMDyoucanbrowsemultidimensionalschema,queryacube,andretrievetheresults.

    LikeADO,ADOMDusesanunderlyingOLEDBprovidertogainaccesstodata.ToworkwithADOMD,theprovidermustbeamultidimensionaldataprovider(MDP)asdefinedbytheOLEDBforOLAPspecification.MDPspresentdatainmultidimensionalviewsasopposedtotabulardataproviders(TDPs)thatpresentdataintabularviews.RefertothedocumentationforyourOLEDBforOLAPproviderformoredetailedinformationaboutthespecificsyntaxandbehaviorssupportedbyyourprovider.

  • ADOX

    MicrosoftActiveXDataObjectsExtensionsforDataDefinitionLanguageandSecurity(ADOX)isanextensiontotheADOobjectsandprogrammingmodel.ADOXincludesobjectsforschemacreationandmodificationaswellassecurity.Becauseitisanobject-basedapproachtoschemamanipulation,youcanwritecodethatwillworkagainstvariousdatasourcesregardlessofdifferencesintheirnativesyntaxes.

    ADOXisacompanionlibrarytothecoreADOobjects.Itexposesadditionalobjectsforcreating,modifying,anddeletingschemaobjects,suchastablesandprocedures.Italsoincludessecurityobjectstomaintainusersandgroups,andtograntandrevokepermissionsonobjects.

    SeeAlso

    SectionI:ActiveXDataObjects(ADO)|SectionII:RemoteDataService(RDS)|SectionIII:ADO(Multidimensional)(ADOMD)|SectionIV:ADOExtensionsforDataDefinitionLanguageandSecurity(ADOX)

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5Programmer'sGuide

  • TheRoleofADOinMicrosoftDataAccessTheMicrosoftDataAccessComponents(MDAC)providedataaccessthatisindependentofdatastores,tools,andlanguages.Itprovidesahigh-level,easy-to-useinterface,andalow-level,high-performanceinterfacetopracticallyanydatastoreavailable.Youcanusethisflexibilitytointegratediversedatastoresanduseyourchoiceoftools,applications,andplatformservicestocreatetherightsolutionsforyourneeds.Thesetechnologiesprovidethebasicframeworkforgeneral-purposedataaccessinMicrosoftWindowsoperatingsystems.

    TherearethreeprimarytechnologiesinMDAC.ActiveXDataObjects(ADO)isahigh-level,easy-to-useinterfacetoOLEDB.OLEDBisalow-level,high-performanceinterfacetoavarietyofdatastores.ADOandOLEDBbothcanworkwithrelational(tabular)andnonrelational(hierarchicalorstream)data.Finally,OpenDatabaseConnectivity(ODBC)isanotherlow-level,high-performanceinterfacethatisdesignedspecificallyforrelationaldatastores.

    ADOprovidesalayerofabstractionbetweenyourclientormiddle-tierapplicationandthelow-levelOLEDBinterfaces.ADOusesasmallsetofAutomationobjectstoprovideasimpleandefficientinterfacetoOLEDB.ThisinterfacemakesADOtheperfectchoicefordevelopersinhigherlevellanguages,suchasVisualBasicandevenVBScript,whowanttoaccessdatawithouthavingtolearntheintricaciesofCOMandOLEDB.

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5Programmer'sGuide

  • ADOTaskTableThefollowingtablelistsprogrammingtaskscontainedintheADOProgrammer'sGuideandprovidesreferencesforeachtask.ThesereferencescanbetextualdescriptionsorcodeexamplesinwhichyoucanfindinformationabouttheADOfeaturethatperformsthetask.

    ADOTask ReferencesConnectingtoadataprovider MakingaConnection

    Executingcommandsorcallingstoredprocedures UsingtheCommandObject

    OpeningaRecordset TheRecordsetObjectOpenMethodDeterminingthesizeofaRecordset CountingRowsandTheLimitsofaRecordset

    Movingtoaspecificrecord NavigatingThroughtheData

    Accessingcolumnvalues TheFieldsCollectionSearchingfordata WorkingwithRecordsetsModifyingdataandchangingvalues EditingExistingRecords

    Addingnewdata AddingRecordsDeletingorremovingdata DeletingRecordsUsingtheDeleteMethodPostingchangestothedatasource UpdatingData

    Beginning,committing,androllingbacktransactions

    TransactionProcessing

    Savingrecordstoafile(XMLorbinary) PersistingData

    Handlingerrors ADOErrorsHandlingevents,asynchronousprogramming

    ADOEventHandlerSummary

  • Choosingcursorlocationandtype TypesofCursors

    Choosinglocktypes TypesofLocksReturningrelatedrecordsinaRecordset DataShapingSummary

    Accessingsemi-structureddata Chapter10:RecordsandStreams

    PublishingtoIIS UsingADOforInternetPublishing

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5Programmer'sGuide

  • ADOTechnologyTableThefollowingtableliststheMicrosoftproducts,tools,andtechnologiesdiscussedintheADOProgrammer'sGuide.Itprovideslinks,whereverpossible,torelevanttopicsintheguide.

    MicrosoftProductorTechnology References

    Access/Jet

    WorkingwithRecordsets

    Chapter15:ADOXFundamentals

    MicrosoftJetandReplicationObjects

    OLEDBProviderforMicrosoftJet

    ActiveDirectoryServiceInterfaces MicrosoftOLEDBProviderforMicrosoftActiveDirectoryService

    COM/DCOM

    Prerequisites

    MarkingBusinessObjectsasSafeforScripting

    RegisteringBusinessObjectsontheClientforUsewithDCOM

    SettingDCOMStreamMarshalingFormat

    EnablingaDLLtoRunonDCOM

    RunningBusinessObjectsinComponentServices

    FrontPage MicrosoftOLEDBProviderforInternetPublishing

    IndexingService MicrosoftOLEDBProviderforMicrosoftIndexingService

  • InternetExplorer InternetExplorerErrorCodes

    InternetInformationServices

    Chapter10:RecordsandStreams

    StreamsandPersistence

    UsingADOforInternetPublishing

    SolutionsforRemoteDataAccess

    ConfiguringVirtualServersonIIS

    SpecifyingThreadsPerProcessoronIIS

    SecuringRDSApplications

    "InternetServerError:AccessDenied"

    MicrosoftOLEDBProviderforInternetPublishing

    InternetInformationServicesErrorCodes

    JScript

    HandlingErrorsinOtherLanguages

    JScriptADOProgramming

    ADOCodeExamplesinMicrosoftJScript

    ODBC

    TheRoleofADOinMicrosoftDataAccess

    UsingtheConnectionObject

    UsingRDSwithODBCConnectionPooling

    MicrosoftOLEDBProviderforODBC

  • OLEDB

    TheRoleofADOinMicrosoftDataAccess

    OLEDBProviders

    AppendixA:Providers

    ProviderErrors

    Oracle MicrosoftOLEDBProviderforOracle

    SQLServer2000

    ControllingTransactions

    CallingaStoredProcedurewithaCommand

    CountingRows

    Forward-OnlyCursors

    CommandStreams

    EnsuringSufficientTempDBSpace

    MinimizingLogFileSpaceUsage

    MicrosoftOLEDBProviderforSQLServer

    TransactionServer RunningBusinessObjectsinComponentServices

    VBScript

    HandlingErrorsinOtherLanguages

    VisualBasicforApplicationsFunctions

    CommandStreams

    SolutionsforRemoteDataAccess

    RDSScenario

  • RDSTutorial(VBScript)

    VBScriptADOProgramming

    ADOCodeExamplesinMicrosoftVisualBasicScriptingEdition

    VisualBasic

    Errors

    ADOErrors

    ADOEventInstantiationByLanguage

    VisualBasicforApplicationsFunctions

    Chapter12:RDSTutorial

    UsingADOwithMicrosoftVisualBasic

    ADOCodeExamplesinMicrosoftVisualBasic

    VisualC++

    HandlingErrorsinOtherLanguages

    ADOEventInstantiationByLanguage

    UsingADOwithMicrosoftVisualC++

    ADOCodeExamplesinMicrosoftVisualC++

    VisualJ++

    HandlingErrorsinOtherLanguages

    ADOEventInstantiationByLanguage

    RDSTutorial(VisualJ++)

    UsingADOwithMicrosoftVisualJ++

  • ADOCodeExamplesinMicrosoftVisualJ++

    VisualStudio AppendixD:ADOSamples

    Windows2000

    SystemRequirementsfortheAddressBookApplication

    GrantingGuestPrivilegestoaWebServerComputer

    RegisteringaCustomBusinessObject

    SecuringRDSApplications

    ConfiguringRDSonWindows2000

    XML

    PersistingRecordsinXMLFormat

    Chapter10:RecordsandStreams

    CommandStreams

    RetrievingResultsetsintoStreams

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • SectionI:ActiveXDataObjects(ADO)Thissectioncontainsthefollowingchapters:

    Chapter1:ADOFundamentalsChapter2:GettingDataChapter3:ExaminingDataChapter4:EditingDataChapter5:UpdatingandPersistingDataChapter6:ErrorHandlingChapter7:HandlingADOEventsChapter8:UnderstandingCursorsandLocksChapter9:DataShapingChapter10:RecordsandStreams

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • Chapter1:ADOFundamentalsThischapterisanintroductiontotheADOlibrary.ItdiscusseswhatyoucandowithADO,reviewstheobjectsintheADOhierarchy,andpresentsasimpleADOapplicationthatusesmanyoftheADOobjectstoretrieve,edit,andupdatedatafromadatasource.Finally,thischaptercoverstwoissuesthatareimportanttounderstandforwritingADOapplications:OLEDBprovidersanderrors.

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • WhatYouCanDoWithADOADOisdesignedtoprovidedeveloperswithapowerful,logicalobjectmodelforprogrammaticallyaccessing,editing,andupdatingawidevarietyofdatasourcesthroughOLEDBsysteminterfaces.ThemostcommonusageofADOistoqueryatableortablesinarelationaldatabase,retrieveanddisplaytheresultsinanapplication,andperhapsallowuserstomakeandsavechangestothedata.OtherthingsthatcanbedoneprogrammaticallywithADOinclude:

    QueryingadatabaseusingSQLanddisplayingtheresults.AccessinginformationinafilestoreovertheInternet.Manipulatingmessagesandfoldersinane-mailsystem.SavingdatafromadatabaseintoanXMLfile.Allowingausertoreviewandmakechangestodataindatabasetables.Creatingandreusingparameterizeddatabasecommands.Executingstoredprocedures.Dynamicallycreatingaflexiblestructure,calledaRecordset,tohold,navigate,andmanipulatedata.Performingtransactionaldatabaseoperations.Filteringandsortinglocalcopiesofdatabaseinformationbasedonrun-timecriteria.Creatingandmanipulatinghierarchicalresultsfromdatabases.Bindingdatabasefieldstodata-awarecomponents.Creatingremote,disconnectedRecordsets.

    ADOmustexposeawidevarietyofoptionsandsettingsinordertoprovidesuchflexibility.Thereforeit'simportanttotakeamethodicalapproachtolearninghowtouseADOinanapplication,breakingdowneachofyourgoalsintomanageablepieces.

    FourprimaryoperationsareinvolvedinmostADOprograms:gettingdata,examiningdata,editingdata,andupdatingdata.Thenextfourchaptersexamineeachoftheseoperationsinmoredetail.

    Beforeproceeding,familiarizeyourselfwiththeobjectsintheADOObjectModel.ThenreviewHelloData:ASimpleADOApplication.ThisapplicationiswritteninVisualBasicandperformseachofthefourprimaryADOoperations.

  • ©1998-2002MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • TheADOObjectModelADOrequiresonlynineobjectsandfourcollectionstoprovideitsentirefunctionality.Thefollowingtableintroducesthem.

    ObjectorCollection Description

    Connectionobject

    Representsauniquesessionwithadatasource.Inthecaseofaclient/serverdatabasesystem,itmaybeequivalenttoanactualnetworkconnectiontotheserver.Dependingonthefunctionalitysupportedbytheprovider,somecollections,methods,orpropertiesofaConnectionobjectmaynotbeavailable.

    CommandobjectUsedtodefineaspecificcommand,suchasaSQLquery,intendedtorunagainstadatasource.

    Recordsetobject

    Representstheentiresetofrecordsfromabasetableortheresultsofanexecutedcommand.AllRecordsetobjectsconsistofrecords(rows)andfields(columns).

    Recordobject

    Representsasinglerowofdata,eitherfromaRecordsetorfromtheprovider.Thisrecordcouldrepresentadatabaserecordorsomeothertypeofobjectsuchasafileordirectory,dependinguponyourprovider.

    Streamobject

    Representsastreamofbinaryortextdata.Forexample,anXMLdocumentcanbeloadedintoastreamforcommandinputorreturnedfromcertainprovidersastheresultsofaquery.AStreamobjectcanbeusedto

  • manipulatefieldsorrecordscontainingthesestreamsofdata.

    Parameterobject

    RepresentsaparameterorargumentassociatedwithaCommandobject,basedonaparameterizedqueryorstoredprocedure.

    Fieldobject

    Representsacolumnofdatawithacommondatatype.EachFieldobjectcorrespondstoacolumnintheRecordset.

    Propertyobject

    RepresentsacharacteristicofanADOobjectthatisdefinedbytheprovider.ADOobjectshavetwotypesofproperties:built-inanddynamic.Built-inpropertiesarethosepropertiesimplementedinADOandimmediatelyavailabletoanynewobject.ThePropertyobjectisacontainerfordynamicproperties,definedbytheunderlyingprovider.

    ErrorobjectContainsdetailsaboutdataaccesserrorsthatpertaintoasingleoperationinvolvingtheprovider.

    Fieldscollection ContainsalltheFieldobjectsofaRecordsetorRecordobject.

    Propertiescollection ContainsallthePropertyobjectsforaspecificinstanceofanobject.

    Parameterscollection ContainsalltheParameterobjectsofaCommandobject.

    ErrorscollectionContainsalltheErrorobjectscreatedinresponsetoasingleprovider-relatedfailure.

    ThefollowingfiguresshowtheADOobjectsandtheircollections.ClickanobjectorcollectionformoreinformationfromtheADOProgrammer'sReference.

  • ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • HelloData:ASimpleADOApplicationTolaythegroundworkforanexplorationoftheADOlibrary,considerasimpleADOapplicationcalled"HelloData."HelloDatastepsthrougheachofthefourmajorADOoperations(getting,examining,editing,andupdatingdata).InordertofocusonthefundamentalsofADOandpreventcodeclutter,minimalerrorhandlingisdoneintheexample.

    TheapplicationqueriestheNorthwindsampledatabasethatisincludedwithMicrosoftSQLServer2000.

    TorunHelloData

    1. CreateanewStandardExecutableVisualBasicProjectthatreferencestheADO2.5library.

    2. Createfourcommandbuttonsatthetopoftheform,settingtheNameandCaptionpropertiestothevaluesshowninthetablebelow.

    3. Belowthebuttons,addaMicrosoftDataGridControl(Msdatgrd.ocx).TheMsdatgrd.ocxfilecomeswithVisualBasicandislocatedinyour\windows\system32or\winnt\system32directory.ToaddtheDataGridcontroltoyourVisualBasictoolboxpane,selectComponents...fromtheProjectmenu.Thenchecktheboxnextto"MicrosoftDataGridControl6.0(SP3)(OLEDB)"andclickOK.Toaddthecontroltotheproject,dragtheDataGridcontrolfromtheToolboxtotheVisualBasicform.

    4. CreateaTextBoxontheformbelowthegridandsetitspropertiesasshowninthetable.Theformshouldlooksimilartothefollowingfigurewhenyouarefinished.

    5. Finally,copythecodelistedin"HelloDataCode"andpasteitintothecodeeditorwindowoftheform.PressF5torunthecode.

    NoteInthefollowingexample,andthroughouttheguide,theuserid"MyId"withapasswordof"123aBc"isusedtoauthenticateagainsttheserver.Youshouldsubstitutethesevalueswithvalidlogoncredentialsforyourserver.Also,substitutethe"MyServer"valuewiththenameofyourserver.

  • Foradetaileddescriptionofthecode,see"HelloDataDetails."

    ControlType Property ValueForm Name Form1 Height 6500 Width 6500MSDataGrid Name grdDisplay1TextBox Name txtDisplay1 Multiline trueCommandButton Name cmdGetData Caption GetDataCommandButton Name cmdExamineData Caption ExamineDataCommandButton Name cmdEditData Caption EditDataCommandButton Name cmdUpdateData Caption UpdateData

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • HelloDataDetailsTheHelloDataapplicationstepsthroughthebasicoperationsofatypicalADOapplication:getting,examining,editing,andupdatingdata.Whenyoustarttheapplication,clickthefirstbutton,GetData.ThiswillruntheGetData()subroutine.

  • GetData

    GetDataplacesavalidconnectionstringintoamodule-levelvariable,m_sConnStr.Formoreinformationaboutconnectionstrings,seeCreatingtheConnectionString.

    AssignanerrorhandlerusingaVisualBasicOnErrorstatement.FormoreinformationabouterrorhandlinginADO,seeChapter6:ErrorHandling.AnewConnectionobjectiscreated,andtheCursorLocationpropertyissettoadUseClientbecausetheHelloDataexamplecreatesadisconnectedRecordset.Thismeansthatoncethedatahasbeenfetchedfromthedatasource,thephysicalconnectionwiththedatasourceisbroken,butyoucanstillworkwiththedatathatiscachedlocallyinyourRecordsetobject.

    Aftertheconnectionhasbeenopened,assignaSQLstringtoavariable(sSQL).TheninstantiateanewRecordsetobject,m_oRecordset1.Inthenextlineofcode,opentheRecordsetovertheexistingConnection,passinginsSQLasthesourceoftheRecordset.YouassistADOinmakingthedeterminationthattheSQLstringyouhavepassedasthesourcefortheRecordsetisatextualdefinitionofacommandbypassingadCmdTextinthefinalargumenttotheRecordsetOpenmethod.ThislinealsosetstheLockTypeandCursorTypeassociatedwiththeRecordset.

    ThenextlineofcodesetstheMarshalOptionspropertyequaltoadMarshalModifiedOnly.MarshalOptionsindicateswhichrecordsshouldbemarshaledtothemiddletier(orwebserver).Formoreinformationaboutmarshaling,seetheCOMdocumentation.WhenusingadMarshalModifiedOnlywithaclient-sidecursor(CursorLocation=adUseClient),onlyrecordsthathavebeenmodifiedontheclientarewrittenbacktothemiddletier.SettingMarshalOptionstoadMarshalModifiedOnlycanimproveperformancebecausefewerrowsaremarshaled.

    Next,disconnecttheRecordsetbysettingitsActiveConnectionpropertyequaltoNothing.Formoreinformation,seeDisconnectingandReconnectingtheRecordsetinChapter5:UpdatingandPersistingData.

    ClosetheconnectiontothedatasourceanddestroytheexistingConnectionobject,therebyreleasingtheresourcesitconsumed.

  • ThefinalstepistosettheRecordsetastheDataSourcefortheMicrosoftDataBoundGridControlontheformsothatyoucaneasilydisplaythedatafromtheRecordsetontheform.

    Clickthesecondbutton,ExamineData.ThisrunstheExamineDatasubroutine.

  • ExamineData

    ExamineDatausesvariousmethodsandpropertiesoftheRecordsetobjecttodisplayinformationaboutthedataintheRecordset.ItreportsthenumberofrecordsbyusingtheRecordCountproperty.ItloopsthroughtheRecordsetandprintsthevalueoftheAbsolutePositionpropertyinthedisplaytextboxontheform.Alsowhileintheloop,thevalueoftheBookmarkpropertyforthethirdrecordisplacedintoavariantvariable,vBookmark,forlateruse.

    Theroutinenavigatesdirectlybacktothethirdrecordusingthebookmarkvariablethatitstoredearlier.TheroutinecallstheWalkFieldssubroutine,whichloopsthroughtheFieldscollectionoftheRecordsetanddisplaysdetailsabouteachFieldinthecollection.

    Finally,ExamineDatausestheFilterpropertyoftheRecordsettoscreenforonlythoserecordswithaCategoryIdequalto2.Theresultofapplyingthisfilterisimmediatelyvisibleinthedisplaygridontheform.

    FormoreinformationaboutthefunctionalityshownintheExamineDatasubroutine,seeChapter3:ExaminingData.

    Next,clickthethirdbutton,EditData.ThiswillruntheEditDatasubroutine.

  • EditData

    WhenthecodeenterstheEditDatasubroutine,theRecordsetisstillfilteredonCategoryIdequalto2,soonlythoseitemsthatmeetthefiltercriteriaarevisible.ItfirstloopsthroughtheRecordsetandincreasesthepriceofeachvisibleitemintheRecordsetby10percent.ThevalueofthePricefieldischangedbysettingtheValuepropertyforthatfieldequaltoanew,validamount.

    RememberthattheRecordsetisdisconnectedfromthedatasource.ThechangesmadeinEditDataaremadeonlytothelocallycachedcopyofthedata.Formoreinformation,seeChapter4:EditingData.

    Thechangeswillnotbemadeonthedatasourceuntilyouclickthefourthbutton,UpdateData.ThiswillruntheUpdateDatasubroutine.

  • UpdateData

    UpdateDatafirstremovesthefilterthathasbeenappliedtotheRecordset.Thecoderemovesandresetsm_oRecordset1astheDataSourcefortheMicrosoftBoundDataGridontheformsothattheunfilteredRecordsetappearsinthegrid.

    ThecodethencheckstoseewhetheryoucanmovebackwardintheRecordsetbyusingtheSupportsmethodwiththeadMovePreviousargument.

    TheroutinemovestothefirstrecordusingtheMoveFirstmethodanddisplaysthefield'soriginalandcurrentvalues,usingtheOriginalValueandValuepropertiesoftheFieldobject.Theseproperties,alongwiththeUnderlyingValueproperty(notusedhere),arediscussedinChapter5:UpdatingandPersistingData.

    Next,anewConnectionobjectiscreatedandusedtoreestablishaconnectiontothedatasource.YoureconnecttheRecordsettothedatasourcebysettingthenewConnectionastheActiveConnectionfortheRecordset.Tosendtheupdatestotheserver,thecodecallsUpdateBatchontheRecordset.

    Ifthebatchupdatesucceeds,amodule-levelflagvariable,m_flgPriceUpdated,issettoTrue.Thiswillremindyoulatertocleanupallchangesmadetothedatabase.

    Finally,thecodemovesbacktothefirstrecordintheRecordsetanddisplaystheoriginalandcurrentvalues.ThevaluesarethesameafterthecalltoUpdateBatch.

    Formoredetailedinformationaboutupdatingdata,includingwhattodowhendataontheserverchangeswhileyourRecordsetisdisconnected,seeChapter5:UpdatingandPersistingData.

  • Form_Unload

    TheForm_Unloadsubroutineisimportantforseveralreasons.First,becausethisisasampleapplication,Form_Unloadcleansupthechangesmadetothedatabasebeforetheapplicationexits.Second,thecodeshowshowacommandcanbeexecuteddirectlyfromanopenConnectionobjectusingtheExecutemethod.Finally,itshowsanexampleofexecutinganon-row–returningquery(anUPDATEquery)againstthedatasource.

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • HelloDataCode'BeginHelloDataOptionExplicit

    Dimm_oRecordsetAsADODB.RecordsetDimm_sConnStrAsStringDimm_flgPriceUpdatedAsBoolean

    PrivateSubcmdGetData_Click()GetDataIfNotm_oRecordsetIsNothingThenIfm_oRecordset.State=adStateOpenThen'Settheproperstatesforthebuttons.cmdGetData.Enabled=FalsecmdExamineData.Enabled=TrueEndIfEndIfEndSub

    PrivateSubcmdExamineData_Click()ExamineDataEndSub

    PrivateSubcmdEditData_Click()EditDataEndSub

    PrivateSubcmdUpdateData_Click()UpdateData'Settheproperstatesforthebuttons.cmdUpdateData.Enabled=FalseEndSub

    PrivateSubGetData()OnErrorGoToGetDataErrorDimsSQLAsStringDimoConnection1AsADODB.Connectionm_sConnStr="Provider='SQLOLEDB';DataSource='MySqlServer';"&_"InitialCatalog='Northwind';IntegratedSecurity='SSPI';"'CreateandOpentheConnectionobject.

  • SetoConnection1=NewADODB.ConnectionoConnection1.CursorLocation=adUseClientoConnection1.Openm_sConnStrsSQL="SELECTProductID,ProductName,CategoryID,UnitPrice"&_"FROMProducts"'CreateandOpentheRecordsetobject.Setm_oRecordset=NewADODB.Recordsetm_oRecordset.OpensSQL,oConnection1,adOpenStatic,_adLockBatchOptimistic,adCmdTextm_oRecordset.MarshalOptions=adMarshalModifiedOnly'DisconnecttheRecordset.Setm_oRecordset.ActiveConnection=NothingoConnection1.CloseSetoConnection1=Nothing'BindRecordsettotheDataGridfordisplay.SetgrdDisplay1.DataSource=m_oRecordsetExitSubGetDataError:IfErr0ThenIfoConnection1IsNothingThenHandleErrs"GetData",m_oRecordset.ActiveConnectionElseHandleErrs"GetData",oConnection1EndIfEndIfIfNotoConnection1IsNothingThenIfoConnection1.State=adStateOpenThenoConnection1.CloseSetoConnection1=NothingEndIfEndSub

    PrivateSubExamineData()OnErrGoToExamineDataErrDimiNumRecordsAsIntegerDimvBookmarkAsVariantiNumRecords=m_oRecordset.RecordCountDisplayMsg"Thereare"&CStr(iNumRecords)&_"recordsinthecurrentRecordset."

  • 'LoopthroughtheRecordsetandprintthe'valueoftheAbsolutePositionproperty.DisplayMsg"******StartAbsolutePositionLoop******"DoWhileNotm_oRecordset.EOF'Storethebookmarkforthe3rdrecord,'fordemopurposes.Ifm_oRecordset.AbsolutePosition=3Then_vBookmark=m_oRecordset.BookmarkDisplayMsgm_oRecordset.AbsolutePositionm_oRecordset.MoveNextLoopDisplayMsg"******EndAbsolutePositionLoop******"&vbCrLf'Useourbookmarktomovebackto3rdrecord.m_oRecordset.Bookmark=vBookmarkMsgBoxvbCr&"Movedbacktoposition"&_m_oRecordset.AbsolutePosition&"usingbookmark.",,_"HelloData"'Displaymeta-dataabouteachfield.SeeWalkFields()sub.CallWalkFields'Applyafilteronthetypefield.MsgBox"Filteringontypefield.(CategoryID=2)",_vbOKOnly,"HelloData"m_oRecordset.Filter="CategoryID=2"'Settheproperstatesforthebuttons.cmdExamineData.Enabled=FalsecmdEditData.Enabled=True

    ExitSubExamineDataErr:HandleErrs"ExamineData",m_oRecordset.ActiveConnectionEndSub

    PrivateSubEditData()OnErrorGoToEditDataErr'RecordsetstillfilteredonCategoryID=2.'Increasepriceby10%forfilteredrecords.MsgBox"Increasingunitpriceby10%"&vbCr&_"forallrecordswithCategoryID=2.",,"HelloData"

  • m_oRecordset.MoveFirstDimcValAsCurrencyDoWhileNotm_oRecordset.EOFcVal=m_oRecordset.Fields("UnitPrice").Valuem_oRecordset.Fields("UnitPrice").Value=(cVal*1.1)m_oRecordset.MoveNextLoop'Settheproperstatesforthebuttons.cmdEditData.Enabled=FalsecmdUpdateData.Enabled=True

    ExitSubEditDataErr:HandleErrs"EditData",m_oRecordset.ActiveConnectionEndSub

    PrivateSubUpdateData()OnErrorGoToUpdateDataErrDimoConnection2AsNewADODB.ConnectionMsgBox"RemovingFilter(adFilterNone).",,"HelloData"m_oRecordset.Filter=adFilterNoneSetgrdDisplay1.DataSource=NothingSetgrdDisplay1.DataSource=m_oRecordsetMsgBox"ApplyingFilter(adFilterPendingRecords).",,"HelloData"m_oRecordset.Filter=adFilterPendingRecordsSetgrdDisplay1.DataSource=NothingSetgrdDisplay1.DataSource=m_oRecordsetDisplayMsg"***PRE-UpdateBatchvaluesfor'UnitPrice'field.***"'DisplayValue,UnderlyingValue,andOriginalValuefor'typefieldinfirstrecord.Ifm_oRecordset.Supports(adMovePrevious)Thenm_oRecordset.MoveFirstDisplayMsg"OriginalValue="&_m_oRecordset.Fields("UnitPrice").OriginalValueDisplayMsg"Value="&_m_oRecordset.Fields("UnitPrice").ValueEndIfoConnection2.ConnectionString=m_sConnStr

  • oConnection2.OpenSetm_oRecordset.ActiveConnection=oConnection2m_oRecordset.UpdateBatchm_flgPriceUpdated=TrueDisplayMsg"***POST-UpdateBatchvaluesfor'UnitPrice'field***"Ifm_oRecordset.Supports(adMovePrevious)Thenm_oRecordset.MoveFirstDisplayMsg"OriginalValue="&_m_oRecordset.Fields("UnitPrice").OriginalValueDisplayMsg"Value="&_m_oRecordset.Fields("UnitPrice").ValueEndIfMsgBox"SeevaluecomparisonsintxtDisplay.",,_"HelloData"'CleanupoConnection2.CloseSetoConnection2=NothingExitSubUpdateDataErr:IfErr0ThenHandleErrs"UpdateData",oConnection2EndIfIfNotoConnection2IsNothingThenIfoConnection2.State=adStateOpenThenoConnection2.CloseSetoConnection2=NothingEndIfEndSub

    PrivateSubWalkFields()OnErrorGoToWalkFieldsErrDimiFldCntAsIntegerDimoFieldsAsADODB.FieldsDimoFieldAsADODB.FieldDimsMsgAsStringSetoFields=m_oRecordset.FieldsDisplayMsg"******BEGINFIELDSWALK******"ForiFldCnt=0To(oFields.Count-1)

  • SetoField=oFields(iFldCnt)sMsg=""sMsg=sMsg&oField.NamesMsg=sMsg&vbTab&"Type:"&GetTypeAsString(oField.Type)sMsg=sMsg&vbTab&"DefinedSize:"&oField.DefinedSizesMsg=sMsg&vbTab&"ActualSize:"&oField.ActualSizegrdDisplay1.SelStartCol=iFldCntgrdDisplay1.SelEndCol=iFldCntDisplayMsgsMsgMsgBoxsMsg,,"HelloData"NextiFldCntDisplayMsg"******ENDFIELDSWALK******"&vbCrLf'CleanupSetoField=NothingSetoFields=NothingExitSubWalkFieldsErr:SetoField=NothingSetoFields=NothingIfErr0ThenMsgBoxErr.Source&"-->"&Err.Description,,"Error"EndIfEndSub

    PrivateFunctionGetTypeAsString(dtTypeAsADODB.DataTypeEnum)AsString'Tosavespace,weareonlycheckingfordatatypes'thatweknowarepresent.SelectCasedtTypeCaseadCharGetTypeAsString="adChar"CaseadVarCharGetTypeAsString="adVarChar"CaseadVarWCharGetTypeAsString="adVarWChar"CaseadCurrencyGetTypeAsString="adCurrency"CaseadIntegerGetTypeAsString="adInteger"EndSelectEndFunction

    PrivateSubHandleErrs(sSourceAsString,ByRefm_oConnectionAsADODB.Connection)DisplayMsg"ADO(OLE)ERRORIN"&sSourceDisplayMsgvbTab&"Error:"&Err.NumberDisplayMsgvbTab&"Description:"&Err.Description

  • DisplayMsgvbTab&"Source:"&Err.SourceIfNotm_oConnectionIsNothingThenIfm_oConnection.Errors.Count0ThenDisplayMsg"PROVIDERERROR"DimoError1AsADODB.ErrorForEachoError1Inm_oConnection.ErrorsDisplayMsgvbTab&"Error:"&oError1.NumberDisplayMsgvbTab&"Description:"&oError1.DescriptionDisplayMsgvbTab&"Source:"&oError1.SourceDisplayMsgvbTab&"NativeError:"&oError1.NativeErrorDisplayMsgvbTab&"SQLState:"&oError1.SQLStateNextoError1m_oConnection.Errors.ClearSetoError1=NothingEndIfEndIfMsgBox"Error(s)occurred.SeetxtDisplay1forspecificinformation.",,_"HelloData"Err.ClearEndSub

    PrivateSubDisplayMsg(sTextAsString)txtDisplay1.Text=(txtDisplay1.Text&vbCrLf&sText)EndSub

    PrivateSubForm_Resize()grdDisplay1.Move100,700,Me.ScaleWidth-200,(Me.ScaleHeight-800)/2txtDisplay1.Move100,grdDisplay1.Top+grdDisplay1.Height+100,_Me.ScaleWidth-200,(Me.ScaleHeight-1000)/2EndSub

    PrivateSubForm_Load()cmdGetData.Enabled=TruecmdExamineData.Enabled=FalsecmdEditData.Enabled=FalsecmdUpdateData.Enabled=FalsegrdDisplay1.AllowAddNew=FalsegrdDisplay1.AllowDelete=FalsegrdDisplay1.AllowUpdate=Falsem_flgPriceUpdated=FalseEndSub

    PrivateSubForm_Unload(CancelAsInteger)OnErrorGoToErrHandler:

  • DimoConnection3AsNewADODB.ConnectionDimsSQLAsStringDimlAffectedAsLong'Undothechangeswe'vemadetothedatabaseontheserver.Ifm_flgPriceUpdatedThensSQL="UPDATEProductsSETUnitPrice=(UnitPrice/1.1)"&_"WHERECategoryID=2"oConnection3.Openm_sConnStroConnection3.ExecutesSQL,lAffected,adCmdTextMsgBox"Restoredpricesfor"&CStr(lAffected)&_"recordsaffected.",,"HelloData"EndIf'CleanupoConnection3.CloseSetoConnection3=Nothingm_oRecordset.CloseSetm_oRecordset=NothingExitSubErrHandler:IfNotoConnection3IsNothingThenIfoConnection3.State=adStateOpenThenoConnection3.CloseSetoConnection3=NothingEndIfIfNotm_oRecordsetIsNothingThenIfm_oRecordset.State=adStateOpenThenm_oRecordset.CloseSetm_oRecordset=NothingEndIfEndSub

    'EndHelloData

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • OLEDBProvidersTheADOProgrammer'sGuideIntroductiondiscussestherelationshipbetweenADOandtherestoftheMicrosoftDataAccessarchitecture.OLEDBdefinesasetofCOMinterfacestoprovideapplicationswithuniformaccesstodatathatisstoredindiverseinformationsources.ThisapproachallowsadatasourcetoshareitsdatathroughtheinterfacesthatsupporttheamountofDBMSfunctionalityappropriatetothedatasource.Bydesign,thehigh-performancearchitectureofOLEDBisbasedonitsuseofaflexible,component-basedservicesmodel.Ratherthanhavingaprescribednumberofintermediarylayersbetweentheapplicationandthedata,OLEDBrequiresonlyasmanycomponentsasareneededtoaccomplishaparticulartask.

    Forexample,supposeauserwantstorunaquery.Considerthefollowingscenarios:

    ThedataresidesinarelationaldatabaseforwhichtherecurrentlyexistsanODBCdriverbutnonativeOLEDBprovider:TheapplicationusesADOtotalktotheOLEDBProviderforODBC,whichthenloadstheappropriateODBCdriver.ThedriverpassestheSQLstatementtotheDBMS,whichretrievesthedata.ThedataresidesinMicrosoftSQLServerforwhichthereisanativeOLEDBprovider:TheapplicationusesADOtotalkdirectlytotheOLEDBProviderforMicrosoftSQLServer.Nointermediariesarerequired.ThedataresidesinMicrosoftExchangeServer,forwhichthereisanOLEDBproviderbutwhichdoesnotexposeanenginetoprocessSQLqueries:TheapplicationusesADOtotalktotheOLEDBProviderforMicrosoftExchangeandcallsuponanOLEDBqueryprocessorcomponenttohandlethequerying.ThedataresidesintheMicrosoftNTFSfilesystemintheformofdocuments:DataisaccessedbyusinganativeOLEDBprovideroverMicrosoftIndexingService,whichindexesthecontentandpropertiesofdocumentsinthefilesystemtoenableefficientcontentsearches.

    Inalloftheprecedingexamples,theapplicationcanquerythedata.Theuser'sneedsaremetwithaminimumnumberofcomponents.Ineachcase,additionalcomponentsareusedonlyifneeded,andonlytherequiredcomponentsare

  • invoked.Thisdemand-loadingofreusableandshareablecomponentsgreatlycontributestohighperformancewhenOLEDBisused.

    Providersfallintotwocategories:thoseprovidingdataandthoseprovidingservices.Adataproviderownsitsowndataandexposesitintabularformtoyourapplication.Aserviceproviderencapsulatesaservicebyproducingandconsumingdata,augmentingfeaturesinyourADOapplications.Aserviceprovidermayalsobefurtherdefinedasaservicecomponent,whichmustworkinconjunctionwithotherserviceprovidersorcomponents.

    ADOprovidesaconsistent,higherlevelinterfacetothevariousOLEDBproviders.

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • DataProvidersDataprovidersrepresentdiversesourcesofdatasuchasSQLdatabases,indexed-sequentialfiles,spreadsheets,documentstores,andmailfiles.Providersexposedatauniformlyusingacommonabstractioncalledtherowset.

    ADOispowerfulandflexiblebecauseitcanconnecttoanyofseveraldifferentdataprovidersandstillexposethesameprogrammingmodel,regardlessofthespecificfeaturesofanygivenprovider.However,becauseeachdataproviderisunique,howyourapplicationinteractswithADOwillvarybydataprovider.

    Forexample,thecapabilitiesandfeaturesoftheOLEDBProviderforSQLServer,whichisusedtoaccessMicrosoftSQLServerdatabases,areconsiderablydifferentfromthoseoftheMicrosoftOLEDBProviderforInternetPublishing,whichisusedtoaccessfilestoresonaWebserver.

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • ServiceProvidersandComponentsServiceprovidersarecomponentsthatextendthefunctionalityofdataprovidersbyimplementingextendedinterfacesthatarenotnativelysupportedbythedatastore.

    MicrosoftDataAccessprovidesacomponentarchitecturethatallowsindividual,specializedcomponentstoimplementdiscretesetsofdatabasefunctionality,or"services,"ontopoflesscapablestores.Thus,ratherthanforcingeachdatastoretoprovideitsownimplementationofextendedfunctionalityorforcinggenericapplicationstoimplementdatabasefunctionalityinternally,servicecomponentsprovideacommonimplementationthatanyapplicationcanusewhenaccessinganydatastore.Thefactthatsomefunctionalityisimplementednativelybythedatastoreandsomethroughgenericcomponentsistransparenttotheapplication.

    Forexample,acursorengine,suchastheMicrosoftCursorServiceforOLEDB,isaservicecomponentthatcanconsumedatafromasequential,forward-onlydatastoretoproducescrollabledata.OtherserviceproviderscommonlyusedbyADOincludetheMicrosoftOLEDBPersistenceProvider(forsavingdatatoafile),theMicrosoftDataShapingServiceforOLEDB(forhierarchicalRecordsets),andtheMicrosoftOLEDBRemotingProvider(forinvokingdataprovidersonaremotecomputer).

    Formoreinformationaboutserviceanddataproviders,seeAppendixA:Providers.

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • ErrorsAnyoperationinvolvingADOobjectscangenerateoneormoreprovidererrors.Aseacherroroccurs,oneormoreErrorobjectsareplacedintheErrorscollectionoftheConnectionobject.FordetailsabouthandlingwarningsanderrorsinyourADOapplication,seeChapter6:ErrorHandling.

    Applicationerrorscanberaisedbyaseparatemechanism.Forexample,inVisualBasic,theErrobjectwillcontainapplication-levelerrors.

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • Chapter2:GettingDataTheprecedingchapterintroducedfourprimaryoperationsinvolvedincreatinganADOapplication:gettingdata,examiningdata,editingdata,andupdatingdata.Thischapterwillfocusonthedetailsoftheconceptsrelevanttothefirstoperation:gettingdata.

    SeveralADOobjectscanplayaroleinthisoperation.FirstyouconnecttothedatasourceusinganADOConnectionobject(whichattimeswillbecreatedimplicitly).ThenyoupassinstructionstothedatasourceaboutwhatyouwanttodousinganADOCommandobject(whichalsocanbecreatedimplicitly).TheresultofpassingacommandtoadatasourceandreceivingitsresponseusuallywillberepresentedinanADORecordsetobject.

    Togetdata,yourapplicationmustbeincommunicationwithadatasource,suchasaDBMS,afilestore,oracomma-delimitedtextfile.Thiscommunicationrepresentsaconnection—theenvironmentnecessaryforexchangingdata.

    TheADOobjectmodelrepresentstheconceptofaconnectionwiththeConnectionobject—thefoundationuponwhichmuchADOfunctionalityisbuilt.ThepurposeofaConnectionobjectisto:

    DefinetheinformationADOneedstocommunicatewithdatasourcesandcreatesessions.Definethetransactionalcapabilitiesofthesession.Allowyoutocreateandexecutecommandsagainstthedatasource.Provideinformationaboutthedesignoftheunderlyingdatasourceintheformofschemarowsets.Formoreinformationaboutschemarowsets,seeOpenSchemaMethod.

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • MakingaConnectionToconnecttoadatasource,youmustspecifyaconnectionstring,theparametersofwhichmightdifferforeachprovideranddatasource.Formoreinformation,seeCreatingtheConnectionString.

    ADOmostcommonlyopensaconnectionbyusingtheConnectionobjectOpenmethod.ThesyntaxfortheOpenmethodisshownhere:

    DimconnectionasNewADODB.Connectionconnection.OpenConnectionString,UserID,Password,OpenOptions

    Alternatively,youcaninvokeashortcuttechnique,Recordset.Open,toopenanimplicitconnectionandissueacommandoverthatconnectioninoneoperation.DothisbypassinginavalidconnectionstringastheActiveConnectionargumenttotheOpenmethod.HereisthesyntaxforeachmethodinVisualBasic:

    DimrecordsetasADODB.RecordsetSetrecordset=NewADODB.Recordsetrecordset.OpenSource,ActiveConnection,CursorType,LockType,Options

    NoteWhenshouldyouuseaConnectionobjectvs.theRecordset.Openshortcut?UsetheConnectionobjectifyouplantoopenmorethanoneRecordset,orwhenexecutingmultiplecommands.AconnectionisstillcreatedbyADOimplicitlywhenyouusetheRecordset.Openshortcut.

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • UsingtheConnectionObjectAConnectionobjectrepresentsauniquesessionwithadatasource.Inthecaseofaclient/serverdatabasesystem,itcanbeequivalenttoanactualnetworkconnectiontotheserver.Dependingonthefunctionalitysupportedbytheprovider,somecollections,methods,orpropertiesofaConnectionobjectmightnotbeavailable.

    BeforeopeningaConnectionobject,youmustdefinecertaininformationaboutthedatasourceandtypeofconnection.TheConnectionStringparameteroftheConnectionobjectOpenmethod—ortheConnectionStringpropertyontheConnectionobject—usuallycontainsmostofthisinformation.Aconnectionstringisastringofcharactersthatdefinesavariablenumberofarguments.Thearguments—somerequiredbyADO,butothersprovider-specific—containinformationthattheConnectionobjectmusthavetocarryoutitswork.TheargumentsthatmakeuptheConnectionStringparameterareseparatedwithsemicolons(;).

    NoteYoucanalsospecifyanODBCDataSourceName(DSN)oraDataLink(UDL)fileinaconnectionstring.FormoreinformationaboutDSNs,seeDataSourcesinPart1oftheODBCProgrammer'sReference.FormoreinformationaboutUDLs,seeDataLinkAPIOverviewintheOLEDBProgrammer'sReference.

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • CreatingtheConnectionStringADOdirectlysupportsfiveargumentsinaconnectionstring.OtherargumentsarepassedtotheproviderthatisnamedintheProviderargumentwithoutanyprocessingbyADO.

    Argument Description

    Provider Specifiesthenameofaprovidertousefortheconnection.

    FileName

    Specifiesthenameofaprovider-specificfile(forexample,apersisteddatasourceobject)containingpresetconnectioninformation.

    URLSpecifiestheconnectionstringasanabsoluteURLidentifyingaresource,suchasafileordirectory.

    RemoteProviderSpecifiesthenameofaprovidertousewhenopeningaclient-sideconnection.(RemoteDataServiceonly.)

    RemoteServer

    Specifiesthepathnameoftheservertousewhenopeningaclient-sideconnection.(RemoteDataServiceonly.)

    NoteInthefollowingexamplesandthroughouttheADOProgrammer'sGuide,theuserid"MyId"withapasswordof"123aBc"isusedtoauthenticateagainsttheserver.Youshouldsubstitutethesevalueswithvalidlogincredentialsforyourserver.Also,substitutethenameofyourserverfor"MySqlServer".

    TheHelloDataapplicationinChapter1usedthefollowingconnectionstring:

    m_sConnStr="Provider='SQLOLEDB';DataSource='MySqlServer';"&_"InitialCatalog='Northwind';IntegratedSecurity='SSPI';"

    TheonlyADOparametersuppliedinthisconnectionstringwas

  • "Provider=SQLOLEDB",whichindicatedtheMicrosoftOLEDBProviderforSQLServer.Othervalidparametersthatcanbepassedintheconnectionstringcanbedeterminedbyreferringtoindividualproviders'documentation.AccordingtotheOLEDBProviderforSQLServerdocumentation,youcansubstitute"Server"fortheDataSourceparameterand"Database"fortheInitialCatalogparameter.Thus,thefollowingconnectionstringwouldproduceresultsidenticaltothefirst:

    m_sConnStr="Provider='SQLOLEDB';Server='MySqlServer';"&_"Database='Northwind';IntegratedSecurity='SSPI';"

    Toopentheconnection,simplypasstheconnectionstringasthefirstargumentintheConnectionobjectOpenmethod:

    objConn.Openm_sConnStr

    ItisalsopossibletosupplymuchofthisinformationbysettingpropertiesoftheConnectionobjectbeforeopeningtheconnection.Forexample,youcouldachievethesameeffectastheconnectionstringabovebyusingthefollowingcode:

    WithobjConn.Provider="SQLOLEDB".DefaultDatabase="Northwind".Properties("DataSource")="MySqlServer".Properties("IntegratedSecurity")="SSPI".OpenEndWith

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • ControllingTransactionsAtransactiondelimitsthebeginningandendofaseriesofdataaccessoperationsthattranspireacrossaconnection.Subjecttothetransactionalcapabilitiesofyourdatasource,theConnectionobjectalsoallowsyoutocreateandmanagetransactions.Forexample,usingtheMicrosoftOLEDBProviderforSQLServertoaccessadatabaseonMicrosoftSQLServer2000,youcancreatemultiplenestedtransactionsforthecommandsyouexecute.

    ADOensuresthatchangestoadatasourceresultingfromoperationsinatransactionoccursuccessfullytogetherornotatall.

    Ifyoucancelthetransaction,orifoneofitsoperationsfails,theultimateresultwillbeasifnoneoftheoperationsinthetransactionoccurred.Thedatasourcewillremainasitwasbeforethetransactionbegan.

    TheADOobjectmodeldoesnotexplicitlyincludetransactions,butrepresentsthemwithasetofConnectionobjectmethods(BeginTrans,CommitTrans,andRollbackTrans).

    Formoreinformationabouttransactions,seeChapter5:UpdatingandPersistingData.

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • UsingtheCommandObjectAfterconnectingtoadatasource,youneedtoexecuterequestsagainstittoobtainresultsets.ADOencapsulatesthistypeofcommandfunctionalityintheCommandobject.

    YoucanusetheCommandobjecttorequestanytypeofoperationfromtheprovider,assumingthattheprovidercaninterpretthecommandstringproperly.AcommonoperationfordataprovidersistoqueryadatabaseandreturnrecordsinaRecordsetobject.Recordsetswillbediscussedlaterinthisandotherchapters;fornow,thinkofthemastoolstoholdandviewresultsets.AswithmanyADOobjects,dependingonthefunctionalityoftheprovider,someCommandobjectcollections,methods,orpropertiesmightgenerateerrorswhenreferenced.

    ItisnotalwaysnecessarytocreateaCommandobjecttoexecuteacommandagainstadatasource.YoucanusetheExecutemethodontheConnectionobjectortheOpenmethodontheRecordsetobject.However,youshoulduseaCommandobjectifyouneedtoreuseacommandinyourcodeorifyouneedtopassdetailedparameterinformationwithyourcommand.Thesescenariosarecoveredinmoredetaillaterinthischapter.

    NoteCertainCommandscanreturnaresultsetasabinarystreamorasasingleRecordratherthanasaRecordset,ifthisissupportedbytheprovider.Also,someCommandsarenotintendedtoreturnanyresultsetatall(forexample,aSQLUpdatequery).Thischapterwillcoverthemosttypicalscenario,however:executingCommandsthatreturnresultsintoaRecordsetobject.FormoreinformationaboutreturningresultsintoRecordsorStreams,seeChapter10:RecordsandStreams.

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • CommandObjectOverviewWiththecollections,methods,andpropertiesofaCommandobject,youcandothefollowing:

    Definetheexecutabletextofthecommand(forexample,aSQLstatementorastoredprocedure)byusingtheCommandTextproperty.DefineparameterizedqueriesorstoredprocedureargumentsbyusingParameterobjectsandtheParameterscollection.ExecuteacommandandreturnaRecordsetobject,ifappropriate,byusingtheExecutemethod.SpecifythetypeofcommandbyusingtheCommandTypepropertypriortoexecutiontooptimizeperformance.Controlwhethertheprovidersavesaprepared(orcompiled)versionofthecommandpriortoexecutionbyusingthePreparedproperty.SetthenumberofsecondsthataproviderwillwaitforacommandtoexecutebyusingtheCommandTimeoutproperty.AssociateanopenconnectionwithaCommandobjectbysettingitsActiveConnectionproperty.SettheNamepropertytoidentifytheCommandobjectasamethodontheassociatedConnectionobject.PassaCommandobjecttotheSourcepropertyofaRecordsetinordertoobtaindata.

    ©1998-2002MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • CreatingandExecutingaSimpleCommandThoughnotatypicalusageoftheCommandobject,thefollowingcodeshowsthebasicmethodofusingtheCommandobjecttoexecuteacommandagainstadatasource.Inthiscase,itisarow-returningcommand,soitreturnstheresultsofthecommandexecutionintoaRecordsetobject.

    'BeginBasicCmdOnErrorGoToErrHandler:DimobjConnAsNewADODB.ConnectionDimobjCmdAsNewADODB.CommandDimobjRsAsNewADODB.RecordsetobjCmd.CommandText="SELECTOrderID,OrderDate,"&_"RequiredDate,ShippedDate"&_"FROMOrders"&_"WHERECustomerID='ALFKI'"&_"ORDERBYOrderID"objCmd.CommandType=adCmdText'Connecttothedatasource.SetobjConn=GetNewConnectionobjCmd.ActiveConnection=objConn'Executeonceanddisplay...SetobjRs=objCmd.ExecuteDebug.Print"ALFKI"DoWhileNotobjRs.EOFDebug.PrintvbTab&objRs(0)&vbTab&objRs(1)&vbTab&_objRs(2)&vbTab&objRs(3)objRs.MoveNextLoop'cleanupobjRs.CloseobjConn.CloseSetobjRs=NothingSetobjConn=NothingSetobjCmd=NothingExitSub

  • ErrHandler:'cleanupIfobjRs.State=adStateOpenThenobjRs.CloseEndIfIfobjConn.State=adStateOpenThenobjConn.CloseEndIfSetobjRs=NothingSetobjConn=NothingSetobjCmd=NothingIfErr0ThenMsgBoxErr.Source&"-->"&Err.Description,,"Error"EndIf'EndBasicCmd

    ThecommandtobeexecutedisspecifiedwiththeCommandTextproperty.

    NoteSeveralexamplesinthissectioncallautilityfunction,GetNewConnection,toestablishaconnectionwiththedataprovider.Toavoidredundancy,itislistedonlyonce,here:

    'BeginNewConnectionPrivateFunctionGetNewConnection()AsADODB.ConnectionDimoCnAsNewADODB.ConnectionDimsCnStrAsStringsCnStr="Provider='SQLOLEDB';DataSource='MySqlServer';"&_"IntegratedSecurity='SSPI';Database='Northwind';"oCn.OpensCnStrIfoCn.State=adStateOpenThenSetGetNewConnection=oCnEndIfEndFunction'EndNewConnection

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • CommandObjectParametersAmoreinterestingusefortheCommandobjectisshowninthenextexample,inwhichthetextoftheSQLcommandhasbeenmodifiedtomakeitparameterized.Thismakesitpossibletoreusethecommand,passinginadifferentvaluefortheparametereachtime.BecausethePreparedpropertyontheCommandobjectissetequaltoTrue,ADOwillrequiretheprovidertocompilethecommandspecifiedinCommandTextbeforeexecutingitforthefirsttime.Italsowillretainthecompiledcommandinmemory.Thisslowstheexecutionofthecommandslightlythefirsttimeitisexecutedbecauseoftheoverheadrequiredtoprepareit,butresultsinaperformancegaineachtimethecommandiscalledthereafter.Thus,commandsshouldbepreparedonlyiftheywillbeusedmorethanonce.

    'BeginManualParamCmdOnErrorGoToErrHandler:

    DimobjConnAsNewADODB.ConnectionDimobjCmdAsNewADODB.CommandDimobjParm1AsNewADODB.ParameterDimobjRsAsNewADODB.Recordset'SettheCommandTextasaparameterizedSQLquery.objCmd.CommandText="SELECTOrderID,OrderDate,"&_"RequiredDate,ShippedDate"&_"FROMOrders"&_"WHERECustomerID=?"&_"ORDERBYOrderID"objCmd.CommandType=adCmdText'Preparecommandsincewewillbeexecutingitmorethanonce.objCmd.Prepared=True'CreatenewparameterforCustomerID.InitialvalueisALFKI.SetobjParm1=objCmd.CreateParameter("CustId",adChar,_adParamInput,5,"ALFKI")objCmd.Parameters.AppendobjParm1'Connecttothedatasource.SetobjConn=GetNewConnectionobjCmd.ActiveConnection=objConn'Executeonceanddisplay...

  • SetobjRs=objCmd.ExecuteDebug.PrintobjParm1.ValueDoWhileNotobjRs.EOFDebug.PrintvbTab&objRs(0)&vbTab&objRs(1)&vbTab&_objRs(2)&vbTab&objRs(3)objRs.MoveNextLoop'...thensetnewparamvalue,re-executecommand,anddisplay.objCmd("CustId")="CACTU"SetobjRs=objCmd.ExecuteDebug.PrintobjParm1.ValueDoWhileNotobjRs.EOFDebug.PrintvbTab&objRs(0)&vbTab&objRs(1)&vbTab&_objRs(2)&vbTab&objRs(3)objRs.MoveNextLoop'cleanupobjRs.CloseobjConn.CloseSetobjRs=NothingSetobjConn=NothingSetobjCmd=NothingSetobjParm1=NothingExitSubErrHandler:'cleanupIfobjRs.State=adStateOpenThenobjRs.CloseEndIfIfobjConn.State=adStateOpenThenobjConn.CloseEndIfSetobjRs=NothingSetobjConn=NothingSetobjCmd=NothingSetobjParm1=NothingIfErr0ThenMsgBoxErr.Source&"-->"&Err.Description,,"Error"EndIf'EndManualParamCmd

  • Notallproviderssupportpreparedcommands.Iftheproviderdoesnotsupportcommandpreparation,itmightreturnanerrorassoonasthispropertyissettoTrue.Ifitdoesnotreturnanerror,itignorestherequesttopreparethecommandandsetsthePreparedpropertytoFalse.

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • CallingaStoredProcedurewithaCommandYoucanalsouseacommandwhencallingastoredprocedure.ThefollowingcodecallsastoredprocedureintheNorthwindsampledatabase,calledCustOrdersOrders,whichisdefinedasfollows:

    CREATEPROCEDURECustOrdersOrders@CustomerIDnchar(5)ASSELECTOrderID,OrderDate,RequiredDate,ShippedDateFROMOrdersWHERECustomerID=@CustomerIDORDERBYOrderID

    ThisstoredprocedureissimilartothecommandusedinCommandObjectParameters,inthatittakesacustomerIDparameterandreturnsinformationaboutthatcustomer'sorders.ThecodebelowusesthisstoredprocedureasthesourceforanADORecordset.

    UsingthestoredprocedureallowsyoutoaccessanothercapabilityofADO:theParameterscollectionRefreshmethod.Byusingthismethod,ADOcanautomaticallyfillinallinformationabouttheparametersrequiredbythecommandatruntime.Thereisaperformancepenaltyinusingthistechnique,becauseADOmustquerythedatasourcefortheinformationabouttheparameters.

    OtherimportantdifferencesexistbetweenthecodebelowandthecodeinCommandObjectParameters,wheretheparameterswereenteredmanually.First,thiscodedoesnotsetthePreparedpropertytoTruebecauseitisaSQLServerstoredprocedureandisprecompiledbydefinition.Second,theCommandTypepropertyoftheCommandobjectchangedtoadCmdStoredProcinthesecondexampletoinformADOthatthecommandwasastoredprocedure.

    'BeginAutoParamCmdOnErrorGoToErrHandler:DimobjConnAsNewADODB.ConnectionDimobjCmdAsNewADODB.Command

  • DimobjParm1AsNewADODB.ParameterDimobjRsAsNewADODB.Recordset'SetCommandTextequaltothestoredprocedurename.objCmd.CommandText="CustOrdersOrders"objCmd.CommandType=adCmdStoredProc'Connecttothedatasource.SetobjConn=GetNewConnectionobjCmd.ActiveConnection=objConn'Automaticallyfillinparameterinfofromstoredprocedure.objCmd.Parameters.Refresh'Settheparamvalue.objCmd(1)="ALFKI"'Executeonceanddisplay...SetobjRs=objCmd.ExecuteDebug.PrintobjParm1.ValueDoWhileNotobjRs.EOFDebug.PrintvbTab&objRs(0)&vbTab&objRs(1)&vbTab&_objRs(2)&vbTab&objRs(3)objRs.MoveNextLoop'...thensetnewparamvalue,re-executecommand,anddisplay.objCmd(1)="CACTU"SetobjRs=objCmd.ExecuteDebug.PrintobjParm1.ValueDoWhileNotobjRs.EOFDebug.PrintvbTab&objRs(0)&vbTab&objRs(1)&vbTab&_objRs(2)&vbTab&objRs(3)objRs.MoveNextLoop'cleanupobjRs.CloseobjConn.CloseSetobjRs=NothingSetobjConn=NothingSetobjCmd=NothingSetobjParm1=NothingExitSubErrHandler:'cleanupIfobjRs.State=adStateOpenThen

  • objRs.CloseEndIfIfobjConn.State=adStateOpenThenobjConn.CloseEndIfSetobjRs=NothingSetobjConn=NothingSetobjCmd=NothingSetobjParm1=NothingIfErr0ThenMsgBoxErr.Source&"-->"&Err.Description,,"Error"EndIf'EndAutoParamCmd

    ©1998-2002MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • NamedCommandsYoucansettheNamepropertyonaCommandobjectandthenexecutethecommandbycallingitasifitwereamethodontheCommandobjectActiveConnectionproperty.Thisisillustratedinthefollowingexample,inwhichthecommandisnamedGetCustomers.NoticethatthecodepassesinadeclaredandinstantiatedRecordsetobjecttotheGetCustomers"method."Youcanalsopassinparameterstothe"method"iftheyarerequiredbytheCommand.

    'BeginNamedCmdOnErrorGoToErrHandler:DimobjConnAsNewADODB.ConnectionDimobjCmdAsNewADODB.CommandDimobjRsAsNewADODB.Recordset'Connecttothedatasource.SetobjConn=GetNewConnectionobjCmd.CommandText="SELECTCustomerID,CompanyNameFROMCustomers"objCmd.CommandType=adCmdText'Namethecommand.objCmd.Name="GetCustomers"objCmd.ActiveConnection=objConn'ExecuteusingCommand.NamefromtheConnection.objConn.GetCustomersobjRs'Display.DoWhileNotobjRs.EOFDebug.PrintobjRs(0)&vbTab&objRs(1)objRs.MoveNextLoop'cleanupobjRs.CloseobjConn.CloseSetobjRs=NothingSetobjConn=NothingSetobjCmd=NothingExitSub

  • ErrHandler:'cleanupIfobjRs.State=adStateOpenThenobjRs.CloseEndIfIfobjConn.State=adStateOpenThenobjConn.CloseEndIfSetobjRs=NothingSetobjConn=NothingSetobjCmd=NothingIfErr0ThenMsgBoxErr.Source&"-->"&Err.Description,,"Error"EndIf'EndNamedCmd

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • AddingDatatoaRecordsetTheRecordsetisprobablythemostusedoftheADOobjects.InADOaRecordsetisbestthoughtofasthecombinationofaresultsetfromadatasourceanditsassociatedcursorbehaviors.Thus,youcanputdataintoaRecordsetandthenusetheRecordsetmethodsandpropertiestonavigatethroughtherowsofdata,viewthevaluesintherows,andotherwisemanipulatetheresultset.

    ThissectionwillfocusonaddingdatatotheRecordset.Forinformationaboutnavigatingthroughthedataorupdatingthedata,seeChapter4:EditingDataandChapter5:UpdatingandPersistingData.YoudonotalwaysneedtheadvancedcapabilitiesofaCommandobjecttoaddyourresultsettoaRecordset.Often,youcanexecuteyourcommandbysettingtheSourcepropertyontheRecordsetorpassingacommandstringtotheRecordsetobjectOpenmethod.

    ThereareavarietyofwaystoadddatafromyourdatasourcetoaRecordset.Thetechniqueyouusedependsontheneedsofyourapplicationandthecapabilitiesofyourprovider.

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • TheRecordsetObjectOpenMethodEverythingyouneedtoopenanADORecordsetisbuiltintotheOpenmethod.Youcanuseitwithoutexplicitlycreatinganyotherobjects.Thesyntaxofthismethodisasfollows:

    recordset.OpenSource,ActiveConnection,CursorType,LockType,Options

    AllargumentsareoptionalbecausetheinformationtheypasscanbecommunicatedtoADOinotherways.However,understandingeachargumentwillhelpyoutounderstandmanyimportantADOconcepts.Thefollowingtopicswillexamineeachargumentofthismethodinmoredetail.

  • SourceandOptionsArguments

    TheSourceandOptionsargumentsappearinthesametopicbecausetheyarecloselyrelated.

    recordset.OpenSource,ActiveConnection,CursorType,LockType,Options

    TheSourceargumentisaVariantthatevaluatestoavalidCommandobject,atextcommand(e.g.,aSQLstatement),atablename,astoredprocedurecall,aURL,orthenameofafileorStreamobjectcontainingapersistentlystoredRecordset.IfSourceisafilepathname,itcanbeafullpath("C:\dir\file.rst"),arelativepath("..\file.rst"),oraURL("http://files/file.rst").YoucanalsospecifythisinformationintheRecordsetobjectSourcepropertyandleavetheSourceargumentblank.

    TheOptionsargumentisaLongvaluethatindicateseitherorbothofthefollowing:

    HowtheprovidershouldevaluatetheSourceargumentifitrepresentssomethingotherthanaCommandobject.ThattheRecordsetshouldberestoredfromafilewhereitwaspreviouslysaved.

    ThisargumentcancontainabitmaskofCommandTypeEnumorExecuteOptionEnumvalues.ACommandTypeEnumpassedintheOptionsargumentsetstheCommandTypepropertyoftheRecordset.

    NoteTheExecuteOpenEnumvaluesofadExecuteNoRecordsandadExecuteStreamcannotbeusedwithOpen.

    IftheCommandTypepropertyvalueequalsadCmdUnknown(thedefaultvalue),youmightexperiencediminishedperformance,becauseADOmustmakecallstotheprovidertodeterminewhethertheCommandTextpropertyisaSQLstatement,astoredprocedure,oratablename.Ifyouknowwhattypeofcommandyouareusing,settingtheCommandTypepropertyinstructsADOtogodirectlytotherelevantcode.IftheCommandTypepropertydoesnotmatchthetypeofcommandintheCommandTextproperty,anerroroccurswhenyoucalltheOpenmethod.

  • FormoreinformationaboutusingtheseenumeratedconstantsforOptionsandwithotherADOmethodsandproperties,seeCommandTypeEnumandExecuteOptionEnum.

  • ActiveConnectionArgument

    YoucanpassineitheraConnectionobjectoraconnectionstringastheActiveConnectionargument.

    recordset.OpenSource,ActiveConnection,CursorType,LockType,Options

    TheActiveConnectionargumentcorrespondstotheActiveConnectionpropertyandspecifiesinwhichconnectiontoopentheRecordsetobject.Ifyoupassaconnectiondefinitionforthisargument,ADOopensanewconnectionusingthespecifiedparameters.AfteropeningtheRecordsetwithaclient-sidecursor(CursorLocation=adUseClient),youcanchangethevalueofthispropertytosendupdatestoanotherprovider.OryoucansetthispropertytoNothing(inMicrosoftVisualBasic)orNULLtodisconnecttheRecordsetfromanyprovider.ChangingActiveConnectionforaserver-sidecursorgeneratesanerror,however.

    IfyoupassaCommandobjectintheSourceargumentandalsopassanActiveConnectionargument,anerroroccursbecausetheActiveConnectionpropertyoftheCommandobjectmustalreadybesettoavalidConnectionobjectorconnectionstring.

  • CursorTypeArgumentrecordset.OpenSource,ActiveConnection,CursorType,LockType,Options

    AsdiscussedinTheSignificanceofCursorLocation,thetypeofcursorthatyourapplicationuseswilldeterminewhichcapabilitiesareavailabletotheresultantRecordset(ifany).Foradetailedexaminationofcursortypes,seeChapter8:UnderstandingCursorsandLocks.

    TheCursorTypeargumentcanacceptanyoftheCursorTypeEnumvalues.

  • LockTypeArgumentrecordset.OpenSource,ActiveConnection,CursorType,LockType,Options

    SettheLockTypeargumenttospecifywhattypeoflockingtheprovidershouldusewhenopeningtheRecordset.ThedifferenttypesoflockingarediscussedinChapter8:UnderstandingCursorsandLocks.

    TheLockTypeargumentcanacceptanyoftheLockTypeEnumvalues.

  • RetrievingMultipleRecordsets

    Youmightoccasionallyneedtoexecuteacommandthatwillreturnmorethanoneresultset.AcommonexampleisastoredprocedurethatrunsagainstaSQLServerdatabase,asinthefollowingexample.ThestoredprocedurecontainsaCOMPUTEclausetoreturntheaveragepriceofallproductsinthetable.Thedefinitionofthestoredprocedureisasfollows:

    CREATEPROCEDUREProductsWithAvgPriceASSELECTProductID,ProductName,UnitPriceFROMPRODUCTSCOMPUTEAVG(UnitPrice)

    TheMicrosoftOLEDBProviderforSQLServerreturnsmultipleresultsetstoADOwhenthecommandcontainsaCOMPUTEclause.Therefore,theADOcodemustusetheNextRecordsetmethodtoaccessthedatainthesecondresultset,asshownhere:

    'BeginNextRsOnErrorGoToErrHandler:DimobjConnAsNewADODB.ConnectionDimobjCmdAsNewADODB.CommandDimobjRsAsNewADODB.Recordset

    SetobjConn=GetNewConnectionobjCmd.ActiveConnection=objConnobjCmd.CommandText="ProductsWithAvgPrice"objCmd.CommandType=adCmdStoredProcSetobjRs=objCmd.ExecuteDoWhileNotobjRs.EOFDebug.PrintobjRs(0)&vbTab&objRs(1)&vbTab&_objRs(2)objRs.MoveNextLoopSetobjRs=objRs.NextRecordsetDebug.Print"AVG.PRICE=$"&objRs(0)

  • 'cleanupobjRs.CloseobjConn.CloseSetobjRs=NothingSetobjConn=NothingSetobjCmd=NothingExitSubErrHandler:'cleanupIfobjRs.State=adStateOpenThenobjRs.CloseEndIfIfobjConn.State=adStateOpenThenobjConn.CloseEndIfSetobjRs=NothingSetobjConn=NothingSetobjCmd=NothingIfErr0ThenMsgBoxErr.Source&"-->"&Err.Description,,"Error"EndIf'EndNextRs

    Formoreinformation,seeNextRecordset.

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • Chapter3:ExaminingDataChapter2explainedhowtoretrievedatafromadatasourceasaRecordsetobject.ThischapterwilldiscusstheRecordsetinmoredetail,includinghowtonavigatethroughtheRecordsetandviewitsdata.

    ThefollowingdiagramillustratestheobjectmodeloftheRecordsetobject.Clickanobjectorcollectionformoreinformation.

    Recordsetshavemethodsandpropertiesdesignedtomakeiteasytomovethroughthemandexaminetheircontents.Dependingonthefunctionalitysupportedbytheprovider,someRecordsetmethodsorpropertiesmightnotbeavailable.TocontinueexploringtheRecordsetobject,consideraRecordsetthatwouldbereturnedfromtheNorthwindsampledatabaseonMicrosoftSQLServer2000,usingthefollowingcode:

    'BeginRsTourPublicSubRecordsetTour()OnErrorGoToErrHandler:DimobjRsAsNewADODB.RecordsetDimstrSQLAsStringstrSQL="SELECTProductID,ProductName,UnitPriceFROMProducts"&_"WHERECategoryID=7"'7=ProduceobjRs.OpenstrSQL,strConnStr,adOpenForwardOnly,_adLockReadOnly,adCmdText'CleanupobjRs.CloseSetobjRs=NothingExitSubErrHandler:IfNotobjRsIsNothingThenIfobjRs.State=adStateOpenThenobjRs.Close

  • SetobjRs=NothingEndIf

    IfErr0ThenMsgBoxErr.Source&"-->"&Err.Description,,"Error"EndIfEndSub'EndRsTour

    ThisSQLqueryreturnsaRecordsetwithfiverows(records)andthreecolumns(fields).Thevaluesforeachrowareshowninthefollowingtable.

    FIELD0Name=ProductID

    FIELD1Name=ProductName

    FIELD2Name=UnitPrice

    7 UncleBob'sOrganicDriedPears 30.000014 Tofu 23.250028 RssleSauerkraut 45.600051 ManjimupDriedApples 53.000074 LonglifeTofu 10.0000

    ThenextsectionwillexplainhowtolocatethecurrentpositionofthecursorinthissampleRecordset.

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • LocatingtheCurrentRecordThecurrentpositionofthecursorintheRecordsetdelineatesthecurrentrecordposition.Assumingthatthecommandissuedreturnsresults,thecursorisautomaticallyplacedatthefirstrecordwhentheRecordsetOpenmethodiscalled.So,withthesampleRecordset,thecursorwouldbeonthefirstrecord,"UncleBob'sOrganicDriedPears."

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • CountingRowsTheRecordCountpropertyreturnsaLongvaluethatindicatesthenumberofrecordsintheRecordset.UsetheRecordCountpropertytofindouthowmanyrecordsareinaRecordsetobject.Thepropertyreturns-1whenADOcannotdeterminethenumberofrecordsoriftheproviderorcursortypedoesnotsupportRecordCount.ReadingtheRecordCountpropertyonaclosedRecordsetcausesanerror.

    TheRecordCountpropertydependsonthecapabilitiesoftheproviderandthetypeofcursor.TheRecordCountpropertywillreturn-1foraforward-onlycursor,theactualcountforastaticorkeysetcursor,andeither-1ortheactualcountforadynamiccursor,dependingonthedatasource.

    ThesampleRecordsetintroducedinExaminingDatawouldreturn–1becauseaforward-onlycursorwasopened.InordertousetheRecordCountproperty,youwouldneedtoopentheRecordsetwithamoresophisticatedcursor(staticorkeyset).

    Incertaincases,yourproviderorcursormightbeunabletoprovidetheRecordCountvaluewithoutfirstfetchingallrecordsfromthedatasource.Toforcethistypeoffetch,calltheRecordsetMoveLastmethodbeforecallingRecordCount.

    IfyouweretoreplacethelineofcodethatcallstheRecordsetOpenmethodwiththefollowing:

    oRs.OpensSQL,sCnStr,adOpenStatic,adLockOptimistic,adCmdText

    youwouldbeabletousetheRecordCountpropertybecausestaticcursorswiththeMicrosoftOLEDBProviderforSQLServersupportRecordCount.Forexample,thefollowingcodewouldprintoutthenumberofrecordsreturnedbythecommandtothedebugwindow,assumingthecursorsupportstheRecordCountproperty:

    Debug.PrintoRs.RecordCount'Output:4

    Fromthispointforward,assumethatthesemorecapable(butmoreexpensive)

  • cursorandlocktypesettingsareused.

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • TheLimitsofaRecordsetUsetheBOFandEOFpropertiestodeterminewhetheraRecordsetobjectcontainsrecordsorwhetheryou'vegonebeyondthelimitsofaRecordsetobjectwhenyoumovefromrecordtorecord.ThinkofBOFandEOFas"phantom"recordsthatarepositionedatthebeginningandendoftheRecordset.BuildingonthesampleRecordsetfromExaminingData,itwouldnowlooklikethis:

    ProductID ProductName UnitPriceBOF

    7 UncleBob'sOrganicDriedPears 30.0000

    14 Tofu 23.250028 RssleSauerkraut 45.600051 ManjimupDriedApples 53.000074 LonglifeTofu 10.0000EOF

    TheBOFpropertyreturnsTrue(-1)ifthecurrentrecordpositionisbeforethefirstrecordandFalse(0)ifthecurrentrecordpositionisonorafterthefirstrecord.

    TheEOFpropertyreturnsTrueifthecurrentrecordpositionisafterthelastrecordandFalseifthecurrentrecordpositionisonorbeforethelastrecord.

    IfeithertheBOForEOFpropertyisTrue,thereisnocurrentrecord,asshowninthefollowingcode:

    IfoRs.BOFAndoRs.EOFThen'Commandreturnednorecords.EndIf

    IfyouopenaRecordsetobjectcontainingnorecords,theBOFandEOFpropertiesarebothsettoTrueandthevalueoftheRecordsetobject'sRecordCountpropertysettingdependsonthecursortype.-1willbereturnedfordynamiccursors(CursorType=adOpenDynamic)and0willbereturned

  • forothercursors.

    WhenyouopenaRecordsetobjectthatcontainsatleastonerecord,thefirstrecordisthecurrentrecordandtheBOFandEOFpropertiesareFalse.

    IfyoudeletethelastremainingrecordintheRecordsetobject,thecursorisleftinanindeterminatestate.TheBOFandEOFpropertiesmayremainFalseuntilyouattempttorepositionthecurrentrecord,dependingupontheprovider.

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • NavigatingThroughtheDataNowthatyouhaveexecutedacommandagainstthedatasourceanddeterminedthattheresultsetcontainsdata,youcanmovethroughtheresultsbyusingthenavigationmethodsandpropertiesprovidedbytheRecordsetobject.ThefollowingtopicsdescribehowtousethesemethodsandpropertiesonthesampleRecordset:

    JumpingtoaRecordMoreWaystoMoveinaRecordsetUsingBookmarksUsingPagesRecordsetPositioning

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • JumpingtoaRecordTheMovemethodallowsyoutomoveforwardorbackwardintheRecordsetaspecifiednumberofrecordsbyusingthefollowingsyntax:

    oRs.MoveNumRecords,Start

    TheMovemethodissupportedonallRecordsetobjects.

    IftheNumRecordsargumentisgreaterthanzero,thecurrentrecordpositionmovesforward(towardtheendoftheRecordset).IfNumRecordsislessthanzero,thecurrentrecordpositionmovesbackward(towardthebeginningoftheRecordset).

    IftheMovecallwouldmovethecurrentrecordpositiontoapointbeforethefirstrecord,ADOsetsthecurrentrecordtothepositionbeforethefirstrecordintheRecordset(BOFisTrue).AnattempttomovebackwardwhentheBOFpropertyisalreadyTruegeneratesanerror.

    IftheMovecallwouldmovethecurrentrecordpositiontoapointafterthelastrecord,ADOsetsthecurrentrecordtothepositionafterthelastrecordintheRecordset(EOFisTrue).AnattempttomoveforwardwhentheEOFpropertyisalreadyTruegeneratesanerror.

    CallingtheMovemethodfromanemptyRecordsetobjectgeneratesanerror.

    IfyoupassabookmarkintheStartargument,themoveisrelativetotherecordwiththisbookmark,assumingtheRecordsetobjectsupportsbookmarks.AbookmarkisobtainedbyusingtheBookmarkproperty.Ifnotspecified,themoveisrelativetothecurrentrecord.

    IfyouareusingtheCacheSizepropertytolocallycacherecordsfromtheprovider,passingaNumRecordsargumentthatmovesthecurrentrecordpositionoutsidethecurrentgroupofcachedrecordsforcesADOtoretrieveanewgroupofrecords,startingfromthedestinationrecord.TheCacheSizepropertydeterminesthesizeofthenewlyretrievedgroup,andthedestinationrecordisthefirstrecordretrieved.

  • ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • MoreWaystoMoveinaRecordsetThefollowingfourmethodsareusedtomovearound,orscroll,intheRecordset:MoveFirst,MoveLast,MoveNext,andMovePrevious.(Someofthesemethodsareunavailableonforward-onlycursors.)

    MoveFirstchangesthecurrentrecordpositiontothefirstrecordintheRecordset.MoveLastchangesthecurrentrecordpositiontothelastrecordintheRecordset.TouseMoveFirstorMoveLast,theRecordsetobjectmustsupportbookmarksorbackwardcursormovement;otherwise,themethodcallwillgenerateanerror.

    MoveNextmovesthecurrentrecordpositiononeplaceforward.IfyouareonthelastrecordwhenyoucallMoveNext,EOFwillbesettoTrue.MovePreviousmovesthecurrentrecordpositiononeplacebackward.IfyouareonthefirstrecordwhenyoucallMovePrevious,BOFwillbesettoTrue.ItiswisetochecktheEOFandBOFpropertieswhenusingthesemethodsandtomovethecursorbacktoavalidcurrentrecordpositionifyoumoveoffeitherendoftheRecordset,asshownhere:

    ...oRs.MoveNextIfoRs.EOFThenoRs.MoveLast...

    Or,inthecaseoftheMovePreviousmethod:

    ...oRs.MovePreviousIfoRs.BOFThenoRs.MoveFirst...

    IncaseswheretheRecordsethasbeenfilteredorsortedandthecurrentrecord'sdataischanged,thepositionmayalsochange.InsuchcasestheMoveNextmethodworksnormally,butbeawarethatthepositionismovedonerecordforwardfromthenewposition,nottheoldposition.Forexample,changingthedatainthecurrentrecord,suchthattherecordismovedtotheendofthesortedRecordset,wouldmeanthatcallingMoveNextresultsinADOsettingthecurrentrecordtothepositionafterthelastrecordintheRecordset(EOF=

  • True).

    ThebehaviorofthevariousMovemethodsoftheRecordsetobjectdepends,tosomeextent,onthedatawithintheRecordset.NewrecordsaddedtotheRecordsetareinitiallyaddedinaparticularorder,whichisdefinedbythedatasourceandmaybedependentimplicitlyorexplicitlyonthedatainthenewrecord.Forexample,ifasortorajoinisdonewithinthequerythatpopulatestheRecordset,thenewrecordwillbeinsertedintheappropriateplacewithintheRecordset.IforderingisnotexplicitlyspecifiedwhencreatingtheRecordset,changesinthedatasourceimplementationmaycausetheorderingofthereturnedrowstochangeinadvertently.Inaddition,thesorting,filtering,andeditingfunctionsoftheRecordsetcanaffecttheorderandpossiblywhichrowsintherecordsetwillbevisible.

    Therefore,MoveNext,MovePrevious,MoveFirst,MoveLast,andMoveareallsensitivetootheroperationsperformedonthesameRecordset.ADOwillalwaystrytomaintainyourcurrentpositionuntilyouexplicitlymoveit,butsometimesinterveningchangesmakeitdifficulttounderstandtheeffectsofasubsequentmove.Forexample,ifyoucallMoveFirsttopositiononthefirstrowofasortedRecordsetandyouchangethesortfromascendingordertodescendingorder,youarestillonthesamerow—butnowitisthelastrowintheRecordset.MoveFirstwilltakeyoutoadifferentrow(thenewfirstrow).

    Asanotherexample,ifyouarepositionedonaparticularrowinthemiddleofaRecordsetandyoucallDeleteandthencallMoveNext,youarenowontherecordimmediatelyfollowingthedeletedrecord.ButcallingMovePreviousmakestherecordprecedingtheoneyoudeletedthecurrentrecord,becausethedeletedrecordisnolongercountedintheactivemembershipoftheRecordset.

    Itisparticularlydifficulttodefineconsistentmovesemanticsacrossallprovidersformethodsthatmoverelativetothecurrentrecord—MovePrevious,MoveNext,andMove—inthefaceofchangingdatainthecurrentrecord.Forexample,ifyouareworkingwithasorted,filteredRecordset,andyouchangethedatainthecurrentrecordsothatitwouldprecedeallotherrecords,butyourchangeddataalsonolongermatchesthefilter,itisnotclearwhereaMoveNextoperationshouldtakeyou.ThesafestconclusionisthatrelativemovementwithinaRecordsetisriskierthanabsolutemovement(suchasusingMoveFirstorMoveLast)whenthedataischangingwhilerecordsarebeingedited,added,ordeleted.SortingandfilteringshouldbebasedonaprimarykeyorID,because

  • thistypeofvalueshouldnotchange.

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • UsingBookmarksItisoftenusefultoreturndirectlytoaspecificrecordafterhavingmovedaroundintheRecordsetwithouthavingtoscrollthrougheveryrecordandcomparevalues.Forexample,ifyouattempttosearchforarecordusingtheFindmethodbutthesearchreturnsnorecords,youareautomaticallyplacedateitherendoftheRecordset.Ifyourprovidersupportsthem,bookmarkscanbeusedtomarkyourplacebeforeusingtheFindmethodsoyoucanreturntoyourlocation.AbookmarkisaVarianttypevaluethatuniquelyidentifiesarecordinaRecordsetobject.

    YoucanalsouseavariantarrayofbookmarkswiththeRecordsetFiltermethodtofilteronaselectedsetofrecords.Fordetailsaboutthistechnique,seeFilteringtheResultsinthetopic,WorkingwithRecordsets,laterinthischapter.

    YoucanusetheBookmarkpropertytogetabookmarkforarecord,orsetthecurrentrecordinaRecordsetobjecttotherecordidentifiedbyavalidbookmark.ThefollowingcodeusestheBookmarkpropertytosetabookmarkandthenreturntothebookmarkedrecordaftermovingontootherrecords.TodetermineifyourRecordsetsupportsbookmarks,usetheSupportsmethod.

    'BeginBookmarkEgDimvarBookmarkAsVariantDimblnCanBkmrkAsBooleanobjRs.OpenstrSQL,strConnStr,adOpenStatic,adLockOptimistic,adCmdTextIfobjRs.RecordCount>4ThenobjRs.Move4'movetothefifthrecordblnCanBkmrk=objRs.Supports(adBookmark)IfblnCanBkmrk=TrueThenvarBookmark=objRs.Bookmark'recordthebookmarkobjRs.MoveLast'movetoadifferentrecordobjRs.Bookmark=varBookmark'returntothebookmarked(sixth)recordEndIfEndIf'EndBookmarkEg

    TheSupportsmethodiscoveredinmoredetaillater.

  • ExceptforthecaseofclonedRecordsets,bookmarksareuniquetotheRecordsetinwhichtheywerecreated,evenifthesamecommandisused.ThismeansthatyoucannotuseaBookmarkobtainedfromoneRecordsettomovetothesamerecordinasecondRecordsetopenedwiththesamecommand.

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • UsingPagesUsethePageCountpropertytodeterminehowmanypagesofdataareintheRecordsetobject.PagesaregroupsofrecordswhosesizeequalsthePageSizepropertysetting.EvenifthelastpageisincompletebecausetherearefewerrecordsthanthePageSizevalue,itcountsasanadditionalpageinthePageCountvalue.IftheRecordsetobjectdoesnotsupportthisproperty,PageCountwillbe-1toindicatethatthePageCountisindeterminable.

    UsethePageSizepropertytodeterminehowmanyrecordsmakeupalogicalpageofdata.EstablishingapagesizeallowsyoutousetheAbsolutePagepropertytomovetothefirstrecordofaparticularpage.ThisisusefulinWeb-serverscenarioswhenyouwanttoallowtheusertopagethroughdata,viewingacertainnumberofrecordsatatime.

    Thispropertycanbesetatanytime,anditsvaluewillbeusedforcalculatingthelocationofthefirstrecordofaparticularpage.

    UsetheAbsolutePagepropertytoidentifythepagenumberonwhichthecurrentrecordislocated.Again,theprovidermustsupporttheappropriatefunctionalityforthispropertytobeavailable.

    AbsolutePageis1-basedandequals1whenthecurrentrecordisthefirstrecordintheRecordset.Setthispropertytomovetothefirstrecordofaparticularpage.ObtainthetotalnumberofpagesfromthePageCountproperty.

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • RecordsetPositioningUsetheAbsolutePositionpropertytomovetoarecord,basedonitsordinalpositionintheRecordsetobject,ortodeterminetheordinalpositionofthecurrentrecord.Theprovidermustsupporttheappropriatefunctionalityforthispropertytobeavailable.

    AbsolutePositionis1-basedandequals1whenthecurrentrecordisthefirstrecordintheRecordset.Asmentionedpreviously,youcanobtainthetotalnumberofrecordsintheRecordsetobjectfromtheRecordCountproperty.

    WhenyousettheAbsolutePositionproperty,evenifitistoarecordinthecurrentcache,ADOreloadsthecachewithanewgroupofrecordsstartingwiththerecordyouspecified.TheCacheSizepropertydeterminesthesizeofthisgroup.

    NoteYoushouldnotusetheAbsolutePositionpropertyasasurrogaterecordnumber.Thepositionofagivenrecordchangeswhenyoudeleteaprecedingrecord.TherealsoisnoassurancethatagivenrecordwillhavethesameAbsolutePositioniftheRecordsetobjectisrequeriedorreopened.BookmarksaretherecommendedwayofretainingandreturningtoagivenpositionandaretheonlywayofpositioningacrossalltypesofRecordsetobjects.

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • UnderstandingRecordsetStructureEveryRecordsethasaFieldscollectionconsistingofoneormoreFieldobjects.AFieldobjectusuallyrepresentsatablecolumn.ThefollowingtopicswillexplainhowtonavigatethroughtheFieldscollectionandgetinformationabouteachfield.ThentheywilldiscusswhatkindofinformationisavailabletoyouviatheFieldobjectandhowtouseit.

    TheFieldsCollectionTheFieldObjectWorkingwithRecordsets

    ©1998-2003MicrosoftCorporation.Allrightsreserved.

  • ADO2.5

  • TheFieldsCollectionTheFieldscollectionisoneofADO'sintrinsiccollections.Acollectionisanorderedsetofitemsthatcanbereferredtoasaunit.FormoreinformationaboutADOcollections,seeTheADOObjectModelinChapter1.

    TheFieldscollectioncontainsaFieldobjectforeveryfield(column)intheRecordset.LikeallADOcollections,ithasCountandItemproperties,aswellasAppendandRefreshmethods.ItalsohasCancelUpdate,Delete,Resync,andUpdatemethods,whicharenotavailabletootherADOcollections.

  • ExaminingtheFieldsCollection

    ConsidertheFieldscollectionofthesampleRecordsetintroducedinthischapter.ThesampleRecordsetwasderivedfromtheSQLstatement

    SELECTProductID,ProductName,UnitPriceFROMProductsWHERECategoryID=7

    Thus,youshouldfindthattheRecordsetFieldscollectioncontainsthreefields.

    'BeginWalkFieldsDimobjFieldsAsADODB.FieldsobjRs.OpenstrSQL,strConnStr,adOpenForwardOnly,adLockReadOnly,adCmdTextSetobjFields=objRs.FieldsForintLoop=0To(objFields.Count-1)Debug.PrintobjFields.Item(intLoop).NameNext'EndWalkFields

    ThiscodesimplydeterminesthenumberofFieldobjectsintheFieldscollectionusingtheCountpropertyandloopsthroughthecollection,returningthevalueoftheNamepropertyforeachFieldobject.YoucanusemanymoreFieldpropertiestogetinformationaboutafield.FormoreinformationaboutqueryingaField,seeTheFieldObject.

  • CountingColumns

    Asyoumightexpect,theCountpropertyreturnstheactualnumberofFieldobjectsintheFieldscollection.Becausenumberingformembersofacollectionbeginswithzero,youshouldalwayscodeloopsstartingwiththezeromemberandendingwiththevalueoftheCountpropertyminus1.IfyouareusingMicrosoftVisualBasicandwanttoloopthroughthemembersofacollectionwithoutcheckingtheCountproperty,usetheForEach...Nextcommand.

    IftheCountpropertyiszero,therearenoobjectsinthecollection.

  • GettingtotheField

    AswithanyADOcollection,theItempropertyisthedefaultpropertyofthecollection.ItreturnstheindividualFieldobjectspecifiedbythenameorindexpassedtoit.Therefore,thefollowingstatementsareequivalentforthesampleRecordset:

    objField=objRecordset.Fields.Item("ProductID")objField=objRecordset.Fields("ProductID")objField=objRecordset.Fields.Item(0)objField=objRecordset.Fields(0)

    Ifthesemethodsareequivalent,whichisbest?Itdepends.UsinganindextoretrieveaFieldfromthecollectionisfasterbecauseitaccessestheFielddirectlywithouthavingtoperformastringlookup.Ontheotherhand,theorderofFieldswithinthecollectionmustbeknown,andiftheorderchanges,thereferencetotheField'sindexwillhavetobechangedwhereveritoccurs.Althoughslightlyslower,usingthenameoftheFieldismoreflexiblebecauseitdoesn'tdependontheorderoftheFieldsinthecollection.

  • UsingtheRefreshMethod

    UnlikesomeotherADOcollections,usingtheRefreshmethodontheFieldscollectionhasnovisibleeffect.Toretrievechangesfromtheunderlyingdatabasestructure,youmustuseeithertheRequerymethod,oriftheRecordsetobjectdoesnotsupportbookmarks,theMoveFirstmethod,whichwillcausethecommandtobeexecutedagainsttheprovideragain.

  • AddingFieldstoaRecordset

    TheAppendmethodisusedtoaddfieldstoaRecordset.

    YoucanusetheAppendmethodtofabricateaRecordsetprogrammaticallywithoutopeningaconnectiontoadatasource.Arun-timeerrorwilloccuriftheAppendmethodiscalledontheFieldscollectionofanopenRecordsetoron