Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Answers To Marcia'S Dry Cleaning Project Questions: Customer

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 21

 ANSWERS TO MARCIA’S DRY CLEANING PROJECT

QUESTIONS
Assume that Marcia has created a database with the tables described at the end of Chapter 7:

CUSTOMER (CustomerID, FirstName, LastName, Phone, Email,)

ORDER (InvoiceNumber, CustomerID, DateIn, DateOut, Subtotal, Tax, TotalAmount)

ORDER_ITEM (InvoiceNumber, ItemNumber, Service, Quantity, UnitPrice,


ExtendedPrice)
SERVICE (Service, Description, UnitPrice)

Assume that all relationships have been defined, as implied by the foreign keys in this table list.

NOTE: Refer to the Marcia’s Dry Cleaning project questions in Chapter Seven, and use the solutions to
project questions E and G to create another copy of the database for this project named MDC-Ch08. Text
files with the necessary SQL commands are available at the Instructor’s Resource Center on the text’s
Web site (www.pearsonhighered.com/kroenke), but you may prefer that your students use their own
solution. Solution files for your use for this set of Marcia’s Dry Cleaning project questions are available
at the Instructor’s Resource Center on the text’s Web site (www.pearsonhighered.com/kroenke).

A. Create a dependency graph that shows dependencies among these tables. Explain how
you need to extend this graph for views and other database constructs such as triggers
and stored procedures.

CUSTOMER

ORDER

ORDER_ITEM

SERVICE

We would extend this dependency graph by adding objects to represent views, triggers and stored
procedures such that each additional object was connected by directed line segments to the tables
it was dependent upon. For example, we can add in the views that we created in the Chapter
Seven project questions as shown in the diagram on the next page.
CustomerOrderHistoryView

CUSTOMER
CustomerOrderCheckView

ORDER

CustomerOrderSummaryView ORDER_ITEM

OrderSummaryView

SERVICE

B. Using your dependency graph, describe the tasks necessary to change the name of the
ORDER table to CUST_ORDER.

Given that Microsoft’s SQL Server considers ORDER a keyword and wants us to put brackets
around the table name in our SQL commands (i.e., [ORDER]), this is a good idea.

We will use the original dependency graph with just the tables. Based on the dependency graph,
we can see that ORDER is dependent on CUSTOMER, and that ORDER_ITEM is dependent on
ORDER.

As described in Review Question 8.25 above, the process for changing a table name is:

(1) Create a new table with the new name.

(2) Alter any constraints, triggers, or views that may be affected.

(3) Copy all data from the old table to the new table.

(4) Create any needed foreign key constraints

(5) Drop the old table.

So we would:

(1) Create the table CUST_ORDER (note – the foreign key constraint between CUSTOMER and
CUST_ORDER can be created as part of the table creation process).

(2) Drop the foreign key constraints between CUSTOMER and ORDER and between
ORDER_ITEM and ORDER.

(3) Copy all data from ORDER to CUST_ORDER.

(4) Add the foreign key constraint between ORDER_ITEM and CUST_ORDER.

(5) Drop ORDER.


C. Write all SQL statements to make the name change described in question B.

(1) Create the table CUST_ORDER. Note that we will also create the foreign key constraint
between CUSTOMER and CUST_ORDER at this time – we’re used to doing this when we create
a new table.
CREATE TABLE CUST_ORDER (
InvoiceNumber Int NOT NULL,
CustomerID Int NOT NULL,
DateIn DateTime NOT NULL,
DateOut DateTime NULL,
Subtotal Numeric(8,2) NULL,
Tax Numeric(8,2) NULL,
Total Numeric(8,2) NULL,
CONSTRAINT CustOrderPK PRIMARY KEY(InvoiceNumber),
CONSTRAINT CustOrder_Cust_FK FOREIGN KEY(CustomerID)
REFERENCES CUSTOMER(CustomerID)
ON UPDATE NO ACTION
ON DELETE NO ACTION
);
(2) Drop the foreign key constraints between CUSTOMER and ORDER and between
ORDER_ITEM and ORDER, and add one between ORDER_ITEM and CUST_ORDER.
ALTER TABLE [ORDER]
DROP CONSTRAINT Order_Cust_FK;

ALTER TABLE ORDER_ITEM


DROP CONSTRAINT Order_Item_FK;

(3) Copy all data from ORDER to CUST_ORDER.


INSERT INTO CUST_ORDER (InvoiceNumber, CustomerID, DateIn, DateOut, Subtotal,
Tax, Total)
SELECT InvoiceNumber, CustomerID, DateIn, DateOut, Subtotal, Tax, Total
FROM [ORDER];

SELECT * FROM CUST_ORDER;

(4) Add the foreign key constraint for ORDER_ITEM.


ALTER TABLE ORDER_ITEM
ADD CONSTRAINT CustOrder_Item_FK FOREIGN KEY(InvoiceNumber)
REFERENCES CUST_ORDER(InvoiceNumber)
ON UPDATE CASCADE
ON DELETE CASCADE;
Note that the contents of the two tables are now identical:

If we look at the database diagram in the Microsoft SQL Server Management Studio, we can see
that CUST_ORDER is correctly inserted into the database, and ORDER is now disconnected.
(5) Drop the ORDER table.
DROP TABLE [ORDER];
D. Suppose that Marcia decides to allow multiple customers per order (for customers'
spouses, for example). Modify the design of these tables.

We will assume that the name change from ORDER to CUST_ORDER described above has been
made. If this hasn’t been done, the following steps would be the same – only the table name
would be different. We need to modify the relationship between CUSTOMER and
CUST_ORDER. So far it has been 1:N, but now it will have to be N:M. According to Review
Question 8.43 above, the steps to change a 1:N relationship to a N:M relationship are:

(1) Create the intersection table. Foreign key constraints can be done while creating the table or
as a separate step.

(2) Copy the values of primary keys from the tables for rows in which there is an existing foreign
key match between the tables.

(3) Drop the original foreign key constraint and foreign key column for the original child table.

So we would:

(1) Create the ORDER_CUSTOMER_INT. Since we normally create foreign key constraints
when we create a table, we will do the foreign key constraints between
ORDER_CUSTOMER_INT and CUSTOMER and between ORDER_CUSTOMER_INT and
CUST_ORDER while creating the intersection table.

(2) Copy the values of primary keys from the tables CUST_ORDER to CUSTOMER for rows in
which there is an existing foreign key match from CUST_ORDER to CUSTOMER into
ORDER_CUSTOMER_INT.

(3) Drop the original foreign key constraint and foreign key column for CUST_ORDER.

E. Code SQL statements necessary to redesign the database, as described in your answer
to question D.

ORDER_CUSTOMER_INT (InvoiceNumber, CustomerSK )

(1) Create the intersection table. Foreign key constraints can be done while creating the table or
as a separate step.
CREATE TABLE ORDER_CUSTOMER_INT(
InvoiceNumber Int NOT NULL,
CustomerID Int NOT NULL,
CONSTRAINT CustomerOrderIntPK
PRIMARY KEY (InvoiceNumber, CustomerID),
CONSTRAINT COInt_CustOrder_FK FOREIGN KEY(InvoiceNumber)
REFERENCES CUST_ORDER(InvoiceNumber)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT COInt_Customer_FK FOREIGN KEY(CustomerID)
REFERENCES CUSTOMER(CustomerID)
ON UPDATE NO ACTION
ON DELETE NO ACTION
);
(2) Copy the values of primary keys from the tables of the original child table for rows in which
there is an existing foreign key match from CUST_ORDER to CUSTOMER and the foreign key
is not null.
INSERT INTO ORDER_CUSTOMER_INT(InvoiceNumber, CustomerID)
SELECT InvoiceNumber, CustomerID
FROM CUST_ORDER
WHERE CustomerID IS NOT NULL;

If we look at the database diagram in the Microsoft SQL Server Management Studio, we can see
that ORDER_CUSTOMER_INT is correctly inserted into the database, but that the foreign key
relationship between ORDER and CUSTOMER still exists.
(3) Drop the original foreign key constraint and foreign key column for CUST_ORDER.
ALTER TABLE CUST_ORDER
DROP CONSTRAINT CustOrderCustomerFK;

ALTER TABLE CUST_ORDER


DROP COLUMN CustomerSK;

A final look at the database diagram in the Microsoft SQL Server Management Studio, we can
see that ORDER_CUSTOMER_INT is correctly inserted into the database,
F. Suppose that Marcia considers changing the primary key of CUSTOMER to (FirstName,
LastName). Write correlated subqueries to display any data that indicate that this
change is not justifiable.

CUSTOMER (CustomerID, FirstName, LastName, Phone, Email)

If (FirstName, LastName) is going to be a primary key, then the following functional


dependencies must exist:

(FirstName, LastName)  Phone

(FirstName, LastName)  Email

Which can be combined as:

(FirstName, LastName)  (Phone, Email)

A quick look at the data in the table (which only works because we have very little data) shows
that (FirstName, LastName) is not unique – there are two people named Betsy Miller.

Since the table still has CustomerID as a primary key, the easiest way to check is to test
uniqueness for (firstName, LastName). We did something similar is Review Question 8.7. Here
is a similar SQL statement:

For SQL Server:


SELECT C1.CustomerID, C1.FirstName, C1.LastName
FROM CUSTOMER AS C1
WHERE C1.LastName IN
(SELECT C2.LastName
FROM CUSTOMER AS C2
WHERE C1.FirstName = C2.FirstName
AND C1.LastName = C2.LastName
AND C1.CustomerID <> C2.CustomerID);
This detects the two occurrences of “Betsy Miller”:

We can also try a variation using CUSTOMER.FirstName, which obtains the same result.

For SQL Server:


SELECT C1.CustomerID, C1.FirstName, C1.LastName
FROM CUSTOMER AS C1
WHERE C1.FirstName IN
(SELECT C2.FirstName
FROM CUSTOMER AS C2
WHERE C1.FirstName = C2.FirstName
AND C1.LastName = C2.LastName
AND C1.CustomerID <> C2.CustomerID);
G. Suppose that (FirstName, LastName) can be made the primary key of CUSTOMER.
Make appropriate changes to the table design with this new primary key.

Given our results to Project Question F, this won’t work. SO, we’ll change the data set to allow
(FirstName, LastName) to be a possible primary key by changing the first name of CustomerID =
130 to “Betty”.
UPDATE CUSTOMER
SET FirstName = 'Betty'
WHERE CustomerID = 130;

We will assume that both the changes described in all the preceding questions have been made.
Therefore the current table design (schema) is:

CUSTOMER (CustomerID, FirstName, LastName, Phone, Email,)

CUST_ORDER (InvoiceNumber, DateIn, DateOut, Subtotal, Tax, Total)

ORDER_CUSTOMER_INT (InvoiceNumber, CustomerID )

ORDER_ITEM (InvoiceNumber, ItemNumber, Service, Quantity, UnitPrice,

ExtendedPrice)

SERVICE (Service, Description, UnitPrice)


Without moving the locations of existing columns in the schema (table design), if we make
(FirstName, LastName) the primary key of CUSTOMER we would have:

CUSTOMER (CustomerID, FirstName, LastName, Phone, Email,)

CUST_ORDER (InvoiceNumber, DateIn, DateOut, Subtotal, Tax, Total)

ORDER_CUSTOMER_INT (InvoiceNumber, FirstName, LastName)

ORDER_ITEM (InvoiceNumber, ItemNumber, Qty, Service, UnitPrice, ExtendedPrice)

SERVICE (Service, Description, UnitPrice)

[NOTE: IF we assume that NONE of the changes described in all the preceding project
questions have been made, the revised table design (schema) would be:

CUSTOMER (CustomerID, FirstName, LastName, Phone, Email,)

ORDER (InvoiceNumber, FirstName, LastName,DateIn, DateOut, Subtotal, Tax, Total,)

ORDER_ITEM (InvoiceNumber, ItemNumber, Service, Quantity, UnitPrice,

ExtendedPrice)

SERVICE (Service, Description, UnitPrice)

The steps that follow would be similar, but we would use ORDER instead of
ORDER_CUSTOMER_INT.]

H. Code all SQL statements necessary to implement the changes described in question G.

(1) Add the new columns to ORDER_CUSTOMER_INT to hold the foreign key values, but
allow these columns to be NULL at this point (there are many existing rows, and these columns
will initially be empty).
ALTER TABLE ORDER_CUSTOMER_INT
ADD FirstName Char(25) NULL;

ALTER TABLE ORDER_CUSTOMER_INT


ADD LastName Char(25) NULL;
(2) Add foreign key data to ORDER_CUSTOMER_INT.

First we’ll see what the current table data looks like, then add the data and finally look at the data
again.
SELECT * FROM ORDER_CUSTOMER_INT;
UPDATE ORDER_CUSTOMER_INT
SET ORDER_CUSTOMER_INT.FirstName =
(SELECT C.FirstName
FROM CUSTOMER AS C
WHERE C.CustomerID = ORDER_CUSTOMER_INT.CustomerID);

UPDATE ORDER_CUSTOMER_INT
SET ORDER_CUSTOMER_INT.LastName =
(SELECT C.LastName
FROM CUSTOMER AS C
WHERE C.CustomerID = ORDER_CUSTOMER_INT.CustomerID);
SELECT * FROM ORDER_CUSTOMER_INT;

(3) Set the new columns to NOT NULL.


ALTER TABLE ORDER_CUSTOMER_INT
ALTER COLUMN FirstName Char(25) NOT NULL;

ALTER TABLE ORDER_CUSTOMER_INT


ALTER COLUMN LastName Char(25) NOT NULL;
(4) Drop the existing foreign key constraint between CUSTOMER and
ORDER_CUSTOMER_INT.
ALTER TABLE ORDER_CUSTOMER_INT
DROP CONSTRAINT COInt_Customer_FK;

(5) Drop the existing primary key constraint for CUSTOMER and set a new primary key
constraint.
ALTER TABLE CUSTOMER
DROP CONSTRAINT CustomerPK;

ALTER TABLE CUSTOMER


ADD CONSTRAINT CustomerPK_2
PRIMARY KEY(FirstName, LastName);
(6) Create a new foreign key constraint between CUSTOMER and ORDER_CUSTOMER_INT.
Note that since the primary key of CUSTOMER is no longer a surrogate key, we will now
cascade updates.
ALTER TABLE ORDER_CUSTOMER_INT
ADD CONSTRAINT COInt_Customer_FK_2 FOREIGN KEY(FirstName, LastName)
REFERENCES CUSTOMER(FirstName, LastName)
ON UPDATE CASCADE
ON DELETE NO ACTION;

(7) Drop the primary key constraint on (InvoiceNumber, CustomerID) in


ORDER_CUSTOMER_INT, and replace it with a primary key constraint on (InvoiceNumber,
FirstName, LastName).
ALTER TABLE ORDER_CUSTOMER_INT
DROP CONSTRAINT CustomerOrderIntPK;

ALTER TABLE ORDER_CUSTOMER_INT


ADD CONSTRAINT CustomerOrderIntPK_2
PRIMARY KEY (InvoiceNumber, FirstName, LastName);
(8) Drop the CustomerID column for ORDER_CUSTOMER_INT – we will keep it in
CUSTOMER (although we could drop it as well).

A look at the database diagram in the Microsoft SQL Server Management Studio shows that the
new primary key in CUSTOMER is set up correctly, and the CustomerID in CUSTOMER and
ORDER_CUSTOMER_INT is no longer a primary key or part of a composite primary key. We
can now finish the database redesign by dropping CustomerID from ORDER_CUSTOMER_INT.
We could also drop CustomerID from CUSTOMER, but in this case we'll leave it in.

ALTER TABLE ORDER_CUSTOMER_INT


DROP COLUMN CustomerID;

A look at the final database diagram in the Microsoft SQL Server Management Studio shows that
the new primary key in CUSTOMER is set up correctly, the CustomerID column has been
removed from ORDER_CUSTOMER_INT, and the database redesign is done.

You might also like