ColdFusion in Context: Downsizing Data to Access

Suppose you want to build a demo based on a full application that runs in a large database engine such as Oracle or Microsoft SQL. Perhaps the demo needs to go on a laptop that will handle Microsoft Access but not anything larger. Perhaps the entire demo and its data must fit on a floppy. This tip helps you move data structures and content into Access for situations such as this.

Start with Access Datatypes

Major database engines can generate data description language: scripts which could be used to create the tables in their databases in the first place. The challenge is in modifying these "create table" scripts to produce comparable structures in Microsoft Access. Just as with any maze, the easiest way to solve it is to start with the end and work backward. Here are some common data types that can be interpreted directly by Access if you paste them into a query. See what's available and reasonable to use in Microsoft Access and then determine how these datatypes compare with the source of the data. Unless you're pressed for space, You might want to avoid the following datatype when moving data between database engines.

Consider Conversions

Now that you know what's available, here are some conversions to consider. Note that the script that the original database would have used to create its tables will probably enclose the datatype in square brackets, and you'll have to at least remove the brackets to make Access happy. Bearing that in mind, here are suggested conversions.

Use the Scripts

Open a copy of the script in Microsoft Word or a word processor of comparable power so you can replace all "\[numeric\] \(*\)" in wildcard mode with "single". (The backslash escapes special characters that you want treated as normal characters during the wildcard search and replace.) Make the remaining conversions above in a similar manner. If you see other things that Access won't like (such as "[dbo]." prefixes and " ON [PRIMARY] GO"), get rid of them while you're at it.

Open Microsoft Access. Get to the page that lets you enter an SQL query. Then paste the script for one table into this page, execute it, take care of any highlighted problems, and repeat until you've created all the tables you need. This is much faster than doing the task manually. You can easily add ten tables per minute this way.

Copy the Data

When using Microsoft SQL, if you poke around long enough in this program or its supporting programs, you'll find an option that lets you export data to an Excel spreadsheet. Do NOT use any Excel version lower than version 5. Version 5 will place each table in a separate page of the workbook and will let you export the entire database at once (if tables don't exceed Excel's limitations). However, version 4 and below will try to use named ranges in a single page and will usually fail unless you export one table at a time, a tedious process.

When using Microsoft Access, import the spreadsheet data one worksheet at a time to the tables you've created. This is also a fast process.

If you have to use text files for transfer, you may have to load dates converted to text into text fields, then convert them back to dates. The spreadsheet route is faster if it's available to you.

Hints

Most of your application's queries will now run as is. As you're tweaking the ones that don't, here are a few things to keep in mind:

- If you want to use mostly the same code for both database engines, one way to make sure the changes you make for an Access demo aren't run during production is to limit their execution to the local host (127.0.0.1). For example:

<cfif left(cgi.server_name, 3) is "127">....
... Of course, you would probably reverse the test to take the production case first.

- You can't take a field being produced by the query you're trying to build and put it within a ColdFusion function; because, the field doesn't exist yet! This means that you need to figure out the Access way of handling dates (for example) or handle the conversion completely outside the database.

- A common problem that comes up is how to compare the current date/time with a date in the database:

-- The MS SQL way uses native database functions to get the current datetime and make the comparison to see if an hour has elapsed; the database handles both processes:

where (DateDiff(hour,SubmitDate,getdate()) > 1)
-- An Access/ColdFusion way uses ColdFusion to subtract an hour from the current datetime and then lets the query compare the field with that new result:
where SubmitDate < #dateAdd("h",-1,now())#

- Access is said to be less restrictive than other engines. However, in this context, you'll find it to be more restrictive.

-- When you use the scripts above to define a field as not null, then you must supply a value for the fields when you insert a new record. MS SQL lets you leave them undefined; Access doesn't.

-- If the code uses variables for column names, note that Access doesn't want you to alias a field with its own name. For example, using variables that evaluate to a pair like this this is a no-no:

<--- bad code ---> select SubmitDate as SubmitDate

- Access handles inexact matches differently from other database engines. For example, you'll probably replace a construct like "charindex('#ucase(attributes.VendorEmail)#', upper(Email)) <> 0" with "instr(Email, '#attributes.VendorEmail#') <> 0" when moving from another database engine to Access. (The "like" function syntax varies and would be slower than a solution like this.)

- Generally, when you're having trouble with a difficult construct, the problem is usually something simple such as the differences above. Before you give up on a difficult construct, re-check the basics (such as data types).

- Access does handle joins differently from other database engines. Fortunately, you can use Access to construct the join you need by dropping and dragging fields and then can copy the resulting SQL to your application.

Just getting the data into Access is a worthy first step. Once you've done this, enough of your application will work that you can figure out the rest. This will give you a floppy-size demo that can make your point on the road. =Marty=