Pages

Saturday, 14 April 2018

The Connection Object Summary In ActiveX Data Objects

This chapter has introduced the Connection object -- the first of the nine major components of ActiveX Data Objects. You have learned how to establish connections with any type of OLE DB data provider. The following list summarizes key points:

You can create a Connection object either explicitly within your own code, or implicitly, through instantiation of a Recordset or Command object.

Each Connection object represents a single unique connection to a particular OLE DB data source through a data provider, both of which you have specified in a connection string.

With the Connection object, you can execute commands against the associated data source. There are three types of commands that can be executed: a SQL statement, a stored procedure, or parameterized query. In addition, you can open a simple table or pass a data provider-specific string to the particular data provider, which will provide its own analysis and resultset.

The Connection object controls the utilization of transaction management through three methods: BeginTrans, CommitTrans, and RollbackTrans. Transactions are used to manage the integrity of one or multiple data sources when data is manipulated. Like If...Then statements, transactions can be nested.

You can use the Connection object to obtain information about the structure of a given data source with the use of the OpenSchema method. This information can be helpful when querying for table, procedure, or index names.

Determining The Layout Of Your Data Source In ActiveX Data Objects

Your data source has many characteristics that can be exposed to your applications via ADO. For instance, some data sources have table names, field names, and indexes. You can use the OpenSchema method of the Connection object to enumerate the characteristics that make up the structure of your data source. The OpenSchema method has the following syntax:

Set recordset_name = connection_name.OpenSchema(QueryType, Criteria, SchemaID)

Table 4-7 describes each of the components found in the previous syntax declaration.

Table 4-7. The Components of the OpenSchema Method

Component
Description
recordset_name
A valid Recordset object.
connection_name
A currently open Connection object.
QueryType
Indicates what type of schema query to perform on the associated connection object. This value must be a valid constant that belongs to the SchemaEnum enumeration. Not all QueryType values are supported by every data source. See the OpenSchema method in Appendix C, for more information.
Criteria
Optional. Indicates a specific constraint used to perform the query as defined by the QueryType argument. Criteria values are specific to each QueryType value, and, because not all QueryTypes are supported by every data source, neither are all Criteria values.
SchemaID
Optional. A GUID for a provider-specific schema that is used only with the QueryType constant, adSchemaProviderSpecific.

In most cases, your data provider will not support all of the Criteria constraints. As a matter of fact, the data provider must supply you with only the adSchemaTables, adSchemaColumns, and adSchemaProviderTypes constants, according to the OLE DB specification. For a list of all the constraints available, refer to the SchemaEnum enumeration in Appendix E.

Example 4-19 utilizes the OpenSchema method to create a viewer for all possible QueryType and Criteria combinations for a given data source.

To create this example, first open up a new Application EXE project within Visual Basic, and add the latest version of Microsoft ActiveX Data Objects through the Project References tool item. Next, add the controls listed in Table 4-8, and name them accordingly.

Table 4-8. The Components of the OpenSchema Method

Control
Name
ListBox Control
lstQueryType
ListBox Control
lstCriteria
ListBox Control
lstValue
Command Button
cmdClose

Now, replacing the code that is already in the Form1 form dialog box, enter the code for the modular-level object variables, as shown in Example 4-19. This example will use the OLE DB provider for ODBC connections and the SQL Server DSN, SQLNorthwindDSN.

If you do not have SQL Server, you can replace this DSN with the BiblioDSN DSN (see Section 4.2.2.1 earlier in this chapter).

Example 4-19. The Schema Viewer Example:-

Option Explicit

Private con As ADODB.Connection
Private rst As ADODB.Recordset

Private Sub Form_Load( )

Set con = New ADODB.Connection
Set rst = New ADODB.Recordset

' connect to our data source
con.Open "SQLNorthwindDSN"

' populate the query types list box with valid query type values
for
' this particular data source
Call PopulateQueryTypes

End Sub

Private Sub PopulateQueryTypes( )

lstQueryType.Clear

' call the CheckQueryType function for each possible query type
value
CheckQueryType "adSchemaCatalogs: " & adSchemaCatalogs

CheckQueryType "adSchemaCharacterSets: " & adSchemaCharacterSets
CheckQueryType "adSchemaCheckConstraints: " &
adSchemaCheckConstraints
CheckQueryType "adSchemaCollations: " & adSchemaCollations
CheckQueryType "adSchemaColumnPrivileges: " &
adSchemaColumnPrivileges
CheckQueryType "adSchemaColumns: " & adSchemaColumns
CheckQueryType "adSchemaColumnsDomainUsage: " _
& adSchemaColumnsDomainUsage
CheckQueryType "adSchemaConstraintColumnUsage: " _
& adSchemaConstraintColumnUsage
CheckQueryType "adSchemaConstraintTableUsage: " _
& adSchemaConstraintTableUsage
CheckQueryType "adSchemaCubes: " & adSchemaCubes
CheckQueryType "adSchemaDBInfoKeywords: " & adSchemaDBInfoKeywords
CheckQueryType "adSchemaDBInfoLiterals: " & adSchemaDBInfoLiterals
CheckQueryType "adSchemaDimensions: " & adSchemaDimensions
CheckQueryType "adSchemaForeignKeys: " & adSchemaForeignKeys
CheckQueryType "adSchemaHierarchies: " & adSchemaHierarchies
CheckQueryType "adSchemaIndexes: " & adSchemaIndexes
CheckQueryType "adSchemaKeyColumnUsage: " & adSchemaKeyColumnUsage
CheckQueryType "adschemaLevels: " & adSchemaLevels
CheckQueryType "adSchemaMeasures: " & adSchemaMeasures
CheckQueryType "adSchemaMembers: " & adSchemaMembers
CheckQueryType "adSchemaPrimaryKeys: " & adSchemaPrimaryKeys
CheckQueryType "adSchemaProcedureColumns: " &
adSchemaProcedureColumns
CheckQueryType "adSchemaProcedureParameters: " _
& adSchemaProcedureParameters
CheckQueryType "adSchemaProcedures: " & adSchemaProcedures
CheckQueryType "adSchemaProperties: " & adSchemaProperties
CheckQueryType "adSchemaProviderTypes: " & adSchemaProviderTypes
CheckQueryType "adSchemaReferentialContraints: " _
& adSchemaReferentialContraints
CheckQueryType "adSchemaSchemata: " & adSchemaSchemata

CheckQueryType "adSchemaSQLLanguages: " & adSchemaSQLLanguages
CheckQueryType "adSchemaStatistics: " & adSchemaStatistics
CheckQueryType "adSchemaTableConstraints: " &
adSchemaTableConstraints
CheckQueryType "adSchemaTablePrivileges: " &
adSchemaTablePrivileges
CheckQueryType "adSchemaTables: " & adSchemaTables
CheckQueryType "adSchemaTranslations: " & adSchemaTranslations
CheckQueryType "adSchemaUsagePrivileges: " &
adSchemaUsagePrivileges
CheckQueryType "adSchemaViewColumnUsage: " &
adSchemaViewColumnUsage
CheckQueryType "adSchemaViews: " & adSchemaViews
CheckQueryType "adSchemaViewTableUsage: " & adSchemaViewTableUsage

End Sub

The CheckQueryType method determines if a schema is available by attempting to open it with the OpenSchema method:

Private Sub CheckQueryType(sQueryType As String)
On Error GoTo ERR_CheckQueryType:

' if we can open the schema without getting an error, the data
source
' will support it, otherwise, do not add it to the list box
Set rst = con.OpenSchema(GetQueryTypeValue(sQueryType))

ERR_CheckQueryType:
Select Case Err.Number
Case 0:
lstQueryType.AddItem (sQueryType)
Case adErrFeatureNotAvailable:
' not supported
End Select

End Sub

When a user clicks on a query-type list box, the corresponding schema is opened and used to populate the criteria list box:

Private Sub lstQueryType_Click( )

Dim lTemp As Long

Dim fld As ADODB.Field

lstCriteria.Clear
lstValue.Clear

' get the value of the query type from parsing the string
' that is selected
lTemp = GetQueryTypeValue(lstQueryType.List(lstQueryType.ListIndex))

' open the schema for the query type chosen
Set rst = con.OpenSchema(lTemp)

' add criterias that are available for the query type to the list
box

For Each fld In rst.Fields
lstCriteria.AddItem fld.Name
Next fld

End Sub

In turn, as the criteria list box is selected, the individual values for the criteria are added to the values list box:

Private Sub lstCriteria_Click( )

lstValue.Clear

' populate the values list box with the values for the selected
' query type and criteria
If (Not (rst.EOF And rst.BOF)) Then rst.MoveFirst
Do Until (rst.EOF)
lstValue.AddItem _
ConvertToString(rst.Fields(lstCriteria.ListIndex).Value)
rst.MoveNext
Loop

End Sub

Now enter the remaining utility and termination methods, and you are done:

Private Function ConvertToString(vInput As Variant) As String

' return the 'Null' string if the value is null, otherwise return
the
' actual string
If IsNull(vInput) Then
ConvertToString = "Null"
Else
ConvertToString = vInput
End If
End Function

Private Function GetQueryTypeValue(sQueryType As String) As Long

Dim sTemp As String

' take the number (value of the query type) off of the string
sTemp = Right$(sQueryType, Len(sQueryType) - InStr(1, sQueryType,
":"))

GetQueryTypeValue = Val(sTemp)

End Function

Private Sub cmdClose_Click( )

' clean up recordset object
rst.Close
Set rst = Nothing

' clean up connection object
con.Close
Set con = Nothing

' end the application
Unload Me

End Sub

When this application is compiled and run, it should produce a result similar to Figure 4- 8, assuming your data source is similar to mine.

Figure 4-8. The Schema Viewer application in action
The OpenSchema method is very useful for finding such information about the data source as table names, stored procedure and query names, index information, table names, as well as a number of other valuable pieces of information. I suggest that you use the Schema Viewer application from Example 4-19 on your data source to see what is available and what you would find useful within your own application.

The OpenSchema method is not available to a client-side Connection object when using RDS.

Managing Multiple Transactions With ActiveX Data Objects

Transaction management is used to maintain the integrity of a data source when operations on one or more data sources need to be treated as a single operation.

The most common example of transaction management comes from banking. Take, for instance, the steps involved in transferring money from a savings account to a checking account. First, you must remove the desired amount of money from the savings account, and then that amount must be added to your checking account. Suppose that somebody walked by and pulled the plug of the ATM machine just when it had completed removing your money from your savings account, but before it added it to your checking account. By using three methods (BeginTrans, CommitTrans, and RollbackTrans), you can create single transactions from multiple operations.

The BeginTrans, CommitTrans, and RollbackTrans methods are not available when you are using a client-side Connection object with RDS.

Starting a Transaction: The BeginTrans and CommitTrans Methods:-

A transaction begins with a call to a Connection object's BeginTrans method and ends with a call to the CommitTrans method. The CommitTrans method indicates that the transaction is completed and that the data should be saved, or committed, to the data source.

The following code illustrates the use of the BeginTrans and CommitTrans methods:

' begin a new transaction
con.BeginTrans

'
' do some manipulation of the data here
'

' commit the manipulations of the data to the data source now
con.CommitTrans

Not all data providers support transactions, and you should check before using them. You can tell whether the current data provider supports transactions by checking for the Transaction DDL dynamic property by using the Properties collection of the Connection object. If it appears in the Connection object's Properties collection, then your data provider supports transaction management through the BeginTrans, CommitTrans, and RollbackTrans methods.

Example 4-14 shows how you can test for the support of transactions by your data provider, and how you can work with or without it depending on the result of your test.

Example 4-14. Testing for Transaction Support:-

Public Sub TestForTransactionSupport( )

Dim con As ADODB.Connection
Set con = New ADODB.Connection

' open the connection on a given data source
con.Open "BiblioDSN"

' if the data provider supports transactions, begin one
If (SupportsTransactions(con)) Then con.BeginTrans

' manipulate data here
'
' if the data provider supports transactions, commit changes
If (SupportsTransactions(con)) Then con.CommitTrans

' close the Connection and clean up
con.Close
Set con = Nothing

End Sub

Private Function SupportsTransactions( _
conConnectionToTest As ADODB.Connection) As Boolean
On Error GoTo ERR_SupportsTransactions:

Dim lValue As Long

' simply try to access the property to verify whether the data
provider
' supports transactions
lValue = conConnectionToTest.Properties("Transaction DDL").Value

' if we got this far, the property exists and the data provider
' supports transactions
SupportsTransactions = True

Exit Function

ERR_SupportsTransactions:

Select Case (Err.Number)

' property does not exist, therefore the data provider does not
' support transactions
Case adErrItemNotFound:
SupportsTransactions = False

Case Else:
' another error

End Select

End Function

Canceling a Transaction: The RollbackTrans Method:-
It doesn't make sense to keep track of transactions if you cannot cancel them, so the Connection object implements the RollbackTrans method. The RollbackTrans method cancels the current transaction, which is defined as the entire set of operations performed on the data source since the last call to the BeginTrans method. Once the RollbackTrans method is called, your data source will never see the changes that were made during the last transaction.

A common time to use the RollbackTrans method is immediately following an error that has occurred during the processing of data. Example 4-15 demonstrates the RollbackTrans method.

Example 4-15. The RollbackTrans Method:-

Public Sub Rollback( )
On Error GoTo ERR_Rollback:

Dim con As ADODB.Connection


Set con = New ADODB.Connection

' open the connection on a given data source
con.Open "BiblioDSN"

' begin a transaction
con.BeginTrans

'
' manipulate data here
'

' commit changes
con.CommitTrans

' skip rollback and close the connection
GoTo CloseConnection

ERR_Rollback:

' an error has occurred, abort changes
con.RollbackTrans

CloseConnection:

' close the Connection and clean up
con.Close
Set con = Nothing

End Sub

Nesting Transactions:-
If your data provider supports transactions, there is a good chance that it also supports nested transactions. For instance, Microsoft Access can support nested transactions up to five levels deep.

The BeginTrans method returns a Long value that represents the level of nesting for the newly created transaction. The first level is considered level one (1), not zero (0). When you nest transactions, you must resolve the more recently created transaction with either the CommitTrans or RollbackTrans method before you can resolve previously created transactions.

Example 4-16 illustrates the use of nested transactions.

Example 4-16. Nested Transactions:-

Dim con As ADODB.Connection

Dim lLevel As Long

Set con = New ADODB.Connection

' the connection must be open to utilize transactions
con.Open "Provider=Microsoft.Jet.OLEDB.4.0; " _
& "Data Source=C:\Program Files" _
& "\Microsoft Visual Studio" _
& "\VB98\Biblio.mdb"

' record the level of the newly created transaction and print it
lLevel = con.BeginTrans( )
Debug.Print lLevel

' inside level 1 transaction

' record the level of the newly created transaction and print it
lLevel = con.BeginTrans( )
Debug.Print lLevel

' inside level 2 transaction

' record the level of the newly created transaction and print
it
lLevel = con.BeginTrans( )
Debug.Print lLevel

' inside level 3 transaction

' commit changes to the level 3 transaction
con.CommitTrans

' commit changes to the level 2 transaction
con.CommitTrans

' commit changes to the level 1 transaction
con.CommitTrans

' close the Connection and clean up
con.Close
Set con = Nothing

Setting Transaction Options:-There are two types of options that we can specify when using transactions through ADO:

Attributes:-
The Attributes property specifies the automatic creation of new transactions. By using the Attributes property of the Connection object, we can define whether new transactions are created when the current one has ended.

IsolationLevel:-
By setting the value of the IsolationLevel property, you can determine whether the current transaction can read the changes that are as of yet not committed by another transaction.

Automatic creation of new transactions:-
When you call either the CommitTrans or the RollbackTrans methods, you are ending the current transaction. By default, you must call BeginTrans once again to start another transaction, but you can change this behavior by setting the value of the Attributes property. Table 4-5 lists these values.

Table 4-5. The XactAttributeEnum Values of the Attributes Property

Constant
Value
Description
none
0
Default. Indicates that neither of the following constants have been chosen.
adXactCommitRetaining
131072
Indicates that a new transaction will be created after the CommitTrans method is called.
adXactAbortRetaining
262144
Indicates that a new transaction will be created after the RollBackTrans method is called.

You can use both the adXactCommitRetaining and the adXactAbortRetaining constants at the same time, as shown in Example 4-17.

Example 4-17. Using the Attributes Property with Multiple Constants:-

Dim con As ADODB.Connection
Set con = New ADODB.Connection

' the connection must be open to utilize transactions
con.Open "BiblioDSN"

' set the attributes to automatically create a new transaction
' when both the CommitTrans and the RollbackTrans methods are
' called
con.Attributes = adXactCommitRetaining _
+ adXactAbortRetaining

' start transaction #1
con.BeginTrans

' do something here

' commit transaction #1, start transaction #2
con.CommitTrans

' do something here

' rollback transaction #2, start transaction #3
con.RollbackTrans

' do something here

' set the attributes so that neither CommitTrans nor RollbackTrans
' will create a new transaction
con.Attributes = 0

' commit transaction #3
con.CommitTrans

' close the Connection and clean up
con.Close
Set con = Nothing

The Attributes property is not available to a client-side Connection object when using RDS. In addition, not all data providers support the transactions, and, therefore, they won't support the Attributes property. Be sure to check for the Transaction DDL property in the Properties collection of your Connection object to see whether your data provider supports transactions before you attempt to use the Attributes property.

Isolation level
The IsolationLevel property is used to indicate how transactions relate to each other. By setting its value, you can determine whether the current transaction can read the changes that are as of yet not committed by another transaction.

IsolationLevel is a read/write property that can take any one of the following IsolationLevelEnum constants shown in Table 4-6.

Table 4-6. The IsolationLevelEnum Values

Constant
Value
Description
adXactUnspecified
-1
Indicates that the data provider is using an isolation level that cannot be determined.
AdXactChaos
16
Indicates that you cannot write over changes that have been made by higher level transactions.
AdXactBrowse
256
Indicates that you can view changes that have not yet been committed by other transactions.
adXactReadUncommitted
256
Same as adXactBrowse. Kept for compatibility with earlier versions of ADO.
adXactCursorStability
4096
Default. Indicates that you can only view changes from other transactions once they have been committed.
adXactReadCommitted
4096
Same as adXactCursorStability. Kept for
compatibility with earlier versions of ADO.
adXactRepeatableRead
65536
Indicates that from one transaction, you cannot see changes that have been made in other transactions until they are committed, but you can requery the data source to see newly created records.
AdXactIsolated
1048576
Indicates all transactions are completely isolated from each other.
adXactSerializable
1048576
Same as adXactIsolated. Kept for compatibility with earlier versions of ADO.

The constant adXactUnspecified is the only valid value for the IsolationLevel property when you are using a client-side Connection object when using RDS.

Example 4-18 shows how you can use the IsolationLevel property to determine the level of isolation for the current transactions.

Example 4-18. Using the IsolationLevel Property:-

Dim con As ADODB.Connection
Set con = New ADODB.Connection

Dim sLevel As String

' open the connection
con.Open "BiblioDSN"

' select message based on the current isolation level
Select Case (con.IsolationLevel)

Case adXactUnspecified:
sLevel = "Isolation level cannot be determined."

Case adXactChaos:
sLevel = "You cannot write over changes that have been " _
& "made by higher level transactions."

Case adXactBrowse Or adXactReadUncommitted:
sLevel = "You can view changes not yet committed by other " _
& "transactions."

Case adXactCursorStability Or adXactReadCommitted:
sLevel = "You can only view changes from other " _
& "transactions that have been committed."

Case adXactRepeatableRead:
sLevel = "You can only view changes from other " _
& "transactions that have been committed and you " _
& "can requery data to see new records."

Case adXactIsolated Or adXactSerializable:
sLevel = "All transactions are isolated from each other."

End Select

' display isolation level message
MsgBox sLevel

con.Close
Set con = Nothing

The IsolationLevel property is both read- and write-enabled, but it does not take effect until you call the BeginTrans method of the Connection object. It is possible that the data provider will automatically change the level of isolation when it cannot establish the level requested. In such a case, the level will be changed to the next higher level of isolation.

Thursday, 12 April 2018

Executing Commands In ActiveX Data Objects

ADO can work with data, or execute commands, in several ways:

Data can be queried or gathered based on a specific list of qualifications (selection commands).

Data can be manipulated with an action query that usually changes data in some common way throughout your data source (update commands).

Data can be restructured with statements that alter the way the data resides in a particular data source (restructuring commands).

These three types of data gathering and manipulation can be done through either SQL statements or stored procedures. The Connection object allows the execution of both SQL statements and stored procedures directly, through the use of an Execute method. The Execute method can also be used to open an entire table from your data source.

The following sections describe in detail execution of commands.

The Execute Method:-
There are two different syntaxes for the Connection object's Execute method. The first is for commands that return information in the form of a Recordset object (see Chapter 5 ), and the second is for commands that do not return anything.

The correct syntax for a call to the Execute method that returns a Recordset object is:

Set recordset = connection.Execute (CommandText, RecordsAffected, 
Options)

The correct syntax for a method call that does not return any records is:

connection.Execute CommandText, RecordsAffected, Options

Table 4-3 describes each of the components found in these syntaxes.

Table 4-3. The Components of the Execute Method

Component Description
connection A currently open Connection object.
CommandText
A string value containing a SQL statement, a table name, or a stored
procedure command.
RecordsAffected
Optional. A long value that returns the number of records that were
affected by the call to the Execute method.
Options
Optional. A long value that indicates the precise content of the
CommandText argument. See Table 4-4.

Table 4-4 describes the different values for the Options argument of the Execute method, which are values of the CommandTypeEnum.

Table 4-4. The CommandTypeEnum Values

Constant Value Description
adCmdText 1 Indicates that the CommandText string is a data provider-specific command and will pass it onto that data provider for evaluation and execution. This value would be used when passing a SQL statement to a SQL data provider.
adCmdTable 2
Indicates that the CommandText string is evaluated as a name of a
table in the current database. This type of CommandText string,
when used with the Execute method of the Connection object, will
result in a recordset that includes the entire table specified.
adCmdStoredProc 4
Indicates that the CommandText string is evaluated as a name of a
stored procedure located within the current database.
adCmdUnknown 8
Default. Indicates that you have no clue what kind of
information you are passing to the data provider and that the
data provider will have to figure it out itself. This usually
indicates that the Options flag was not set.
adCmdFile 256
Indicates that the CommandText string is evaluated as a name of a
file that contains a previously persisted Recordset object. This
option can be used only with the Open and Requery methods.
If you do not specify a value for the Options argument, then ADO has to communicate with your data provider to determine whether the CommandText string is a SQL statement, a stored procedure name, or a table name. This could take a considerable amount of time; therefore, it is recommended that you always specify the kind of information that you are sending to the data provider through the CommandText argument. Example 4-11 illustrates how the Execute method can be used to execute each type of command matching those indicated in Table 4-4.

Example 4-11. Executing Different Command Types with the Connection Object:-
Dim con As ADODB.Connection
Dim rst As ADODB.Recordset
Set con = New ADODB.Connection
Set rst = New ADODB.Recordset
' use this variable to record the number of records affected by the
' Execute method
Dim lRecordsAffected As Long

' open the DSN (Data Source Name)
con.Open "SQLNorthwindDSN"

' execute a SQL statement on the database
Set rst = con.Execute("SELECT * FROM Orders;", _
lRecordsAffected, _
adCmdText)

' execute an open table command
Set rst = con.Execute("Orders", _
lRecordsAffected, _
adCmdTable)

rst.Close
Set rst = Nothing

' execute a stored proceudre
' notice that we did not specify the options argument, therefore,
' the data provider must determine what type of command this is
con.Execute "Invoices"

con.Close
Set con = Nothing

The OLE DB provider for ODBC can utilize the CommandText argument of the Execute method to access stored procedures with a special syntax. An example of this syntax appears in Example 4-12 where it is used to execute a Microsoft Access select query. (I will discuss the CommandText property of the Command object in Chapter 7.)

The Parameters collection belongs only to a Command object, not to a Connection object. For this reason, we cannot pass parameters to stored procedures via a Connection object. We can execute queries that do not require parameters, using this special syntax or by naming the stored procedure as in Example 4-12.

Example 4-12. Executing Stored Procedures:-

Dim con As ADODB.Connection
Dim rst As ADODB.Recordset

Set con = New ADODB.Connection
Set rst = New ADODB.Recordset

Dim lRecordsAffected As Long

con.Open "SQLNorthwindDSN"

' use just the name of the stored procedure
Set rst = con.Execute("[Ten Most Expensive Products]", _
lRecordsAffected, _
adCmdStoredProc)

' use OLE DB Provider for ODBC Drivers special stored procedure
' call syntax

Set rst = con.Execute("{call SalesByCategory(1)}", _
lRecordsAffected, _
adCmdText)

rst.Close
Set rst = Nothing

con.Close
Set con = Nothing

The code that is emphasized in Example 4-12 illustrates the syntax used for calling stored procedures with the OLE DB provider for ODBC drivers.

The CommandTimeout Property:-
The behavior of the Connection object's CommandTimeout property is very similar to the ConnectionTimeout property, although the setting for one does not affect the other. As described earlier, the ConnectionTimeout property indicates the maximum number of seconds allowed when completing a connection on a specified data source. The CommandTimeout property represents the maximum number of seconds allowed for ADO to complete a given command with the Execute method.

The default value for the CommandTimeout property is 30, representing 30 seconds. If the execution of a command exceeds the number of seconds specified in the CommandTimeout property, then the command is abandoned and an error is raised. This permits your command to timeout if network traffic is too busy to carry out such an operation.

Example 4-13 shows the use of the CommandTimeout property.

Example 4-13. The CommandTimeout Property:-

Public Sub CommandTimeout( )
On Error GoTo ERR_CommandTimeout:

Dim con As ADODB.Connection
Set con = New ADODB.Connection

' set the timeout period to 2 seconds
con.CommandTimeout = 2

' attempt to open the Connection object with a connection string
con.Open "BiblioDSN"

con.Execute "[All Titles]"

' close the connection
con.Close

GoTo CleanUp:

' an error has occurred

ERR_CommandTimeout:

Dim oErr As ADODB.Error

' there can be multiple errors in ADO; we must look at all of them
For Each oErr In con.Errors

Select Case (Err.Number)

Case adErrStillConnecting:
' timeout error
MsgBox "The command timed out on attempting to
execute."

Case Else:
' other type of error
MsgBox "Other Error: " & oErr.Description

End Select

Next oErr

' this code will be ran whether there was an error or not
CleanUp:

' clean up
Set con = Nothing

End Sub

The CommandTimeout property is read-only once the Connection object is opened, but while it is closed, you can either read or set its value.