<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>SQL Developer - Connecting Databases : OLEDB API</title><link>http://blogs.msdn.com/selvar/archive/tags/OLEDB+API/default.aspx</link><description>Tags: OLEDB API</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>OLEDB API Calls</title><link>http://blogs.msdn.com/selvar/archive/2007/11/10/oledb-api-calls.aspx</link><pubDate>Sat, 10 Nov 2007 18:22:48 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6059756</guid><dc:creator>selvar</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/selvar/comments/6059756.aspx</comments><wfw:commentRss>http://blogs.msdn.com/selvar/commentrss.aspx?PostID=6059756</wfw:commentRss><description>&lt;p&gt;&lt;a name="_Toc423269299"&gt;&lt;strong&gt;What is OLE DB?&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;OLE DB is a specification&lt;/b&gt;. It is not a set of components or files. It defines the way that a consumer, the client who is retrieving the data, talks to a provider, the server who is supplying the data. The provider is a COM object which is created by calling &lt;b&gt;CoCreateInstance()&lt;/b&gt; . After creating an instance of the provider, the consumer than talks to the provider using the OLE DB defined interfaces. These interfaces are acquired by calling QueryInterface().&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/selvar/WindowsLiveWriter/OLEDBAPICalls_125AF/clip_image002_2.jpg"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="334" alt="clip_image002" src="http://blogs.msdn.com/blogfiles/selvar/WindowsLiveWriter/OLEDBAPICalls_125AF/clip_image002_thumb.jpg" width="441" border="0" /&gt;&lt;/a&gt;    &lt;br /&gt;Here is a diagram showing the objects exposed by OLE DB:&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Figure &lt;/b&gt;&lt;b&gt;1&lt;/b&gt;&lt;b&gt; &amp;#8211; OLE DB Object Model&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&amp;#183; &lt;b&gt;Enumerators&lt;/b&gt;. Enumerators search for available data sources and other enumerators. Consumers that are not customized for a particular data source use enumerators to search for a data source to use.&lt;/p&gt;  &lt;p&gt;&amp;#183; &lt;b&gt;Data Source Objects&lt;/b&gt;. Data source objects contain the machinery to connect to a data source, such as a file or a DBMS. They are a factory for sessions.&lt;/p&gt;  &lt;p&gt;&amp;#183; &lt;b&gt;Sessions.&lt;/b&gt; Sessions provide a context for transactions and can be implicitly or explicitly transacted. A single data source object can create multiple sessions. Sessions are a factory for transactions, commands, and rowsets.&lt;/p&gt;  &lt;p&gt;&amp;#183; &lt;b&gt;Transactions&lt;/b&gt;. Transaction objects are used when committing or aborting nested transactions at other than the lowest level.&lt;/p&gt;  &lt;p&gt;&amp;#183; &lt;b&gt;Commands&lt;/b&gt;. Commands execute a text command, such as an SQL statement. If the text command specifies a rowset, such as an SQL SELECT statement, the command is a factory for the rowset. A single session can create multiple commands.&lt;/p&gt;  &lt;p&gt;&amp;#183; &lt;b&gt;Rowsets&lt;/b&gt;. Rowsets expose data in tabular format. A special case of a rowset is an index. Rowsets can be created from the session or the command.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;i&gt;The only object which gets created using the OLE function CoCreateInstance()&lt;/i&gt;&lt;/b&gt; &lt;b&gt;&lt;i&gt;function is the Data Source object which is classified as the OLE DB Provider&lt;/i&gt;&lt;/b&gt;. It is given a CLSID and ProgID. No other OLE DB objects shown above have a CLSID or ProgID as they are not creatable COM Classes (CoClasses). &lt;b&gt;&lt;i&gt;The remaining OLE DB objects are created by calling methods of an interface like IDBCreateSession::CreateSession() and IDBCreateCommand::CreateCommand().&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;  &lt;h4&gt;A Walk Through Using OLE DB&lt;/h4&gt;  &lt;p&gt;To better understand how OLE DB works and how the objects are created and used, this section will walk through the steps of traversing data supplied by an OLE DB Provider.&lt;/p&gt;  &lt;p&gt;1. Create an instance of the OLE DB Provider by calling the appropriate COM functions such as CoCreateInstance(). Request one of the interfaces of the data source object such as IDBInitialize or IDBProperties.&lt;/p&gt;  &lt;p&gt;2. Get information about the data source or set the data source properties. Finally, call IDBInitialize::Initialize().&lt;/p&gt;  &lt;p&gt;3. Create a Session object from the data source object and possibly start a transaction.&lt;/p&gt;  &lt;p&gt;4. Create a rowset immediately if there are no commands needs to access the data or create a command object. One example where a rowset could be created immediately is when a data source object is fed the property of a text file and no other information is needed to read the file. The provider could simply support the creation of the rowset immediately without having to receive a command. This is done through the OLE DB interface IOpenRowset which is a interface of the Session object. If a command is necessary, the Session object is queried for the IDBCreateCommand interface and IDBCreateCommand::CreateCommand is called. In the call to CreateCommand() the programmer specifies which interface of the command object to retrieve.&lt;/p&gt;  &lt;p&gt;5. In the command object, set the command text by calling ICommandText::SetCommandText().&lt;/p&gt;  &lt;p&gt;6. Set the properties of the rowset that will be retrieved by using the ICommandProperties::SetProperties(). Some of these properties determine updatability, scrollablity, and whether or not the cursor will be a server-side cursor.&lt;/p&gt;  &lt;p&gt;7. Create OLE DB accessors for any parameters which will be used in the command.&lt;/p&gt;  &lt;p&gt;8. Call ICommand::Execute() to retrieve the rowset and get back an interface to the rowset.&lt;/p&gt;  &lt;p&gt;9. Create an accessor for the returned rowset&lt;/p&gt;  &lt;p&gt;10. Move through the rowset using GetNextRows() to retrive the handles to the rowset rows.&lt;/p&gt;  &lt;p&gt;11. Call IRowset::GetData() using the accessor to retrieve the data of the current record.&lt;/p&gt;  &lt;p&gt;12. Retrieve all of the data and be sure to free all of the handles (row and accessor).&lt;/p&gt;  &lt;p&gt;13. Release all of the interfaces of the OLE DB objects. This will unload the OLE DB Provider.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6059756" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/selvar/archive/tags/OLEDB+API/default.aspx">OLEDB API</category></item><item><title>OLE DB Resource Pooling</title><link>http://blogs.msdn.com/selvar/archive/2007/11/10/ole-db-resource-pooling.aspx</link><pubDate>Sat, 10 Nov 2007 15:04:02 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6053268</guid><dc:creator>selvar</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/selvar/comments/6053268.aspx</comments><wfw:commentRss>http://blogs.msdn.com/selvar/commentrss.aspx?PostID=6053268</wfw:commentRss><description>&lt;p&gt;OLE DB resource pooling, also known as OLE DB session pooling, is handled by the OLE DB core components. To take advantage of resource pooling, an OLE DB consumer must invoke the data provider by using either the &lt;b&gt;IDataInitialize&lt;/b&gt; or the &lt;b&gt;IDBPromptInitialize&lt;/b&gt; interface. (ADO will attempt to do this automatically.) OLE DB resource pooling can be turned on for one provider and off for another.&lt;/p&gt;  &lt;blockquote&gt;&lt;b&gt;Note&lt;/b&gt;&amp;#160;&amp;#160; Performing &lt;b&gt;CoCreateInstance&lt;/b&gt; on &lt;b&gt;IDBInitialize&lt;/b&gt; is traditionally used in OLE DB to open a data source object. To use resource pooling, you perform &lt;b&gt;CoCreateInstance&lt;/b&gt; on either &lt;b&gt;IDataInitialize&lt;/b&gt; or &lt;b&gt;IDBPromptInitialize&lt;/b&gt;. Both interfaces are part of the OLE DB service components and not your OLE DB data provider. You can use &lt;b&gt;IDataInitialize&lt;/b&gt; and &lt;b&gt;IDBPromptInitialize&lt;/b&gt; to retrieve an instance of &lt;b&gt;IDBInitialize&lt;/b&gt; from your data provider so that the service components can be used. The two interfaces make it possible to use service component features such as pooling, transaction enlistment, and the Client Cursor Engine. &lt;/blockquote&gt;  &lt;p&gt;When the application creates an OLE DB data source object (via ADO or an OLE DB consumer), OLE DB services query the data provider for supported information and provide a proxy data source object to the application. To the consuming application, this proxy data source object looks like any other data source object, but in this case setting properties merely caches the information in the local proxy. When the application calls &lt;b&gt;IDBInitialize::Initialize&lt;/b&gt; in OLE DB or opens a connection in ADO, the proxy data source object checks whether any connections already exist that match the specified connection information and are not in use. If so, rather than creating a new object, setting properties, and establishing a new connection to the database, the proxy data source object uses the existing initialized data source object. When the application releases the data source object, it is returned to the pool. Any data source object that is released by the application and not reused after 60 seconds is automatically released from the pool.&lt;/p&gt;  &lt;p&gt;Figure 4 shows how OLE DB resource pooling works.&lt;/p&gt;  &lt;p&gt;&lt;img alt="" src="http://msdn2.microsoft.com/ms810829.pooling2_04(en-us,MSDN.10).gif" border="0" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Figure 4. The Benefits of OLE DB Resource Pooling &lt;/b&gt;&lt;/p&gt;  &lt;blockquote&gt;&lt;b&gt;Note&lt;/b&gt;&amp;#160;&amp;#160; The term &lt;i&gt;resource pooling&lt;/i&gt; is actually something of a misnomer. It implies that any kind of resource can be pooled, when in fact OLE DB resource pooling is just for the pooling of an OLE DB data source proxy object (DPO). Resource pooling does use the resource dispenser found with Microsoft Transaction Server, which is a more generic form of pool manager. More than a few OLE DB users have been confused by the term &amp;quot;resource pooling&amp;quot; into thinking that it pools more than it actually does.&lt;/blockquote&gt;  &lt;blockquote&gt;&lt;b&gt;Note&amp;#160;&amp;#160; &lt;/b&gt;Most of the functionality of Microsoft Transaction Server has been incorporated into Windows Component Services for Microsoft Windows 2000 and XP. References to Microsoft Transaction Server in this article may not reflect the equivalent behavior with Windows Component Services. If you are using Windows 2000 or XP, see your operating system documentation for more information.&lt;/blockquote&gt;  &lt;h5&gt;Configuring OLE DB Resource Pooling&lt;/h5&gt;  &lt;p&gt;By default, service components are enabled for all Microsoft OLE DB providers if the provider is invoked by &lt;b&gt;IDataInitialize &lt;/b&gt;or&lt;b&gt; IDBPromptInitialize&lt;/b&gt; and if the provider is marked to work with pooling by using the OLEDB_Services registry key.&lt;/p&gt;  &lt;p&gt;You can control pooling from your application in the following three ways: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;You can disable pooling for an individual provider through the registry. &lt;/li&gt;    &lt;li&gt;If you write directly to the OLE DB API, you can control pooling through the properties you set when connecting to the database. &lt;/li&gt;    &lt;li&gt;You can control pooling from your connection string. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The time-out value is set to 60 seconds; this value cannot be configured in OLE DB resource pooling prior to the release of MDAC 2.5.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Retry Wait&lt;/b&gt; works much differently in resource pooling than in ODBC connection pooling. After the server has been determined to be unavailable, resource pooling blocks the pool. The next retry for a valid connection on the server occurs after one minute. If this attempt fails, the next retry occurs after two minutes, and again after five minutes. Thereafter, the retry occurs every five minutes until a valid connection is returned.&lt;/p&gt;  &lt;h6&gt;Configuring Resource Pooling from the Registry&lt;/h6&gt;  &lt;p&gt;To determine whether individual core components can be invoked to satisfy extended functionality requested by the consumer, OLE DB compares the properties specified by the consumer to those supported by the provider. Table 2 lists values that can exist in the OLEDB_Services registry entry, which should be created during installation of the provider.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Table 2. Setting OLE DB_Services Registry Entry Under Provider's CLSID&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Default services enabled&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DWORD value&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;All services (the default)&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 0xffffffff&lt;/p&gt;  &lt;p&gt;All services except pooling&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 0xfffffffe&lt;/p&gt;  &lt;p&gt;All services except pooling and auto-enlistment&amp;#160;&amp;#160;&amp;#160;&amp;#160; 0xfffffffc&lt;/p&gt;  &lt;p&gt;All services except client cursor&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 0xfffffffb&lt;/p&gt;  &lt;p&gt;All services except client cursor and pooling&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 0xfffffffa&lt;/p&gt;  &lt;p&gt;No services&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 0x00000000&lt;/p&gt;  &lt;p&gt;No aggregation, all services disabled&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; No OLEDB_Services registry entry&lt;/p&gt;  &lt;p&gt;With the release of MDAC 2.5, you can configure both connection time-out and the &lt;b&gt;Retry Wait&lt;/b&gt; values by using the registry. &lt;/p&gt;  &lt;p&gt;When set under a provider's CLSID entry in the registry, the &lt;b&gt;SPTimeout&lt;/b&gt; value controls the length of time, in seconds, that unused sessions are held in the pool. &lt;b&gt;SPTimeout&lt;/b&gt; should be entered as a &lt;b&gt;DWORD&lt;/b&gt; value under HKEY_CLASSES_ROOT/CLSID/&lt;i&gt;ClassID&lt;/i&gt; where &lt;i&gt;ClassID&lt;/i&gt; is the CLSID of the OLE DB provider. The default &lt;b&gt;SPTimeout&lt;/b&gt; value is 60 seconds.&lt;/p&gt;  &lt;p&gt;The &lt;b&gt;Retry Wait&lt;/b&gt; value controls the length of time, in seconds, to wait between connection attempts. It is entered as a DWORD value under HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/DataAccess/Session Pooling. The default &lt;b&gt;SPTimeout&lt;/b&gt; value is 60 seconds.&lt;/p&gt;  &lt;h6&gt;Configuring resource pooling from your application&lt;/h6&gt;  &lt;p&gt;If you write directly to the OLE DB API, you can set the DBPROP_INIT_OLEDBSERVICES property to enable or disable various core components, including OLE DB resource pooling. There is no way to configure connection time-out or &lt;b&gt;Retry Wait&lt;/b&gt; programmatically in your application except by manipulating the registry entries directly. It is best not to have any services or applications using OLE DB when you make these changes, or the effects might not show up right away.&lt;/p&gt;  &lt;p&gt;Table 3 lists values and the services enabled or disabled by the value settings. Code Example 2 is an excerpt of code that uses resource pooling in an OLE DB consumer.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Table 3. Setting OLE DB Services by Using the DBPROP_INIT_OLEDBSERVICES Property&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Services enabled&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Property value&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;All services&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DBPROPVAL_OS_ENABLEALL&lt;/p&gt;  &lt;p&gt;All services except pooling&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (DBPROPVAL_OS_ENABLEALL &amp;amp; ~DBPROPVAL_OS_RESOURCEPOOLING)&lt;/p&gt;  &lt;p&gt;All services except pooling and auto-enlistment&amp;#160;&amp;#160; (DBPROPVAL_OS_ENABLEALL    &lt;br /&gt;&amp;amp; ~DBPROPVAL_OS_RESOURCEPOOLING &amp;amp; ~DBPROPVAL_OS_TXNENLISTMENT)&lt;/p&gt;  &lt;p&gt;All services except client cursor&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (DBPROPVAL_OS_ENABLEALL    &lt;br /&gt;&amp;amp; ~DBPROPVAL_OS_CLIENTCURSOR)&lt;/p&gt;  &lt;p&gt;All services except client cursor and pooling&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (DBPROPVAL_OS_ENABLEALL    &lt;br /&gt;&amp;amp; ~DBPROPVAL_OS_RESOURCEPOOLING &amp;amp; ~DBPROPVAL_OS_CLIENTCURSOR)&lt;/p&gt;  &lt;p&gt;No services&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ~DBPROPVAL_OS_ENABLEALL&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Code Example 2: OLE DB Consumer Code Using Pooling&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;long OLEDBConnect( char&amp;#160;&amp;#160; *lpszInitString,   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; bool&amp;#160;&amp;#160;&amp;#160; bUsePooling,&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Flag to set pooling     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ULONG&amp;#160;&amp;#160; nCount )    &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160; IDataInitialize&amp;#160;&amp;#160; *pIDataInitialize = NULL;    &lt;br /&gt;&amp;#160;&amp;#160; IDBProperties&amp;#160;&amp;#160;&amp;#160;&amp;#160; *pDBProperties&amp;#160;&amp;#160;&amp;#160; = NULL;    &lt;br /&gt;&amp;#160;&amp;#160; IDBInitialize&amp;#160;&amp;#160;&amp;#160;&amp;#160; *pIDBInit&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; = NULL;    &lt;br /&gt;&amp;#160;&amp;#160; HRESULT&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; hr&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; = S_OK;    &lt;br /&gt;&amp;#160;&amp;#160; WCHAR&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; wszInitString[1024];    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160; AtoU( lpszInitString, &amp;amp;wszInitString[0], 1024 );    &lt;br /&gt;&amp;#160;&amp;#160; hr = CoCreateInstance(CLSID_MSDAINITIALIZE,     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; NULL,     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CLSCTX_INPROC_SERVER,     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; IID_IDataInitialize,    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (void**)&amp;amp;pIDataInitialize);    &lt;br /&gt;&amp;#160;&amp;#160; for (ULONG i=0;i&amp;lt;nCount &amp;amp;&amp;amp; SUCCEEDED( hr ); i++)    &lt;br /&gt;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; hr=pIDataInitialize-&amp;gt;GetDataSource(NULL,    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CLSCTX_INPROC_SERVER,    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; wszInitString,    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; IID_IDBInitialize,    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (IUnknown**)&amp;amp;pIDBInit);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (pIDBInit)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; hr=pIDBInit-&amp;gt;Initialize();    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if ( bUsePooling == false )    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (pIDBInit)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pIDBInit-&amp;gt;Uninitialize();&amp;#160;&amp;#160; // Disables Pooling(!)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (pIDBInit) pIDBInit-&amp;gt;Release();&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pIDBInit = NULL;    &lt;br /&gt;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160; if (pIDataInitialize)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pIDataInitialize-&amp;gt;Release();    &lt;br /&gt;&amp;#160;&amp;#160; return 0;    &lt;br /&gt;}    &lt;br /&gt;&lt;/p&gt;  &lt;blockquote&gt;&lt;b&gt;Note&lt;/b&gt;&amp;#160;&amp;#160; One of the key points to note in the preceding code is that if you call &lt;b&gt;IDBInitialize::Uninitialize&lt;/b&gt;, you will turn off pooling! To release a connection, use &lt;b&gt;IDBInitialize::Release &lt;/b&gt;instead.&lt;/blockquote&gt;  &lt;p&gt;The OLE DB property DBPROP_INIT_OLEDBSERVICES maps directly to a connection string attribute, OLE DB Services, as shown in Table 4. Code Example 3 demonstrates this.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Table 4. Setting OLE DB Services by Using ADO Connection String Attributes&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Services enabled&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Value in connection string&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;All services (the default)&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;OLE DB Services = -1;&amp;quot;&lt;/p&gt;  &lt;p&gt;All services except pooling&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;OLE DB Services = -2;&amp;quot;&lt;/p&gt;  &lt;p&gt;All services except pooling and auto-enlistment&amp;#160;&amp;#160; &amp;quot;OLE DB Services = -4;&amp;quot;&lt;/p&gt;  &lt;p&gt;All services except client cursor&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;OLE DB Services = -5;&amp;quot;&lt;/p&gt;  &lt;p&gt;All services except client cursor and pooling&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;OLE DB Services = -6;&amp;quot;&lt;/p&gt;  &lt;p&gt;No services&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;OLE DB Services = 0;&amp;quot;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Code Example 3: ADO Consumer Code Using Pooling&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;'This will take advantage of resource pooling.   &lt;br /&gt;Dim i As Integer    &lt;br /&gt;Dim cnn As New ADODB.Connection    &lt;br /&gt;Dim rst As ADODB.Recordset    &lt;br /&gt;    &lt;br /&gt;cnn.Open &amp;quot;DSN=LocalServer;UID=MyUserName;PWD=MyPassword; &amp;quot; &amp;amp; _    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;OLE DB Services=-1&amp;quot;    &lt;br /&gt;For i = 1 To 100    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set rst = New ADODB.Recordset    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; rst.Open &amp;quot;SELECT * FROM Authors&amp;quot;, cnn    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set rst = Nothing    &lt;br /&gt;Next i    &lt;br /&gt;    &lt;br /&gt;cnn.Close    &lt;br /&gt;Set cnn = Nothing    &lt;br /&gt;&lt;/p&gt;  &lt;h5&gt;Enabling OLE DB Resource Pooling&lt;/h5&gt;  &lt;p&gt;Resource pooling can be enabled in several ways: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Automatically, when a consumer accesses a provider from within Microsoft Transaction Server or Internet Information Services 4.0 or later. &lt;/li&gt;    &lt;li&gt;For an OLE DB-based consumer, by using the &lt;b&gt;IDataInitialize&lt;/b&gt; or &lt;b&gt;IDBPromptInitialize&lt;/b&gt; interface. If you use &lt;b&gt;IDataInitialize::CreateDBInstance&lt;/b&gt;, you can enable or disable services components by using the DBPROP_INIT_OLEDBSERVICES property. &lt;/li&gt;    &lt;li&gt;For an ADO-based consumer, by keeping one open instance of a &lt;b&gt;Connection&lt;/b&gt; object for each unique user and using the OLEDB_SERVICES connection string attribute to enable or disable pooling. By default, ADO attempts to use pooling, but if you do not keep at least one instance of a &lt;b&gt;Connection&lt;/b&gt; object open for each user, there will not be a persistent pool available to your application. (However, Microsoft Transaction Server keeps pools persistent as long as the connections in them have not been released and have not eventually timed out.) &lt;/li&gt; &lt;/ul&gt;  &lt;blockquote&gt;&lt;b&gt;Note&lt;/b&gt;&amp;#160;&amp;#160; Pooling will not be enabled if you call &lt;b&gt;CoCreateInstance&lt;/b&gt; directly on the CLSID of the data provider.&lt;/blockquote&gt;  &lt;h5&gt;Determining the Number of Available Pools&lt;/h5&gt;  &lt;p&gt;In OLE DB resource pooling, the following formula determines the number of pools (&lt;strong&gt;where &lt;i&gt;N&lt;/i&gt; is the number of pools, &lt;i&gt;P&lt;/i&gt; is the number of processors, and &lt;i&gt;C&lt;/i&gt; is the number of distinct sets of connection attributes on the system&lt;/strong&gt;):&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;i&gt;N&lt;/i&gt; = (&lt;i&gt;P&lt;/i&gt; + 1) * &lt;i&gt;C&lt;/i&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Using this formula, OLE DB resource pooling eliminates lock contentions on the pools.&lt;/p&gt;  &lt;blockquote&gt;&lt;b&gt;Note&amp;#160;&amp;#160; &lt;/b&gt;&lt;i&gt;P&lt;/i&gt;+1 is a default value which can be overridden by setting the following registry key:    &lt;br /&gt;CLSID\{2206CDB0-19C1-11D1-89E0-00C04FD7A829}\Holders. &lt;/blockquote&gt;  &lt;p&gt;OLE DB resource pooling keeps a map of which pools contain which users. From there, it is possible to jump to the right pool and start looking for an available connection. With OLE DB resource pooling, a given pool contains connections only for a single provider with a specific set of connection attributes. In other words, each pool contains only connections to one set of credentials and one data store. As a result, a new pool will be created for each user if a user is connecting using Windows Authentication. &lt;/p&gt;  &lt;h5&gt;Writing Data Consumers That Work With OLE DB Services&lt;/h5&gt;  &lt;p&gt;When developing an application using either ADO or native OLE DB, the following tips will help you to enable resource pooling or to avoid inadvertently disabling it. These rules apply whether you use ADO, OLE DB consumer templates, or native OLE DB code.&lt;/p&gt;  &lt;h6&gt;Tips for ADO Users&lt;/h6&gt;  &lt;ul&gt;   &lt;li&gt;The ADO &lt;b&gt;Connection&lt;/b&gt; object implicitly uses &lt;b&gt;IDataInitialize&lt;/b&gt;. However, this means your application needs to keep at least one instance of a &lt;b&gt;Connection&lt;/b&gt; object instantiated for each unique user&amp;#8212;at all times. Otherwise, the pool will be destroyed when the last &lt;b&gt;Connection &lt;/b&gt;object for that string is closed. (The exception to this is if you use Microsoft Transaction Server. In this case, the pool is destroyed only if all of the connections in the pool have been closed by client applications and are allowed to time out.)       &lt;blockquote&gt;&lt;b&gt;Note&lt;/b&gt;&amp;#160;&amp;#160; If you open a &lt;b&gt;Connection&lt;/b&gt; object, remember to close it. Do not rely on garbage collection to implicitly close your connections.&lt;/blockquote&gt;   &lt;/li&gt;    &lt;li&gt;By avoiding connection creep (discussed in section &amp;quot;Connection Creep and Effective Server Tracing&amp;quot; later in this article), you can also help your application use pooling. &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Tips for OLE DB Users&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Use &lt;b&gt;IDataInitialize&lt;/b&gt; or &lt;b&gt;IDBPromptInitialize&lt;/b&gt; to create an instance of your data provider. As long as one instance of either interface exists, a pool is available to your application. Otherwise, the pool will be destroyed. &lt;/li&gt;    &lt;li&gt;Do not request provider-specific interfaces prior to connecting. &lt;/li&gt;    &lt;li&gt;Do not request prompting. &lt;/li&gt;    &lt;li&gt;Do not use &lt;b&gt;IDBInitialize::Uninitialize&lt;/b&gt;. Use &lt;b&gt;IDBInitialize::Release&lt;/b&gt; instead. If you call &lt;b&gt;Uninitialize&lt;/b&gt;, the connection you were using will be flushed from the pool. This is because the user can change the properties of the connection after calling &lt;b&gt;Uninitialize&lt;/b&gt;. &lt;/li&gt;    &lt;li&gt;Do not release your last instance of &lt;b&gt;IDataInitialize&lt;/b&gt; or &lt;b&gt;IDBPromptInitialize&lt;/b&gt; while pooling is needed by your application. &lt;/li&gt;    &lt;li&gt;Use only one resource per connection. &lt;/li&gt;    &lt;li&gt;By avoiding connection creep (discussed below), you also help your application use pooling. &lt;/li&gt; &lt;/ul&gt;  &lt;h5&gt;Writing Data Providers That Work with OLE DB Services&lt;/h5&gt;  &lt;p&gt;As mentioned above, ADO attempts to use or enable services implicitly by referencing the OLEDB_Services registry value when a connection is established. However, some older providers may not be able to support services. Simply creating this registry entry is not enough to enable services for your application. The data provider must support certain features or services will not work. Attempting to use services with a data provider that does not offer this functionality can create unexpected behavior in your application. Following is a brief list of the functionality a data provider must support for your consumer application to utilize services: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The provider must support aggregation of all objects. &lt;/li&gt;    &lt;li&gt;Providers must support the free-threaded model or, at a minimum, the rental-threaded model. Services will determine the data provider's thread model by using the DBPROP_DSOTHREADMODEL property. &lt;/li&gt;    &lt;li&gt;If the provider has a global connection state that may change while the data source object is in an initialized state, it should support the DBPROP_RESETDATASOURCE property. &lt;/li&gt;    &lt;li&gt;Providers that connect to a remote database and can detect whether that connection has been lost should support the DBPROP_CONNECTIONSTATUS property. This allows pooling to detect dead connections and to ensure that they are not returned to the pool. &lt;/li&gt;    &lt;li&gt;Providers should support both pooling and transaction enlistment by using the DBPROP_INIT_OLEDBSERVICES property. The values used with this property also correspond to the OLEDB_Services registry key. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;For more information, consult either the OLE DB Readme file that shipped with the Data Access 2.0 SDK or the OLE DB Services section in the documentation with version 2.1 and later of the SDK.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6053268" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/selvar/archive/tags/OLEDB+API/default.aspx">OLEDB API</category></item><item><title>ADO Overview and Architecture</title><link>http://blogs.msdn.com/selvar/archive/2007/11/10/ado-overview-and-architecture.aspx</link><pubDate>Sat, 10 Nov 2007 14:53:36 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6052963</guid><dc:creator>selvar</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/selvar/comments/6052963.aspx</comments><wfw:commentRss>http://blogs.msdn.com/selvar/commentrss.aspx?PostID=6052963</wfw:commentRss><description>&lt;p&gt;ADO is the most popular and well-known of Microsoft&amp;#8217;s Data Access API&amp;#8217;s. ADO is, like OLEDB, a COM object model for accessing, retrieving and updating data. Unlike OLE DB, however, ADO objects expose OLE Automation interfaces, allowing them to be accessed not only from C++, but also languages such as Visual Basic, and even from scripting languages like VBScript on ASP pages. ADO is also the easiest of the API&amp;#8217;s to program against, as it provides a great deal of flexibility in how to do many operations, and the object model is relatively simple. &lt;/p&gt;  &lt;p&gt;Behind the scenes, the &lt;strong&gt;ADO objects act as an OLE DB consumer&lt;/strong&gt;. When you use ADO in your application, you are using &lt;strong&gt;OLE DB implicitly&lt;/strong&gt;. ADO applications therefore must specify what OLE DB provider they wish to use. ADO uses the concept of connection strings similar to ODBC. The connection strings created through OLE DB data links can be used in ADO. &lt;/p&gt;  &lt;p&gt;As with any OLE DB consumer, ADO can load any provider it wishes (although some providers may not support interfaces which ADO requires). This means that ADO can access data not only through data source specific providers, but also through ODBC drivers via MSDASQL. In fact, &lt;strong&gt;&lt;em&gt;if in your ADO connection string you only specify what DSN to use, you will by default load the MSDASQL provider and connect to the data source specified in the DSN.&lt;/em&gt;&lt;/strong&gt; For example, your connection string could look like:&lt;/p&gt;  &lt;p&gt;&amp;#8220;DSN=MyTestDSN1&amp;#8221;&lt;/p&gt;  &lt;p&gt;Remember, however, that going through MSDASQL to reach a data source for which an OLE DB provider exists is not the best solution. Therefore, for instance, if you are using ADO to talk to SQL Server you should not specify a DSN in the connection string as this implies you want to load MSDASQL, when in fact you should be using the SQL Server OLE DB provider.&lt;/p&gt;  &lt;p&gt;The following diagram shows the basic flow of an application connecting to SQL Server via ADO:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/selvar/WindowsLiveWriter/ADOOverviewandArchitecture_F48B/clip_image001_2.gif"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="492" alt="clip_image001" src="http://blogs.msdn.com/blogfiles/selvar/WindowsLiveWriter/ADOOverviewandArchitecture_F48B/clip_image001_thumb.gif" width="533" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6052963" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/selvar/archive/tags/OLEDB+API/default.aspx">OLEDB API</category></item><item><title>MSDASQL - OLEDB Provider for ODBC drivers</title><link>http://blogs.msdn.com/selvar/archive/2007/11/10/msdasql-oledb-provider-for-odbc-drivers.aspx</link><pubDate>Sat, 10 Nov 2007 14:43:52 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6052740</guid><dc:creator>selvar</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/selvar/comments/6052740.aspx</comments><wfw:commentRss>http://blogs.msdn.com/selvar/commentrss.aspx?PostID=6052740</wfw:commentRss><description>&lt;p&gt;As mentioned before, a provider is needed for any data source that is to be exposed through OLE DB. Microsoft releases providers for several common data sources, including SQL Server, Oracle, and Jet. In addition, Microsoft ships a special provider called the &amp;#8220;OLE DB Provider for ODBC Drivers&amp;#8221;. This was the very first OLE DB provider ever released, and is also known as &amp;#8220;MSDASQL&amp;#8221;, due to the fact that it is contained in &amp;#8220;MSDASQL.DLL&amp;#8221;.&lt;/p&gt;  &lt;p&gt;MSDASQL allows OLE DB consumer applications to utilize ODBC drivers to connect to a data source. The provider converts incoming OLE DB calls into ODBC calls, and passes them on to the specified ODBC driver. It then retrieves results from the ODBC driver and formats those into OLE DB specific structures which the consumer then has access to. &lt;/p&gt;  &lt;p&gt;The following diagram shows the flow of connecting to a SQL Server database through the MSDASQL provider and SQL Server ODBC driver.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/selvar/WindowsLiveWriter/MSDASQLOLEDBProviderforODBCdrivers_F215/clip_image001_2.gif"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="489" alt="clip_image001" src="http://blogs.msdn.com/blogfiles/selvar/WindowsLiveWriter/MSDASQLOLEDBProviderforODBCdrivers_F215/clip_image001_thumb.gif" width="623" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;OLE DB Flow with MSDASQL&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;MSDASQL was written because at the time OLE DB was first released, very few data sources were exposed through OLE DB providers. The MSDASQL provider allowed OLE DB applications to be able to talk to data sources for which providers had not yet been written. However, as with any scenario where you increase the length of the code path to complete an operation, talking to a data source via MSDASQL is slower than talking directly with a data source specific provider. We should recommend that customers use data source specific providers wherever possible. In addition, &lt;strong&gt;&lt;em&gt;MSDASQL is becoming deprecated&lt;/em&gt;&lt;/strong&gt;. &lt;strong&gt;&lt;em&gt;It will not be ported to 64 bit platforms, and will not receive any feature enhancements in future releases.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6052740" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/selvar/archive/tags/OLEDB+API/default.aspx">OLEDB API</category></item><item><title>OLE DB Programming Overview and Architecture</title><link>http://blogs.msdn.com/selvar/archive/2007/11/10/ole-db-programming-overview-and-architecture.aspx</link><pubDate>Sat, 10 Nov 2007 14:36:50 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6052550</guid><dc:creator>selvar</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/selvar/comments/6052550.aspx</comments><wfw:commentRss>http://blogs.msdn.com/selvar/commentrss.aspx?PostID=6052550</wfw:commentRss><description>&lt;p&gt;OLE DB is a COM based object model used for access to various relational data sources as well as structured, not relational data (such as folders in an email store, or a file system). This ability to access both relational and structured data is one of the major features that sets OLE DB apart from ODBC. However, there are many more differences between the two API&amp;#8217;s. OLE DB was developed as a successor to ODBC, and has continued to gain increasing importance as the core of Microsoft&amp;#8217;s data access strategy. (Although with the release of .NET, OLE DB&amp;#8217;s importance has diminished some to being only the core of the unmanaged, or native, environment.) Both ODBC and OLE DB API&amp;#8217;s provide very fast access to data. Although benchmark results vary from test to test, generally OLE DB and ODBC perform similarly well in most tasks.&lt;/p&gt;  &lt;p&gt;The fundamental concepts of OLE DB are that of the &lt;i&gt;Consumer&lt;/i&gt; and the &lt;i&gt;Provider&lt;/i&gt;. In a general sense, consumers are applications or components which take and use data from a data source. A provider is a piece of software which works to present data to consumers. The ODBC equivalent of an OLE DB provider is the driver. In OLE DB, providers are written for each individual data source, as ODBC drivers are also written for each data source. An OLE DB provider exposes data to an OLE DB consumer. The architecture of the consumer-provider system is quite flexible, and in some cases a consumer can talk to a provider, which itself acts as a consumer to another provider, and so on. However, most of the time a data source is exposed by a single provider with which the consumer, usually a client application, communicates. The diagram below shows the standard flow of communication in OLE DB, in this example from a client application to a SQL Server database.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/selvar/WindowsLiveWriter/OLEDBProgrammingOverviewandArchitecture_F0CE/clip_image001%5B4%5D.gif"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="606" alt="clip_image001[4]" src="http://blogs.msdn.com/blogfiles/selvar/WindowsLiveWriter/OLEDBProgrammingOverviewandArchitecture_F0CE/clip_image001%5B4%5D_thumb.gif" width="313" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The &lt;i&gt;OLE DB Service Components &lt;/i&gt;is a set of services provided in OLEDB32.DLL. The service components are frequently loaded along with a data provider by OLE DB consumers. The OLE DB Service Components (also known as Core Services) provide such facilities as pooling and the data links, which is discussed next. Loading the service components is also necessary to use client side cursors, which is also discussed later in this course. (The client cursor engine, however, is not in OLEDB32.DLL, but rather in MSDACE.DLL).&lt;/p&gt;  &lt;h4&gt;Data Links&lt;/h4&gt;  &lt;p&gt;Similar to the ODBC DSN facility, OLE DB does provide a way for connection information to be stored separate from the compiled client code. This mechanism, however, is entirely file-based, and does not use the registry as ODBC DSN&amp;#8217;s can. The mechanism which allows OLE DB consumers to use connection information stored in files is called the &lt;i&gt;Data Links &lt;/i&gt;Service, and is provided in the OLE DB Core Services. The files used to store this information are known as &amp;#8220;UDL&amp;#8221; files, and are saved with a &amp;#8220;.UDL&amp;#8221; extension.&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;The following demonstration will show how a UDL file can be created, and used as a troubleshooting tool to test OLE DB connectivity.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Demonstration:&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;1. Make sure in Windows Explorer, Tools-&amp;gt;Folder Options, View Tab, that &amp;#8220;Hide file extensions for known file types&amp;#8221; is not checked.&lt;/p&gt;  &lt;p&gt;2. Right click on Windows desktop, and select New-&amp;gt;Text File. &lt;/p&gt;  &lt;p&gt;3. Name the file &amp;#8220;Test.udl&amp;#8221;. The icon for the file should now be the special &amp;#8220;UDL&amp;#8221; icon.&lt;/p&gt;  &lt;p&gt;4. Double click the file to open the Data Links dialog.&lt;/p&gt;  &lt;p&gt;5. Click on the &amp;#8220;Provider&amp;#8221; tab. Select &amp;#8220;Microsoft OLE DB Provider for SQL Server&amp;#8221;.&lt;/p&gt;  &lt;p&gt;6. Click on the &amp;#8220;Connection&amp;#8221; tab. In the first dialog box (server name) type &amp;#8220;(local)&amp;#8221;.&lt;/p&gt;  &lt;p&gt;7. Click the radio button for &amp;#8220;Use NT Integrated Security&amp;#8221;. &lt;/p&gt;  &lt;p&gt;8. Click on this &amp;#8220;Advanced&amp;#8221; and &amp;#8220;All&amp;#8221; tabs. These are additional options available to set on the provider at the time you connect. &lt;/p&gt;  &lt;p&gt;9. Go back to the &amp;#8220;Connection&amp;#8221; tab and click &amp;#8220;Test Connection&amp;#8221;. You should see &amp;#8220;Test Connection Succeeded&amp;#8221;. This is a good way to verify if basic OLE DB connectivity works to a given data source.&lt;/p&gt;  &lt;p&gt;10. Now click &amp;#8216;OK&amp;#8217; to close the dialog. Then open the &amp;#8220;Test.udl&amp;#8221; file with notepad. What you see is the &amp;#8220;Connection String&amp;#8221; for the information specified in the dialogs. The Data Links interfaces in OLEDB allow a consumer to pass connection strings formatted such as this to establish a connection to a data source. You can also use these connection strings in ADO. It is a helpful trick to cut and paste the connection string from a UDL file such as this into your ADO code. (we will cover ADO in much more detail later).&lt;/p&gt;  &lt;p&gt;Another benefit Data Links provides is that consumer applications can launch this pre-built dialog to allow users to enter connection information for a data source at run time.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6052550" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/selvar/archive/tags/OLEDB+API/default.aspx">OLEDB API</category></item></channel></rss>