Archives
 
 
 
  Special
 
 
 
  About Us
 
 
 

Newsletter
Free E-mail Newsletter from BYTE.com

 
    
           
Visit the home page Browse the four-year online archive Download platform-neutral CPU/FPU benchmarks Find information for advertisers, authors, vendors, subscribers Request free information on products written about or advertised in BYTE Submit a press release, or scan recent announcements Talk with BYTE's staff and readers about products and technologies

ArticlesUsing ODBCDirect's Advanced Features


September 1997 / Core Technologies / Using ODBCDirect's Advanced Features

A look at back-end database access for Office 97 applications and batched server updates.

Rick Dobson

I launched a discussion last month of ODBCDirect, a client/server technology that especially targets Office 97 developers. It provides at least three benefits to corporate developers.

First, it delivers more remote data-processing flexibility in a smaller footprint than going through Access's database engine, Jet. Second, ODBCDirect's tight integration with the Office 97 applications enhances the worth of Data Access Objects (DAO) and Visual Basic for Applications (VBA) programm ers by letting them serve up back-end data to corporate desktops like never before. Third, the licensing of VBA to dozens of third-p arty firms broadens the selection of routes for tapping ODBCDirect's power. This article builds on last month's Programming column by going beyond the basics to showcase a collection of advanced ODBCDirect features.

How does ODBCDirect contrast with other back-end database-connectivity options? ODBCDirect links to ODBC data more quickly and with fewer resources than going through Jet. However, Jet has its own special benefits, including heterogeneous database joins, bound forms, and controls. Developers must choose which projects will benefit most from ODBCDirect's speed and finer-grained functions versus Jet's traditional and easy route of ODBC access.

From Back End into Excel

My first sample application drops data from a SQL Server data set into an Excel spreadsheet. This shows how to drop back-end data into friendly enviro nments and illustrates interesting ODBCDirect development issues. While this example works with Excel, it sets up the ODBCDirect workspace and connects to the Pubs database with the same code I used last month for Access. This sharing of common code among Office 97 applications shows VBA's ability to dramatically reduce development time.

Two additional points merit attention besides the actual code. The only way to derive the benefit of ODBCDirect's small footprint is to use it outside Access. This is because Access loads Jet, even when you use ODBCDirect workspaces exclusively. For Excel or other applications that rely on ODBCDirect to avoid using Access inadvertently, you must reference the DAO 3.5 Object Library explicitly. In Excel, choose the Tools menu and select References. Then scroll to Microsoft DAO 3.5 Object Library and select its check box before closing the References dialog box, as shown in the screen .

The listing "From the Back End to Excel" begins by creating a string, stSQL , that contains the SQL for the data that it will download. A querydef, qdfYTD , relies on this string. The OpenRecordset method for the querydef returns the rows from SQL Server to the workstation's local recordset, rsYTD . After some spreadsheet maintenance, a While...Wend loop copies the values from the DAO recordset to Sheet1, the active sheet. Offset methods move the active cell to the proper spreadsheet location before a simple assignment statement performs the copy.

Cached, Batched Updating

One of ODBCDirect's more advanced features is its ability to perform cached, local updating of server-based data. ODBCDirect introduces batch optimistic updating. This facilitates the downloading of a recordset that's used to cache the local updates and the subsequent batch updating of those records on the server.

Other database users can edit records between the time you download your records for local processing a nd upload them back to the server. When the edits of others conflict with yours, the two versions collide on the server. ODBCDirect includes several built-in mechanisms for facilitating collision reconciliation.

First, batch optimistic updating automatically detects, counts, and marks collisions. Second, ODBCDirect provides simple techniques for overriding other changes with your own. Third, properties permit you to compare and contrast the various values of a collided field on a record. The example illustrates how to get started coding this capability.

Batch optimistic updating requires a minimum of six steps. First, you create an ODBCDirect workspace. Second, set the workspace's DefaultCursorDriver property to dbUseClientBatchCursor . Third, forge a link to a server database via an ODBCDirect connection or database object. Fourth, create a local recordset based on server-based data with the OpenRecordset method. You must specify dbOptimisticBatch for the l ockedits argument. Fifth, perform edits as necessary to the local recordset cache. Last, use the recordset's Update method with a dbUpdateBatch type argument.

The second, fourth, and sixth steps are critical ones. Batch optimistic updating requires that you set the DefaultCursorDriver property to dbUseClientBatchCursor . The use of dbOptimisticBatch for the lockedits argument in step four enables batch optimistic updating. The dbUpdateBatch parameter for the type argument in step six instructs ODBCDirect to send the local cache to the server as a batch of records.

My code excerpt "Cached, Batched Updating" has four code blocks. First, it makes the back-end server connection. I show this code so you can see precisely how and where to specify the DefaultCursorDriver workspace property.

The second block creates a recordset, rsSales , and completes the invocation of batch optimistic updating by referencing dbOptimisticBatch in an OpenRecordset method. You also need a recordset type that is not read-only, as the code shows using the dbOpenDynaset argument.

The third code block performs a series of edits to the cached data in its While...Wend loop. The Update method inside the loop caches the changes locally. The Update method outside the loop sends these updates from the local cache to the server.

The fourth code block illustrates a simple collision-reconciliation rule. It overwrites all collisions on the server with those from the local cache. After the initial batch update at the end of the third block, ODBCDirect marks those records in the local cache that collide with the server. It also retrieves the conflicting server values. The code shows how to copy data from the local cache to the server and then update them en masse. The last line uses a dbUpdateBatch argument that sends all the changes to the server. The Tr ue parameter forces those changes over the server data.

Asynchronous Operations

ODBCDirect can open asynchronous connections, querydefs, and recordsets. ODBCDirect also lets you move asynchronously to the last record in a recordset. Each of these functions can take a while: Consider moving to the last of 2,000,000 records -- on a remote server.

ODBCDirect's asynchronous capabilities let you use this time locally while you are waiting for a remote server to respond to a command. However, you will have to write code that checks when the asynchronous activity concludes. An object's stillExecuting property permits you to run tasks while you wait for the property to turn false or cancel the operation if it takes too long.

Always wrap your updating code statements in a transaction when running tasks that can modify a remote database. This permits your program to "roll back" any completed updates if the task gets canceled, or if it didn't complete the operation within a speci fied maximum duration.

ODBCDirect offers powerful ways to add value to back-end databases. VBA and DAO developers have new opportunities to serve up back-end data to users in familiar, friendly environments. I hope Microsoft sees fit to upgrade ODBCDirect with events, so that it's easier to manage asynchronous functions.


ODBCDirect Features


From the Back End to Excel


'Create row-returning recordset from server
stSQL = "SELECT titles.title_id, titles" & _
    ".title, titles.ytd_sales FROM titles"
Set qdfYTD = conPubs.CreateQueryDef("", _
    stSQL)
Set rsYTD = qdfYTD.OpenRecordset
'Insert column headings
Sheets("Sheet1").Cells(1, 1).Value = "Title"
Sheets("Sheet1").Cells(1, 2).Value = _
    "YTD_Sales"
Sheets("Sheet1").Cells(2, 1).Activate
'Copy rows
While Not rsYTD.EOF
    ActiveCell.Value = rsYTD!Title
    ActiveCell.Offset(0, 1).Activate
    ActiveCell.Value = rsYTD!ytd_sales
    ActiveCell.Offset(1, -1).Act
ivate
    rsYTD.MoveNext
Wend


Cached, Batched Updating


'Make connection
Set wspPubs=CreateWorkspace("PubsSession", _
    "admin", "", dbUseODBC)
wspPubs.DefaultCursorDriver _
    = dbUseClientBatchCursor
stConnect = "ODBC;DSN=Pubs;UID=sa;PWD=;" & _
    "DATABASE=Pubs"
Set conPubs = wspPubs.OpenConnection _
    ("", , , stConnect)
'Create cached recordset
stSQL = "SELECT Stor_id, Ord_num," & _
    "title_id, qty FROM Sales"
Set rsSales = conPubs.OpenRecordset(stSQL, _
    dbOpenDynaset, 0, dbOptimisticBatch)
'Modify local cache and attempt
'to update server
While Not rsSales.EOF
    rsSales.Edit
    rsSales!qty = rsSales!qty + 3
    rsSales.Update
    rsSales.MoveNext
Wend
rsSales.Update dbUpdateBatch
'Force in changes even if there
'are conflicts
intIterations=rsSales.BatchCollisionCount _
    - 1
For j = 0 To intIterations
    rsSales.Bookmark = _
        rsSales.BatchCollisions(j)
Next j
rsSales.Update dbUpdateBatch, True




Explicit Use

screen_link (43 Kbytes)

You must explicitly reference DAO 3.5 to use ODBCDirect outside of Access.


Rick Dobson, Ph.D., is president of CAB, Inc., a database and Internet development consultancy. You can send e-mail to him at Rick_Dobson@msn.com .

Up to the Core Technologies section contentsGo to previous article: The Pentium II RevealedSearchSend a comment on this articleSubscribe to BYTE or BYTE on CD-ROM  
Flexible C++
Matthew Wilson
My approach to software engineering is far more pragmatic than it is theoretical--and no language better exemplifies this than C++.

more...

BYTE Digest

BYTE Digest editors every month analyze and evaluate the best articles from Information Week, EE Times, Dr. Dobb's Journal, Network Computing, Sys Admin, and dozens of other CMP publications—bringing you critical news and information about wireless communication, computer security, software development, embedded systems, and more!

Find out more

BYTE.com Store

BYTE CD-ROM
NOW, on one CD-ROM, you can instantly access more than 8 years of BYTE.
 
The Best of BYTE Volume 1: Programming Languages
The Best of BYTE
Volume 1: Programming Languages
In this issue of Best of BYTE, we bring together some of the leading programming language designers and implementors...

Copyright © 2005 CMP Media LLC, Privacy Policy, Your California Privacy rights, Terms of Service
Site comments: webmaster@byte.com
SDMG Web Sites: BYTE.com, C/C++ Users Journal, Dr. Dobb's Journal, MSDN Magazine, New Architect, SD Expo, SD Magazine, Sys Admin, The Perl Journal, UnixReview.com, Windows Developer Network