Delivering pizza with a dump truck Developers trying to move data from one place to another are confronted with a variety of choices. Usually the “places” include a component run on a server somewhere and a remote client application. As I see it, there are a number of problems developers face when trying to solve this problem: What delivery vehicle should be used. All too often we choose an oversized delivery vehicle for the situation—sorta like delivering pizza with a giant truck. It works, but scares the customers not to mention the neighbor’s dog. We also tend to return far more data than the customer can consume before it starts getting cold. This is like delivering pizza in anticipation of orders the customer is likely to place next week. The other problem relates to the others but is a little more complex. Developers and the interfaces we choose have started packaging the data we order in wrappers that describe the information to the finest detail. This is like getting our pizza in a package that describes the crust, each mushroom, pepperoni, and anchovy and how the ingredients were gathered, processed and prepared. This technique is especially useful when you need to deliver pizza to space aliens that might not know what they are getting and need to know how to consume it. So let’s take a longer look at the problem and the choices you have to solve it. First, consider the type of data you want to move. If you simply want to pass something simple back to the client, consider a simple approach. That is, if you only want to pass back a string of characters, a “yes” or “no” or a number, then you don’t really need a complex data structure to do so. Yes, more complex data structures are handy if the client needs to know how to deal with the data and does not really know what to expect. For example, if you have customers that tell you to deliver something hot and Italian, you might want to include a description and re-heating instructions as well as legal disclaimers—unless you send out a sweaty tenor. So, this means if you need an ADO Recordset object to define the data being transmitted, use a Recordset. But you have other alternatives that might be far easier to construct, transmit and parse on the other end. For example, Visual Basic has a number of new extensions that know how to deal with delimited strings. A typical Recordset can take 100K to store a few rows while a delimited string contains very, very little overhead—one to three extra characters per field and two extra characters per row. Transmitting a Recordset mean that your client can use ADO to move around in the rows, filter, sort and find wanted rows in the data once it arrives. But these approaches begin to smack of the second problem. Why return data that the customer will discover is cold and stale when they finally get to it? When working with static data (with a long shelf life), sending out extra can seem like a good idea, but if the client never uses it, you have wasted network, server and client resources gathering, packaging and transmitting it. Many, more successful applications have found that transmitting rows “just in time” and “only as needed” works better than simply dumping 100 boxes of pizza on the doorstep. The following text is an example of a delimited string result set. I replaced the tab characters with the text “<tab>” for readability. As you can see, all we get here is data. This approach assumes you know what the data you asked for is going to look like. 3<tab>Boddie, John<tab>1947<tab>0-1355423-9-1<tab>1996<tab>0-1355423-9-1<tab>Managing a Programming Project : People and Processes 244<tab>Vaughn, William<tab>1947<tab>1-5561590-6-4<tab>1995<tab>1-5561590-6-4<tab>Hitchhiker's Guide to Visual Basic & Sql Server -- Fourth Edition (Book and Disk) Not all situations can be solved by sending a simple delimited string. Sometimes the client needs to be able to change the data and sometimes (but not nearly always) an updatable cursor is called for. In this case, the ADO Recordset seems to fit the bill. In many respects, the ADO Recordset object is really quite sophisticated. It contains a wealth of information about the data and where it came from. Some of this information can be essential when it comes time to update the data in the original source. RDO (rdoResultset) and ADO Recordset objects also support the concept of “multiple” resultsets so you can execute a complex stored procedure and return one, two or twenty resultsets and use an automorphing Recordset object to refer to the first and each subsequent result set. The ADO Recordset object also supplies a bevy of properties that describe a number of complex aspects of the data structure—often making it possible to identify the root source of the data. However, some applications need something even more generic and less binary than an ADO Recordset—especially when updatability is not that important. That’s where XML comes in. XML (Extensible Markup Language) is touted as the new universal format for data on the Web. XML allows developers to describe and deliver rich, structured data from any application in a standard, consistent way. XML is an internationally recognized format for recordset (schema + data) persistence. Wellformed XML can be read by anyone, in any language any where in the world. Simply put, XML is yet another way to pass data from one point to another and carry with it and some of the information you need to know about the dataset to view it. You don’t need ADO to decipher an XML data structure— just an XML parser. No, there’s nothing in an XML data structure that tells you where the data came from, just what it looks like, so it will be tough to create an update statement based simply on an XML dataset. In addition, you can’t tell that the data was drawn from table X or Stored Procedure Y. When working with ADO, you can save Recordsets to an XML stream (in ADO 2.5) or a file (ADO 2.1). This section refers to ADO’s adPersistXML format, aka XMLData. This is also referred to as a canonical format. So the XML structure could look like this or any other well-formed XML. However, ADO understands how to read this. XML data structures are broken into sections that first define the data rows—at least the names of the fields (columns) and their datatypes. This is the </s:Schema> section. The following section (</rs:data> contains the data itself. But each and every field is tagged so the data structure repeats the field names over and over—once in each row as shown here. <rs:data> <z:row Au_ID="244" Author="Vaughn, William" Year_Born="1947" ISBN="1-5561590-6-4" Year_Published="1995" Expr1="1-5561590-6-4" Title="Hitchhiker's Guide to Visual Basic & Sql Server -Fourth Edition (Book and Disk)" /> <z:row Au_ID="5386" Author="Viescas, John" Year_Born="1947" ISBN="1-5561519-8-5" Year_Published="1989" Expr1="1-5561519-8-5" Title="Quick Reference Guide to Sql" /> <z:row Au_ID="5386" Author="Viescas, John" Year_Born="1947" ISBN="1-5561523-7-X" Year_Published="1990" Expr1="15561523-7-X" Title="dBASE IV (Programmer's Quick Reference Series)" </rs:data> This permits a degree of flexibility in that you can define an XML dataset that could potentially contain different fields for each row—but multiple resultsets are not (yet) supported from Visual Basic or ADO. My point is that we as developers need to build solutions using the right packaging with the right contents with the right amount of useful information. Don’t send more than needed—no more fields or data description language (DDL) or rows than the customer can consume at a sitting. This means use a bicycle when the pizza place is close and hold the anchovies.