CS145 - Spring 2003
Introduction to Databases
Part 2: Oracle Features   --   Due Thursday May 15th
Warning: This is the first project part in which significant numbers of students will be putting significant load onto the Oracle system at the same time. Unfortunately it is possible the system will become much slower as the deadline approaches. We strongly suggest that you start early for your own benefit and convenience, and please be aware that we will not extend the on-time deadline because the system is slow.

Overview

This part of the project will introduce you to the PL/SQL database programming language, and to the constraints and triggers features in Oracle. You will also add a "current time" feature to your AuctionBase database.

Part A: Current Time

The original auction data that we provided for you in XML, which you translated into relations and loaded into your AuctionBase database in Programming Assignment 1, represents a single point in time, specifically one second after midnight on December 20th, 2001 ("Dec-20-01 00:00:01").

To fully test your functionality, and to simulate the true operation of an online auction system in which auctions close as time passes, we suggest that you maintain a fictitious "current time" in your database. Add a new one-attribute table to your AuctionBase schema. This table should at all times contain a single row (i.e., a single value) representing the "current time," which can be updated to represent time passing. (It's up to you whether you also want to permit backward time-travel.) Initialize the table by inserting the current time for the initial state of your database: Dec-20-01 00:00:01.

Note: If you want to input and output dates in Oracle using the same format as in the original XML auction data files, issue the command:

  ALTER SESSION SET NLS_DATE_FORMAT='MON-DD-YY HH24:MI:SS';
For more information see the Oracle Dates and Times help document.

Part B: PL/SQL

Before getting started, please read the help document Using Oracle PL/SQL. Take particular note of the section on how to turn on debug messages when compiling PL/SQL procedures.

For this part, you will be writing a procedure that computes the "bidding closure" for a specified seller. More precisely, for a particular seller we wish to construct the set of all bidders who placed a bid on one of the seller's items, or (recursively) on an item being sold by any of the bidders in this set. For example, if we wish to compute the recursive bidding closure of seller Homestar, and Marzipan placed a bid on one of Homestar's items and Pompom placed a bid on one of Marzipan's items, then Marzipan and Pompom would be in the recursive bidding closure of Homestar. Note that Homestar is not part of this closure.

Your procedure should take as an argument the user id of a seller, and insert the user id's of the individuals in the bidding closure into a relation. Be sure to test your procedure thoroughly. When you are confident that your procedure is working correctly, run your procedure on user 'westbur' and create a transcript of your output on the large data set (with the full list of individuals in westbur's bidding closure). Save this transcript as closure.script and save your procedure as closure.sql. Please include the command to create your closure relation as part of closure.sql.

Correctness check: Your 'westbur' query should return 87 rows on the large data set.

Part C: Constraints and Triggers

Constraints and triggers are covered in your textbook readings and will be the topic of lecture on May 7th. Before getting started with Part C, please also read the help document Oracle Constraints and Triggers. Please be very careful to note that constraints and triggers as supported in Oracle do not conform exactly to the SQL-99 standard, the lecture notes, or the textbook. You will need to read the help document carefully.

Please remember that constraints and triggers in Oracle do not conform to the SQL-99 standard, the lecture notes, or the textbook.

If the data in your AuctionBase system at a given point in time represents a correct state of the real world, a number of constraints are expected to hold. To get you started, here are a few possible examples, some of which depend on a particular schema:

Your job is to:
  1. Specify in English every constraint you believe should hold in a correct AuctionBase database, i.e., in a database that represents a viable state of the real world. Consider only constraints that go beyond what is already enforced in the schema, e.g., you do not need to specify that ratings are integers, if indeed you implemented them as such. However, other than simple schema-enforced type constraints, you should list every constraint you can think of.

  2. Choose at least five of your constraints from part (1) to implement in your system. Use the simplest possible mechanism to enforce each constraint, e.g., do not use triggers to enforce a unique key constraint or a simple attribute-level check. You should choose your five (or more) constraints so that at least one is implemented using referential integrity, at least one is implemented as a CHECK constraint, and at least two require triggers.

    For all cases other than triggers and referential integrity with an ON DELETE option, an error is raised automatically whenever a constraint is violated. For triggers, you may as part of the trigger(s) program a way of "repairing" a violated constraint automatically, or you may simply raise an error with the function RAISE_APPLICATION_ERROR as described in the Constraints and Triggers help document.

  3. Add the constraints and triggers to your full AuctionBase database. The three steps we suggest you take are:

    1. Use the ALTER TABLE command to add key (UNIQUE), referential integrity, and CHECK constraints. See the Oracle 9i SQL and Constraints and Triggers help documents for examples. The ALTER TABLE command will fail if you try to add a constraint that does not hold on the current database.

    2. Unlike constraints, when you add a trigger to the database, the condition part of the trigger is not checked (i.e., there is no "retroactive" firing of the new trigger). Thus, any of your constraints that are enforced by triggers must be checked separately at the time you install your triggers, in order to ensure that the database begins in a consistent state. From that point on, the triggers should ensure that the constraints continue to hold whenever the database is modified. Write and execute a set of queries to check that all constraints being enforced by triggers hold in the current state of the database. Often the easiest way to write constraint-checking queries is to create queries that return an empty result if and only if the corresponding constraint holds.

      At this point, if any constraints do not hold, then either your constraints are inappropriate or your database is in an inconsistent state. Stop now and fix the problem!

    3. Create all of your triggers using the CREATE TRIGGER command described in the Constraints and Triggers help document. (If you get an error message "Warning: Trigger created with compilation errors.", type "SHOW ERRORS" to see what's wrong.)

    Note that if you recreate your entire database from scratch, you may create your tables with the key, referential integrity, and CHECK constraints already in place, in which case these constraints will be checked on data load. You probably will need to be careful that you load your tables in the correct order for referential integrity checking, or you can use deferred checking as described in the Constraints and Triggers help document. If you take this approach, you still need to follow steps 2 and 3 above for triggers.

  4. For each constraint, demonstrate at least two database modifications relevant to the constraint: at least one that violates the constraint and one that doesn't. Similarly, for each trigger, demonstrate at least two database modifications that activate the trigger (i.e., that match the trigger's ON event): at least one where the trigger condition is satisfied and the trigger action executes, and one where the trigger condition is not satisfied so the trigger action does not execute.

  5. Are there any database modifications that can violate more than one of your constraints simultaneously? If so, demonstrate what happens.

A note about transactions

This is the first time you will be doing significant updating to a large Oracle database. Assuming you want your database updates to persist, you may need to think just a little bit about transactions. Transactions are covered in your textbook readings and are the topic of lecture on May 12th. Please read the section on Transactions in the Oracle 9i SQL help document.

Part C Submission

For this part of the project you will create a large file called constraints.txt. As the first part of your constraints.txt file, specify your list of constraints from part (1), in English, similar to the bullet list of examples above.

Following the English list, you will illustrate the five (or more) constraints that you chose to implement. For each constraint, repeat the English description and then list all items (a) through (e) as follows, carefully labelled:

(a) The Oracle constraint definition(s) (CREATE TRIGGER command(s), ALTER TABLE command(s), etc.). If the constraint is specified in the schema definition then include the entire CREATE TABLE command. List the commands in this part, but do not run them.

(b) One or more sample database modifications (SQL statements) that are relevant to the constraint but do not violate it. Include any commands you used to defer constraint checking or to disable/enable triggers. List the commands in this part, but do not run them.

(c) One or more sample database modifications (SQL statements) that are relevant to the constraint and do violate it. Include any commands you used to defer constraint checking or to disable/enable triggers. List the commands in this part, but do not run them.

(d) A transcript showing:

  1. The successful definition of the constraint using your part (a) commands.
  2. That the existing large database satisfies the constraint, or that you were able to reload the database with the constraint in place. (For example, for a constraint that all bid prices are positive, you might run the query "SELECT * FROM Bids WHERE Price <= 0" and show that the result is empty.)

  3. The execution of the updates in parts (b) and (c).
Thus, your constraints.txt file should look like this:
  [English descriptions of all of the constraints you can think of]

  [Constraint 1]
  (a) [...]
  (b) [...]
  (c) [...]
  (d) 1. [...]
      2. [...]
      3. [...]

  [Constraint 2]
  (a) [...]
  (b) [...]
  (c) [...]
  (d) 1. [...]
      2. [...]
      3. [...]

    ...

What to submit

Your submission directory should contain only the following 4 files :

closure.sql PL/SQL program for Part B
closure.script Transcript for Part B
constraints.txt Your constraints file as specified above
README Your README file with any special instructions or notes (this may be empty if you do not have anything special to say).

From your submission directory, execute the command

/usr/class/cs145/bin/submit

Follow the instructions exactly. If you must resubmit, run the command

/usr/class/cs145/bin/submit -replace

If you have any problems, please send mail to cs145@cs.stanford.edu. Remember that points may be deducted if you do not follow the submission procedures exactly as specified, including file naming and contents.