ACC97: Tips for Converting Applications to Using ODBCDirect

ID: Q164481

The information in this article applies to:

SUMMARY

Advanced: Requires expert coding, interoperability, and multiuser skills.

This article contains tips on how to convert an application that currently uses the Microsoft Jet database engine and Data Access Objects (DAO) so that it uses ODBCDirect. ODBCDirect is a technology that enables you to work with ODBC database servers without loading the Microsoft Jet database engine. ODBCDirect relies on the Microsoft DAO 3.5 object model, so that you can easily modify your existing DAO code to take advantage of ODBCDirect.

This article assumes that you are familiar with Visual Basic for Applications and with creating Microsoft Access applications using the programming tools provided with Microsoft Access. For more information about Visual Basic for Applications, please refer to the "Building Applications with Microsoft Access 97" manual.

This article covers the following topics:

MORE INFORMATION

Changing the Type of Workspace You Use

The first thing you must do when implementing ODBCDirect is to create ODBCDirect Workspace objects in your code. In Microsoft Access 97, you can create ODBCDirect workspaces in two ways:

Once you create a workspace, its Type property is read-only, and is set to either dbUseJet or dbUseODBC.

Changing the Database You Open

Prior to Microsoft Access 97 and ODBCDirect, the only way to connect to an ODBC data source was through the Database object. ODBCDirect offers you two connection options: you can use the traditional call to the OpenDatabase method, or you can create a Connection object using the OpenConnection method. The difference between the Database object and the Connection object is that the performance of the Connection object is tuned for remote database connectivity. For example, the Connection object can perform asynchronous operations and can create temporary QueryDef objects against remote data; in contrast, the Database object follows the traditional DAO model using the Jet database engine.

Handling Data Definition Language (DDL) Operations

DAO's ODBCDirect functionality does not support the TableDefs or Indexes collection. This means that an application that programmatically creates new TableDef objects or looks up indexes in the Indexes collection of a TableDef object will not work in the ODBCDirect object model of DAO version 3.5. There are two ways you can work around this limitation:

Creating and Using QueryDef Objects

When you use the OpenDatabase method in an ODBCDirect workspace to connect to an ODBC data source, the CreateQueryDef method is not supported. Therefore, the only way to successfully execute the CreateQueryDef method against an ODBC data source using ODBCDirect, is through a Connection object. If you have existing code that uses the CreateQueryDef method, and the ODBCDirect connection was established using a Database object, you must change your CreateQueryDef calls to execute on the Connection property of the Database object rather than on the Database object itself.

NOTE: QueryDef objects that you create in an ODBCDirect workspace are not stored in the database, and are lost when the Workspace object is closed or goes out of scope.

QueryDef objects are powerful because they are prepared and optimized statements that can be called again and again. QueryDef objects, like Connection objects, support asynchronous execution through the Execute and OpenRecordset methods. Also, you can use the QueryDef object to set up properties for the resulting Recordset. For example, when you use ODBCDirect, you can use the CacheSize method of a QueryDef object to limit the number of records cached locally. The following example illustrates this technique:

   Sub SetCacheSize()
      Dim wrksp As Workspace, qdf As QueryDef, rst As Recordset
      Dim cnn As Connection, strConnect As String

      Set wrksp = CreateWorkspace("ODBCDirect", "Admin", "", dbUseODBC)
      strConnect = "ODBC;DSN=Pubs;UID=sa;PWD=;DATABASE=Pubs"
      Set cnn = wrksp.OpenConnection("", dbDriverNoPrompt, False, _
                                     strConnect)
      Set qdf = cnn.CreateQueryDef("tempqd")
      qdf.SQL = "Select * from authors"
      'The local cache for the Recordset is 200 records
      qdf.CacheSize = 200
      Set rst = qdf.OpenRecordset()
      Debug.Print rst.CacheSize
      rst.Close
      cnn.Close
   End Sub

For more information about QueryDef objects and their properties, search the Help Index for "QueryDef objects," and then select "QueryDef Object (DAO)."

Opening Recordset Objects

Another consideration when you use ODBCDirect workspaces is that recordsets open differently by default than they do in a Jet workspace. For example, Recordset objects opened in an ODBCDirect workspace default to the fastest Recordset type, which is a forward-only, read-only Recordset.

The syntax for creating a Recordset object is:

   Set rs = object.OpenRecordset(source, type , options, lockedits)

In this syntax, the Source argument is required; it refers to the name of the table, query, view, or an SQL statement that returns records. The Type argument is optional; it indicates the type of Recordset to open or the manner in which records are retrieved from the server and buffered. The constants you can use for the Type argument in ODBCDirect are:

   dbOpenDynaset
   dbOpenDynamic
   dbOpenSnapShot
   dbOpenForwardOnly

NOTE: If you do not specify a Type argument with the OpenRecordset method in an ODBCDirect workspace, the object defaults to dbOpenForwardOnly. In order to update records, or to scroll backward through the recordset, be sure to use dbOpenDynaset or dbOpenDynamic in the Type argument.

The Options argument is also optional; it specifies the characteristics of the new Recordset. The Options argument can be any of the following constants in a Microsoft Jet Workspace

   dbAppendOnly
   dbSQLPassThrough
   dbSeeChanges
   dbDenyWrite
   dbDenyRead
   dbForwardOnly
   dbReadOnly
   dbRunAsync
   dbExecDirect
   dbInconsistent
   dbConsistent

However, you can only supply a zero (0) for the Options argument in an ODBCDirect Workspace, for example:

    Set rs=cn.OpenRecordset("Source", dbOpenDynaset, 0, dbOptimistic)

In a Microsoft Jet Workspace, you can use constants in the Options argument in combination, for example:

   Set rs=cn.OpenRecordset("Source", dbOpenDynaset,dbSeeChanges+dbRunAsync)

However, you must be careful when choosing the combinations you create. The type you choose must work with the options that can be selected for that type. For example, in the following statement the dbSeeChanges option is not necessary with a dbOpenSnapShot type recordset:

   Set rs=cn.OpenRecordset("Source", dbOpenSnapShot, dbSeeChanges _
                           + dbConsistent

The LockEdits argument is optional; it specifies the record locking mechanism to use if you open your recordset as dbOpenDynaset or dbOpenDynamic. The constants you can use in this argument are:

   dbPessimistic
   dbOptimistic
   dbOptimisticValue
   dbOptimisticBatch

Using Parameterized Queries

When you work with parameterized QueryDef objects in an ODBCDirect workspace, you continue to work with the Parameter object common to Microsoft Jet database engine version 3.0. One new feature which has been added to Parameter objects which makes them more useful for client/server applications is the Direction property. This property sets or returns a value that indicates whether a Parameter object represents an input parameter, an output parameter, both input and output, or the return value from the procedure. Although the ODBC driver will attempt to determine the direction of the parameter, the Direction property is read/write so you can set it if you need to.

NOTE: Some ODBC servers require you to specify information in the Direction property before you execute the query; others will set the property for you.

ODBCDirect does not support named parameters. Therefore, the syntax for a parameter in a SQL statement in ODBCDirect workspaces is a question mark (?), instead of a name as it is in Microsoft Jet workspaces. For example, the Microsoft Jet SQL expression "SELECT * FROM Employees WHERE LastName = [txtName]" creates a parameter named txtName. With ODBCDirect, the same SQL statement reads as "SELECT * FROM Employees WHERE LastName = ?"

For an example that uses the Direction property, search the Help Index for "Direction property."

Performing Batch Optimistic Updating

Another advantage to using ODBCDirect is the ability to decrease network traffic between client and server computers using Batch Optimistic Updating. This means that all changes to a recordset are cached locally until you specifically tell DAO to flush all changes to the server. This is accomplished by specifying the type argument dbUpdateBatch when you call the Update method.

Before you call the Update method, it is recommended that you specify how individual rows will be updated. To accomplish this, you can use the UpdateOptions property of the Recordset object. Unless you specify otherwise, the UpdateOptions property defaults to the following:

   dbCriteriaKey+dbCriteriaUpdate

This means that Microsoft Access is going to use the primary key value when it constructs the Where clause during the batch update. This property accepts any combination of the following constants:

   Constant               Description
   -----------------------------------------------------------------------

   dbCriteriaKey          (Default) Uses just the key column(s) in the
                            Where clause.
   dbCriteriaModValues      Uses the key column(s) and all updated columns
                            in the Where clause.
   dbCriteriaAllCols        Uses the key column(s) and all the columns in
                            the Where clause.
   dbCriteriaTimeStamp      Uses just the timestamp column if available
                            (will generate a run-time error if no timestamp
                            column is in the result set).
   dbCriteriaDeleteInsert   Uses a set of DELETE and INSERT statements for
                            each modified row.
   dbCriteriaUpdate         (Default) Uses an UPDATE statement for each
                            modified row.

To use Batch Optimistic Updating in Microsoft Access 97, you must satisfy the following conditions: The following example illustrates the use of Batch Optimistic Updating using an ODBCDirect workspace.

   Function BatchUpdate()
      Dim wrkMain As Workspace
      Dim conMain As Connection
      Dim rstTemp As Recordset
      Dim ConnStr as String
      Set wrkMain = CreateWorkspace("ODBCWorkspace", "admin", "", _
                                    dbUseODBC)

      ' This DefaultCursorDriver setting is required for
      ' batch updating.
      wrkMain.DefaultCursorDriver = dbUseClientBatchCursor
      ConnStr = "ODBC;DATABASE=pubs;UID=sa;PWD=;DSN=Publishers"
      Set conMain = wrkMain.OpenConnection("Publishers", _
           dbDriverNoPrompt, False, ConnStr)
      ' The following locking argument (dbOptimisticBatch) is required for
      ' batch updating.
      Set rstTemp = conMain.OpenRecordset("SELECT * FROM Authors", _
                                          dbOpenDynaset, dbRunAsync, _
                                          dbOptimisticBatch)
      With rstTemp
         ' Increase the number of statements sent to the server
         ' during a single batch update, thereby reducing the
         ' number of times an update would have to access the
         ' server.
         .BatchSize = 25
         ' Change the UpdateOptions property so that the WHERE
         ' clause of any batched statements going to the server
         ' will include any updated columns in addition to the
         ' key column(s).  In addition, DAO 3.5 is going to use an Update
         ' statement for each modified row.
         .UpdateOptions = dbCriteriaAllCols + dbCriteriaUpdate
         Do While Not rstTemp.EOF
            rstTemp.Edit
            rstTemp.Fields("au_lname") = rstTemp.Fields("au_lname") & _
               "  Test"
            rstTemp.Update
            rstTemp.MoveNext
         Loop
         rstTemp.Update (dbUpdateBatch)
         .Close
      End With

      conMain.Close
      wrkMain.Close
   End Function

REFERENCES

Microsoft Office 97 "Visual Basic Programmer's Guide," Chapter 11, "Data Access Objects," pages 289-312

For more information about using ODBCDirect, search the Help Index for "ODBCDirect workspaces," or ask the Microsoft Access 97 Office Assistant.

Keywords          : kbinterop kbprg OdbcHowto 
Version           : 97
Platform          : WINDOWS
Hardware          : x86
Issue type        : kbhowto

Last Reviewed: November 21, 1998