Managing your Database - SQL
Now that you've designed the perfect database, you need to create and manage it. IBM developed a "Structured English Query Language", which was later shortended to "Structured Query Language" or simply, SQL. The first commercial version was released in 1979. The chances are, that if you have created a database, the best way to interrogate it is through SQL. But SQL is much more than this. SQL allows you to completely manage your database! The major reasons to use SQL are:
Before we begin, note that instructions in SQL are case-independent - SELECT is regarded as being the same command as select. This doesn't imply that the data in SQL are case-independent. It's good practice to treat everything as if it were case-sensitive, as in any grown-up programming language. Enough said. Let's get down to brass tacks! Different Standards?The initial ANSI/ISO standard for SQL was published in 1986, the second in 1989. Perhaps the defining standard (and one to aim for) was SQL-92 (occasionally referred to as SQL2). Surprisingly, most commercial versions of SQL are still, nearly ten years later, only marginally SQL-92 compliant, even such biggies as Oracle. The "most" SQL-92 compliant RDBMSes we know of are firstly the tiny Ocelot, and secondly postgreSQL, both of which are available in 'free' versions. Needless to say, Microsoft has gone its own merry way in producing a variety of less-or-more compliant products, perhaps the best of which is the somewhat pricey SQL server, and the worst "Access". One can even (at extreme personal risk!) talk to the "Jet Engine" behind Access using simple products such as Visual Basic!Fairly recently, ANSI/ISO have released SQL-99. This is an extension of SQL-92, has been widely embraced (at least in concept) but the practical impact of these extensions has still to be felt. You can be sure that most commercial SQL applications are inching in the general direction of SQL3 (The other, 'more correct' name for SQL99). Note that ANSI/ISO expect to make money out of SQL-92 and -99. Don't expect to find legal copies of the full standard anywhere on the Internet, although if you search around enough, you'll certainly find "draft versions" of SQL-92 that are surprisingly like the final product. Also, don't expect the unabridged text of SQL-92 to be legible to you as a mere mortal. Rather buy a book that explains the arcana to you, unless you're a confirmed masochist! This tutorial should help with the basics, but you really need a good manual if you're serious about SQL. CheatsThere are many ways of bypassing SQL - a host of software applications exist that claim to free you from the onerous task of ever writing a line of SQL. If you can get them to work 100% of the time then:
All automated tools have their deficiencies. We think it's a rather good idea to learn SQL anyway. Empower yourself, and show off a bit! Goals - Aim High!Let's see what Dr Codd, who thought up relational databases in 1970, had to say about how a true relational database management system really should work! In about 1985, he put forward thirteen rules for an RDBMS, with the "Zeroth" rule determining the other twelve. Don't panic if you fail to understand them all on first reading - they're quite a headful, but well worth coming back to repeatedly! Here they are:(Okay, you can skip past these for now if you
really want to)
The above list is intimidating, but as you work through SQL, come back again and again to view it. I think you'll find that Codd's rules provide a glimmer of sanity, even in the most gloomy meanderings through the SQL maze. You'll find to your surprise (and perhaps delight) that even the august bodies of ANSI and ISO have occasionally tended to ignore Dr Codd, usually at our (not their) peril! Making tables in SQLThe usual approach to teaching SQL is to teach you the ubiquitous SELECT statement first. We think this is back-to-front, as you first need something to work on. Anyway, we just spent the previous page of our tutorial telling you how to design databases, so why not get down to some practical examples? We'll use the create statement as a springboard to introduce us to most of the important commands in SQL!CREATEGenerally in SQL (and surprisingly for a computer language) commands are logically named and easily remembered! As it's name suggests, CREATE makes things. You say things like
create table tablename (
a list of columns
);
to (surprise, surprise) create a table. NOTE the syntax - the (parenthesis) surrounding the list of columns, and especially, the semicolon after the end of the statement. Leave these out, and watch things break horribly. Okay, often all you get is an obscure error message, but watch out! There's something hidden in the above statement! What is it? Answer: the format of a a list of columns. To learn this we need to digress a bit - we need to find out about data types in SQL, and how we express them. But before we begin, let's clear up a few trivia:
Okay, here's our large table of data types (Don't get scared, simply concentrate on options in boldface):
Let's say we wish to create a table of Drugs, with the following fields:
Here we probably only need to use two data types: varchar for the first three columns, and a decimal format for the size. We prefer to avoid integers of uncertain size (although they would almost certainly be OK over here) and use something like decimal(precision,scale), where precision refers to the total number of significant digits, and scale the number of digits to the right of the decimal point. For the size of a tablet, we would be happy with values from say 0.01 mg to perhaps a few grams (!), so we might use decimal (7,3) just to be on the safe side, allowing us the range of 9999 milligrams down to 1 microgram. (Hmm, can you think of exceptions?) Okay, here's our CREATE statement:
create table Drug (
DrugName varchar(32), TradeName varchar(32), Formulation varchar(10), SizeMg decimal(7,3) ); As is appropriate, let's now agonize over every definition. Is 32 characters enough to represent every single Drug Name and Trade Name we're likely to encounter? Is it too big? Likewise, for the formulation (we'll cheat here and encode things, so surely 10 characters is too generous). We've already pondered SizeMg, but have we pondered enough? Let's consider something more serious. Which column will we use for the primary key? Clearly the options are DrugName or TradeName, but do we really want to use either of these? Think about it - if we use DrugName, then many drugs (those with more than one TradeName) will not have unique primary keys. What about the trade name? Hmm, despite the reservations of medical purists, this seems a better option, but even this is a clumsy option, as wherever the trade name occurs in a table (there may be many tables) we will have to specify the long trade name! Another option is to generate a unique code for each drug as it is entered into the database (We could possibly even ship out the generic name to a separate table). Let's do something along these lines.. create table Drug (
More agonising. We'll allow a maximum of 999 999 999 drugs in our database -
can we ever forsee a billion or more different drugs in the database? No, never.
In most SQL systems, decimal(9) is a shorthand for saying
decimal(9,0), but we'll be pedantic.
create table Drug (
See how we've been smart, and called our constraint drug_ID_null, so
that when the inevitable happens and an error occurs, the system will
give us a name, and not just say what went wrong!
Okay, while we're about it, let's wantonly put in a default value for where
we don't know the Trade name, thus:
create table Drug (
Later on we'll explore in detail constraints on data values. For now,
just note how the unabridged version of not null has a constraint before it.
We'll also just use (without explanation) a constraint that ensures the
DrugID is indeed unique, thus:
create table Drug (
The use of constraint and the unique keyword should be pretty intuitive
But wait a bit, we still haven't created a primary key for our
table! In fact, a primary key is always unique and not null, and
specified as follows (we can dispense with our unique and not null conditions):
create table Drug (
But wait a bit! It's clear that the "Dosing" column in DrugRegimen corresponds to the "Dosing" column in DrugDosing. How do we tell SQL to make sure that the two correspond (for example, forbid insertion of a Dosing schedule into DrugRegimen that isn't defined in DrugDosing)? We use a foreign key, thus:
create table DrugRegimen (
Here again "regimen_refs_dosing" is just a convenient label that should pop up if the constraint is violated; we reference the table DrugDosing, and the (automatic) implication is that the column we are referring to within that table is the primary key, "Dosing"! Good practice - attaching comments!Comments in SQL generally start with two dashes (minus signs) thus:-- this is an SQL comment If you're going to insert comments into your SQL code (and you should) this is the style you might want to use. In some extensions (and SQL-99) you can use /* C-style comments, of which this is an example */, but this is not a component of core SQL. Things don't stop here. Because SQL proper says that a comment ends at the end of a line. Sounds simple doesn't it? Well actually, no! SQL insists that a parser must define its own "end of line character". A pity that few agree on what that EOL should be - some use a combination of carriage return and line feed (CR+LF), others LF alone. Some databases also allow you to, for example, attach comments to formed tables, and even columns, but this is not standard SQL. {for example, Oracle use the syntax:
comment on table tablename is 'This is a comment';
and
comment on column tablename.colname is 'A column comment';
Populating TablesInserting data into tables is straightforward. Let's say we've created the above tables, and now wish to populate DrugDosing with the following information:
We say:
insert into DrugDosing (Dosing, DoseMg, Frequency) values ('D1', 30, 'OD');
See how by specifying the names of the columns and then the corresponding values, we make the insertion independent of position. This is GOOD practice. (In addition, you may leave out values, and defaults will be filled in if they exist, although this practice should be avoided if at all possible). There are a few things you have to be careful of - see how text strings such as 'D1' are surrounded by 'single quotes'. If you fail to observe this simple rule, you are likely to get a long list of errors! Numbers don't need the quotes, and in well-constructed SQL parsers, must not have them! The simple rule is that the data types submitted must be compatible with the data types of the corresponding columns. {If you're into long-term pain, you can also leave out the column names and just submit values:
insert into DrugDosing values ('D1', 30, 'OD');
You must also have exactly the same number of items in the values
section as there are in
the table, and they must be in the correct order!
Although convenient, this approach should be avoided -
remember our dear friend Dr Codd and his Rule 9?
When we initially defined an RDB, we also said that column position
is irrelevant - here we violate that simple rule! 'don''t' Note that we have put in two single quotes, that is, two of these: '
Q2. Can I "insert" from one table to another (i.e. copy)?Certainly, but we won't cover such slightly more advanced statements until later.Check what you've done - a QueryMuch, perhaps most of SQL is centred around the select statement. Here, we give you just a flavour:select * from DrugDosing; will retrieve all columns and rows from the stated table, something along the lines of:
There's much, much more - we cover queries in detail on the next page of our tutorial. Deleting tables, and deletion within tablesSQL has a powerful (and potentially very damaging) ability to delete not only rows in tables, but even entire tables.Deleting a rowDANGER - do NOT say something like:delete from tablename - this will wipe out all the data contained in the table. Always include a where statement that qualifies what to delete! For example, if we had the table:
.. and for some peculiar reason we wished to delete the row with
the key D2, we could say:
delete from tablename where Dosing = 'D2' ;
Those of us who are used to C, Perl, C++, JavaScript or Java will be a bit startled
by the above, because the condition in these languages would be
something along the lines of (Dosing == "D2"). SQL is slightly
different, but one soon gets used to it! The bugger is when you are writing
in several languages, and jumping from one to the other.
Note that there are certain circumstances where such a deletion
will simply not work! Can you think of them? Yes, if other tables
contain references to our data item "D2", then deleting it would
be wicked, because the database would lose referential integrity! {Even more vicious is the Oracle-specific command truncate table which irreversibly
wipes out every row, without any chance of retrieving the data}.
drop table tablename ;
Note that, as for deletion of a row, if the table is referenced
by other tables, the deletion (as we've put it above) will fail.
1. Adding a columnThe syntax is intuitive. Here's an example:
alter table tablename add (
The data already present in the table won't be affected, but clearly each row will now acquire either a NULL where it intersects the new column, or a default value if you specified one. 2. Changing the data type for a columnIn standard SQL, there is no way (AFAIK) of directly changing a column's data type! (There are indirect ways, incorporating use of the cast operator {have an xref}).Generally, for all changes the correct way to make alterations is to create a NEW table with the column characteristics you require, and then copy from the old to the new table. The bottom line is that most SQLs will generally prevent you from doing something silly like truncating data. Note that if you really DO want to truncate column data, you have to use a specific operator to do so. {More of this later - xref!} {Even in noncompliant applications like Oracle,
there are stringent constraints on changing a column's type if it
contains anything other than NULLs. But if the column is unpopulated,
then you can:
The syntax is:
alter table tablename modify (
If a column contains NO NULLs, then and only then can a "not null"
constraint be added to the column.
The varchar and char column types can
be changed (one to the other and back) without any fuss! 3. Deleting a column!In standard SQL the way to remove a column is:alter table tablename drop columname restrict; Unfortunately, in several noncompliant SQLs, there is NO way in SQL to delete a column! You have to go through the rigmarole of making a new table, and then copying over all of the rest of the data (without the column you want to drop) into the new table. Take note that even in the standard, there is a long list of conditions under which such a drop will fail. {? more detail, cf G&P p 373}. 4. Renaming a tableStandard SQL wisely makes no provision for renaming a table. Can you think why?{Others haven't been so smart. For example, in Oracle
a table can be renamed using the rename statement thus:
rename table oldtablename to newtablename
Simple, innit? The big question of course is what happens to
all the references to the old table name?
.. and wish to alter the value 30 in the DoseMg column to say 40. How do we do this? One way is: update DrugDosing set DoseMg = 40 where Dosing = 'D1' ; Note how we chose to use as our selection criterion Dosing = 'D1', rather than say DoseMg = 30. Although the example is rather artificial, it emphasises the need to accurately identify the datum we wish to update. If we had a long list of DoseMg's, we might otherwise end up changing all matching (30mg) doses to 40, rather than just the single row we want! Also remember that the condition Dosing = 'D1' has quotes around the value 'D1' - otherwise SQL will look for some variable called D1, and either fail miserably, or do the wrong thing! Oops!This section has nothing to do with object-oriented programming. It's about the other sort of oopses - where you say "Oops, I shouldn't have done that". Frequently, you will use stronger language. Many 'grown up' databases will allow you to recover from such oopses, at least, a lot of the time. The technical term is a rollback so you won't be surprised to learn that you can restore things to their pristine state using the command:rollback; This does of course beg the question "What pristine state?" The answer is that everything after your last commit statement is rolled back - be prepared to do a lot of typing. We now know the 'opposite' statement to rollback - the one that prevents a rollback. It's of course: commit; Unfortunately, it doesn't end there (or should we say, begin here)! In some noncompliant databases, there are certain circumstances where an automatic commit occurs! {Unfortunate, but true. Here they are for Oracle:
Some crazy software just autocommits by default!
You can see that there is a vast potential for balls-ups implicit in all this commit/rollback stuff. What happens if you're sharing an altered table with somebody else, and then you rollback? Or do you not share information until committed? Think about it! Even more complex "intermediate" options exist as a part of the SQL standard, for example, the ability to save information at critical junctures (savepoint xyz; and rollback to savepoint xyz;).
|
Next - SQL queries in detail | Home |
Date of First Draft: 2001/11/11 | Date of Last Update: 2001/-/- | Web page author: jo@anaesthetist.com |