SQL/DML by Example
A guide to using SQL/DML in practical applications
by Mark Henri
This is code that I've used with Microsoft Access from
an ODBC connection. It will work on other databases with a little
tweaking.
Creating Tables
create table TransactionDetail (
Id counter,
Patient varchar(50),
Item integer,
ArdetItem integer,
`Date` date,
TransactionType integer,
Description varchar(100),
Acctno integer,
Orthodontist integer,
Office integer,
Amount currency,
DTD integer,
MTD integer,
constraint thePrimaryKey Primary Key(Id)
)
*Note the counter type above. This creates an autonumber column in Access.
Also, the reserved word Date is used as a column name. Though I don't
encourage this practice, it's sometimes necessary when converting from a
legacy database.
create table Application (
ComputerName varchar(50),
Application varchar(100),
LoggedOn date,
LoggedOff date,
constraint Index1 primary key(ComputerName, Application)
)
Adding Indexes
I like index names to describe the table and column. Since they're
not referenced directly, it doesn't matter if they gat a little
verbose.
create index ARLogPatient on ARLog(Patient)
Adding Columns
alter table rparty add Phone1 text(25)
Dropping Columns
alter table patient drop address1
alter table patient drop address2
alter table patient drop city
alter table patient drop state
alter table patient drop zip
Dropping Tables
drop table newdeposit
drop table newsplit
Expanding a Column in a Table Without Disrupting Live Data
--widen the phone number for a table
alter table rparty add newphone text(50)
update rparty set newphone = phone
alter table rparty drop phone
alter table rparty add phone text(50)
update rparty set phone=newphone
alter table rparty drop newphone
Miscellaneous
This is a bunch of stuff I did to my DVD database. Notice the
string extracts near the bottom. ODBC is a pain with it's
{fn } tags.
alter table movie add genre2 text(50)
update movie set genre2 = genre
select genre2, {fn locate(',',genre2)}, left(genre2,{fn locate(',',genre2)}-1) from movie where {fn locate(',',genre2)} > 0
update movie set genre2 = left(genre2,{fn locate(',',genre2)}-1) where {fn locate(',',genre2)} > 0
select genre, subgenre from movie
update movie set genre2 = 'Sci-Fi' where genre2 like 'Sci%'
alter table movie add genre3 text(100)
update movie set genre3 = genre
update movie set genre = genre2
alter table drop genre2
alter table movie add subgenre text(100)
update movie set subgenre = genre3
alter table movie drop genre3
alter table movie drop genre2
alter table movie add temp text(100)
update movie set temp = subgenre
update movie set subgenre = left(subgenre,{fn locate(',',subgenre)}-1) where {fn locate(',',subgenre)} > 0
select subgenre, {fn substring( subgenre, {fn locate(',',subgenre)}+1 , 100} from movie where {fn locate(',',subgenre)} > 0
select {fn substring('abcde',3,2)} from movie
update movie set subgenre = {fn substring( subgenre, {fn locate(',',subgenre)}+1 , 100} where {fn locate(',',subgenre)} > 0
update movie set subgenre = {fn ltrim(subgenre)}
General Rules of Design
- Construct Primary Keys From Non-Duplicated Data
If you can find a unique key such as the datatimestamp
in combination with something else this is preferable
to using sequences. The problem with sequences is that
they eventually have gaps and/or wrap around. This means
additional maintenance later. For example, using a
datetime stamp combined with an IPAddress is guaranteed
to be unique for all time.
- Create Meaningless Keys
What I mean is don't put the office number into the key
with the customer initials. Eventually, the customer
will change locations and then your entire keyset becomes
meaningless (because you can't trust it's meaning on any
others).
- Allow For Unlimited Items
If you're going to allow multiple phone number, don't
stop at some arbitrary limit in a flat file.
- Use Words Instead of Codes
Words like high, medium, low are superior to numeric
constants such as 3, 2, 1 which must be interpreted by
programmers and users.
- Use Meaningful Column Names
Names like LastName, EnteredOn, LastBilledOn are superior
to LN0001, ENT02, BD002. I know this seems obvious but
I've worked for major software companies that couldn't
see the rediculousness of the latter approach.
- Use Server Side Processing
If you want blazing speed for your batch processes,
create stored procedures for them. If your database
doesn't support stored procedures (such as MySQL), create
processes that run on the server for all batch operations.
The disadvantage of stored procedures is having to
maintain the code because it's now separate from the
main application code.
- Avoid Triggers
Only use triggers for debugging and tracking security
issues. Remove them as soon as you've found what you're
looking for. They seriously degrade system performance.
Mark Henri has been doing database design and implementation since
1984. His current favorite databases are Oracle and MySQL. "I like
Oracle for it's sheer robustness and reliability. It has the most
features of any." But he's not a snob. "MySQL is a major threat
because of it's ultra low cost and super performance." Both are a
good choice depending on the needs of the customer."