Working with the ADODB.Connection ObjectThe Connection object is the primary top-level ADO component. You must successfully open a Connection object to a data source before you can use associated Command or Recordset objects. Connection PropertiesTable 30.1 lists the names and descriptions of the properties of the ADODB.Connection object.
Note Most property values identified in Table 30.1 as being read/write are writable only when the connection is in the closed state. Some provider-specific properties are read/write, but most are read-only. Provider-Specific Properties and Their ValuesWhen you're tracking down problems with Connection, Command, Recordset, or Record objects, you might need to provide the values of some provider-specific properties to a Microsoft or another database vendor's technical service representative. To display the names and values of provider-specific ADODB.Property objects for an ADODB.Connection to a Jet database in the Immediate window, do the following:
Note
Some of the SQL Server provider-specific properties appear in a list on the All page of the Data Link Properties dialog for a project's connection. To view these properties and their values, when set, open the NorthwindCS project, choose File, Connection to open the Data Link Properties dialog, and click the All tab (see Figure 30.15). Figure 30.15. The All page of the Data Link Properties dialog for the NorthwindCS connection to MSDE displays a few of the 93 provider-specific properties of the OLE DB Provider for SQL Server (SQLOLEDB).
Tip
Transaction Isolation LevelsThe ability to specify the transaction isolation level applies only when you use the BeginTrans, CommitTrans, and RollbackTrans methods (see Table 30.6 later in this chapter) to perform a transaction on a Connection object. If multiple database users simultaneously execute transactions, your application should specify how it responds to other transactions in-process. Table 30.2 lists the options for the degree of your application's isolation from other simultaneous transactions.
Note Enumeration tables in this book list the default value first, followed by the remaining constants in alphabetical order. Where two members of Table 30.2 represent the same isolation level, one of the members is included for backward compatibility. The Connection.Mode PropertyUnless you have a specific reason to specify a particular ADODB.Connection.Mode value, the default adModeUnknown is adequate. The Jet OLE DB provider defaults to adModeShareDenyNone. The Access Permissions list on the Advanced page of the Data Link properties page for SQLOLEDB is disabled, but you can set the Mode property with code. Table 30.3 lists all the constants for the Mode property.
Tip You often can improve performance of client/server decision-support applications by opening the connection as read only (adModeRead). Modifying the structure of a database with SQL's DDL usually requires exclusive access to the database (adModeShareExclusive). The Connection.State PropertyTable 30.4 lists the constants that return the state of the Connection object. These constants also are applicable to the State property of the Command and Recordset objects. It's common to open and close connections as needed to reduce the connection load on the database. (Each open connection to a client/server database consumes a block of memory.) In many cases, you must test whether the Connection object is open or closed before applying the Close or Open method, or changing Connection property values, which are read-only when the connection is open.
Errors Collection and Error ObjectsFigure 30.17 illustrates the relationship between top-level ADO components and their collections. The dependent Errors collection is a property of the Connection object, and if errors are encountered with any operation on the connection, contains one or more Error objects. The Errors collection has one property, Count, which you test to determine whether an error has occurred after executing a method call on Connection and Recordset objects. A collection is required, because it's possible for an object to generate several errors. Figure 30.17. The Connection, Command, and Recordset objects have Properties and Errors collections. The Command object also has a Parameters collection and the Recordset object has a Fields Collection. The new Record object isn't included in this diagram.
The Errors collection has two methods, Clear and Item. The Clear method deletes all current Error objects in the collection, resetting the value of Count to 0. The Item method, which is the default method of the Errors and other collections, returns an object reference (pointer) to an Error object. The syntax for explicit and default use of the Item method is Set errName = cnnName.Errors.Index({strName|intIndex}) Set errName = cnnName.Errors({strName|intIndex}) The Error object has the seven read-only properties listed in Table 30.5. Error objects have no methods or events. The InfoMessage event of the Connection object, described in the "Connection Events" section later in this chapter, fires when an Error object is added to the Errors collection and supplies a pointer to the newly added Error object.
For the basics of error handling in VBA, see "Handling Runtime Errors," p. 1176. Note Unfortunately, not all RDBMS vendors implement SQLSTATE in the same way. If you test the SQLState property value, make sure to follow the vendor-specific specifications for Condition and Subcondition values. Listing 30.1 is an example of code to open a Connection (cnnNwind) and a Recordset (rstCusts) with conventional error handling; rstCusts supplies the Recordset property of the form. The "Non-existent" table name generates a "Syntax error in FROM clause" error in the Immediate window. The Set ObjectName = Nothing statements in the error handler recover the memory consumed by the objects. Listing 30.1 VBA Code That Writes Error Properties to the Immediate WindowPrivate Sub Form_Load Dim cnnNwind As New ADODB.Connection Dim rstCusts As New ADODB.Recordset On Error GoTo CatchErrors cnnNwind.Provider = "Microsoft.Jet.OLEDB.4.0" cnnNwind.Open CurrentProject.Path & "\Northwind.mdb", "Admin" With rstCusts Set .ActiveConnection = cnnNwind .CursorType = adOpenKeyset .LockType = adLockBatchOptimistic .Open "SELECT * FROM Non-existent" End With Set Me.Recordset = rstCusts Exit Sub CatchErrors: Dim colErrors As Errors Dim errNwind As Error Set colErrors = cnnNwind.Errors For Each errNwind In colErrors Debug.Print "Description: " & errNwind.Description Debug.Print "Native Error: " & errNwind.NativeError; "" Debug.Print "SQL State: " & errNwind.SQLState Debug.Print vbCrLf Next errNwind Set colErrors = Nothing Set errNwind = Nothing Set rstCusts = Nothing Set cnnNwind = Nothing Exit Sub End Sub Note
Connection MethodsTable 30.6 lists the methods of the ADODB.Connection object. Only the Execute, Open, and OpenSchema methods accept argument values. The OpenSchema method is of interest primarily for creating database diagrams, data transformation for data warehouses and marts, and online analytical processing (OLAP) applications.
The Connection.Open and Connection.OpenSchema MethodsYou must open a connection before you can execute a statement on it. The syntax of the Open method is cnnName.Open [strConnect[, strUID[, strPwd, lngOptions]]]] Alternatively, you can assign the connection string values to the Connection object's Provider and ConnectionString properties. The following example, similar to that for the Recordset object examples early in the chapter, is for a connection to Northwind.mdb in the same folder as the application .mdb: With cnnNwind .Provider = "Microsoft.Jet.OLEDB.4.0" .ConnectionString = CurrentProject.Path & "\Northwind.mdb" .Open End With In this case, all the information required to open a connection to Northwind.mdb is provided as property values, so the Open method needs no argument values. If you're creating a data dictionary or designing a generic query processor for a client/server RDBMS, the OpenSchema method is likely to be of interest to you. Otherwise, you might want to skip the details of the OpenSchema method, which is included here for completeness. Schema information is called metadata, data that describes the structure of data. Tip ADOX 2.7 defines a Catalog object for Jet 4.0 databases that's more useful for Jet databases than the generic OpenSchema method, which is intended primarily for use with client/server RDBMs. The Catalog object includes Groups, Users, Tables, Views, and Procedures collections. The Connection.Execute MethodThe syntax of the Connection.Execute method to return a reference to a forward-only ADODB.Recordset object is Set rstName = cnnName.Execute (strCommand, [lngRowsAffected[, lngOptions]]) Alternatively, you can use named arguments for all ADO methods. Named arguments, however, require considerably more typing than conventional comma-separated argument syntax. The named argument equivalent of the preceding Set statement is Set rstName = cnnName.Execute (Command:=strCommand, _ RowsAffected:=lngRowsAffected, Options:=lngOptions) If strCommand doesn't return a Recordset, the syntax is cnnName.Execute strCommand, [lngRowsAffected[, lngOptions]] The value of strCommand can be an SQL statement, a table name, the name of a stored procedure, or an arbitrary text string acceptable to the data provider. Tip For best performance, specify a value for the lngOptions argument (see Table 30.7) so the provider doesn't need to interpret the statement to determine its type. The optional lngRowsAffected argument returns the number of rows affected by an INSERT, UPDATE, or DELETE query; these types of queries return a closed Recordset object. A SELECT query returns 0 to lngRowsAffected and an open, forward-only Recordset with 0 or more rows. The value of lngRowsAffected is 0 for T-SQL updates queries and stored procedures that include the SET NOCOUNT ON statement.
Forward-only Recordset objects, created by what's called a firehose cursor, provide the best performance and minimum network traffic in a client/server environment. However, forward-only Recordsets are limited to manipulation by VBA code. If you set the RecordSource property of a form to a forward-only Recordset, controls on the form don't display field values. Connection EventsEvents are useful for trapping errors, eliminating the need to poll the values of properties, such as State, and performing asynchronous database operations. To expose the ADODB.Connection events to your application, you must use the WithEvents reserved word (without New) to declare the ADODB.Connection object in the Declarations section of a class or form module and then use a Set statement with New to create an instance of the object, as shown in the following example: Private WithEvents cnnName As ADODB.Connection Private Sub Form_Load Set cnnName = New ADODB.Connection ... Code using the Connection object ... cnnName.Close End Sub The preceding syntax is required for most Automation objects that source (expose) events. Event-handling subprocedures for Automation events often are called event sinks. Source and sink terminology derives from the early days of transistors; the source (emitter) supplies electrons and the sink (collector) accumulates electrons. Table 30.8 lists the events that appear in the Procedures list of the code-editing window for the cnnName Connection object and gives a description of when the events fire.
Tip Take full advantage of ADO events in your VBA data-handling code. Relatively few developers currently use event-handling code in ordinary database front ends. ADO's event model will be of primary interest to developers migrating from Access 97's RDO to ADO. Developers of data warehousing and OLAP applications, which often involve very long-running queries, are most likely to use events in conjunction with asynchronous query operations. |