Chapter 7 SQL Figure..

advertisement
CREATE TABLE CUSTOMER(
CustomerID int
Name
char(25)
Street
char(30)
City
char(35)
State
char(2)
ZipPostalCode char(9)
Country
char(50)
AreaCode
char(3)
PhoneNumber char(8)
Email
char(100)
CONSTRAINT
CustomerPK
NOT NULL IDENTITY (1000,1),
NOT NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
Null,
PRIMARY KEY (CustomerID)
);
CREATE TABLE ARTIST(
ArtistID
int
Name
char(25)
Nationality char(30)
Birthdate
numeric (4)
DeceasedDate numeric(4)
CONSTRAINT
CONSTRAINT
CONSTRAINT
CONSTRAINT
CONSTRAINT
CONSTRAINT
NOT NULL IDENTITY (1,1),
NOT NULL,
NULL,
NULL,
NULL,
ArtistPK
PRIMARY KEY (ArtistID),
ArtistAK1
UNIQUE (Name),
NationalityValues CHECK
(Nationality IN
('Canadian', 'English', 'French', 'German',
'Mexican', 'Russian', 'Spanish', 'US')),
BirthValuesCheck CHECK (Birthdate < DeceasedDate),
ValidBirthYear CHECK (Birthdate LIKE '[1-2][0-9][0-9][0-9]'),
ValidDeathYear CHECK (DeceasedDate LIKE '[1-2][0-9][0-9][0-9]')
);
CREATE TABLE CUSTOMER_ARTIST_INT(
ArtistID
int
NOT NULL,
CustomerID int
NOT NULL,
CONSTRAINT
CONSTRAINT
CONSTRAINT
CustomerArtistPK PRIMARY KEY (ArtistID, CustomerID),
Customer_Artist_Int_ArtistFK FOREIGN KEY (ArtistID)
REFERENCES ARTIST (ArtistID)
ON UPDATE CASCADE
ON DELETE CASCADE,
Customer_Artist_Int_CustomerFK FOREIGN KEY (CustomerID)
REFERENCES CUSTOMER (CustomerID)
ON UPDATE CASCADE
ON DELETE CASCADE
);
CREATE TABLE WORK (
WorkID
int
NOT NULL IDENTITY (500,1),
Title
char(25)
NOT NULL,
Description varchar(1000) NULL,
Copy
char(8)
NOT NULL,
ArtistID
int
NOT NULL,
CONSTRAINT WorkPK
CONSTRAINT WorkAK1
PRIMARY KEY (WorkID),
UNIQUE (Title, Copy),
CONSTRAINT ArtistFK
FOREIGN KEY(ArtistID) REFERENCES ARTIST (ArtistID)
);
CREATE TABLE TRANSACTION (
TransactionID int
NOT NULL IDENTITY (100,10),
DateAcquired date
NOT NULL,
AcquisitionPrice numeric(8,2) NULL,
PurchaseDate date NULL,
SalesPrice numeric(8,2) NULL,
AskingPrice numeric(8,2) NULL,
CustomerID int
NULL,
WorkID
int
NOT NULL,
CONSTRAINT
CONSTRAINT
CONSTRAINT
CONSTRAINT
CONSTRAINT
TransactionPK PRIMARY KEY (TransactionID),
SalesPriceRange
CHECK ((SalesPrice > 1000) AND (SalesPrice <=200000)),
ValidTransDate CHECK (DateAcquired <= PurchaseDate),
TransactionWorkFK
FOREIGN KEY(WorkID) REFERENCES WORK (WorkID),
TransactionCustomerFK
FOREIGN KEY(CustomerID) REFERENCES CUSTOMER (CustomerID)
);
SQL for Creating the Database Design in Figure 7-3(b)
Figure 7-4
CREATE TRIGGER TRANSACTION_SalesPriceCheck
AFTER UPDATE ON TRANSACTION
BEGIN
IF :new.SalesPrice < .9 * :old.AskingPrice THEN
/* Sales Price is too low, reset it
*/
UPDATE TRANSACTION
SET
SalesPrice = :old.AskingPrice,
AskingPrice = :old.AskingPrice;
/* Note:
/*
the above update will cause a recursive call on this
trigger. The recursion will stop the second time
through because SalesPrice will be = AskingPrice. */
Also should send a message to the user saying what’s been
done
*/
END IF;
END;
Example AFTER UPDATE Trigger for Checking Valid
Values
Figure 7-14
CREATE TRIGGER TRANSACTION_AskingPriceInitialValue
AFTER INSERT ON TRANSACTION
DECLARE
rowcount as int;
sumNetPrice as numeric (10,2);
avgNetPrice as numeric (8,2);
BEGIN
/* First find if work has been here before */
SELECT
FROM
WHERE
Count(*) INTO rowcount
TRANSACTION T
:new.WorkID = T.WorkID;
IF rowcount = 1 Then
/* This is first time work has been in gallery */
:new.AskingPrice = 2 * :new.AcquisitionPrice;
ELSE
IF rowcount > 1 Then
/* Work has been here before */
SELECT
FROM
WHERE
GROUP BY
Sum(NetPrice) into sumNetPrice
ArtistWorkNet AW
AW.WorkID = :new.WorkID
AW.WorkID;
avgNetPrice = sumNetPrice / (rowcount – 1);
/* Now choose larger
*/
IF avgNetPrice > 2 * :new.AcquisitionPrice Then
:new.AskingPrice = avgNetPrice;
ELSE
:new.AskingPrice = 2 * :new.AcquisitionPrice;
END IF;
ELSE
/* Error, rowcount cannot be less than 1 –
Do something */
END IF;
END IF;
END;
Example AFTER INSERT Trigger for Computing a Default
Value
Figure 7-15
CREATE TRIGGER CustomerInterest_CustomerName Update
INSTEAD OF UPDATE ON CustomerInterests
DECLARE
rowcount
int;
SELECT
FROM
WHERE
Count(*) INTO rowcount
CUSTOMER C
C.Name = :old.Customer;
BEGIN
IF rowcount > 1 THEN
/* Non-unique name, cannot update */
/* Send message to user that there are duplicates
and cannot update because do not know which
to change. */
ELSE
/* If get here, then only one customer with this name.
Make the name change. */
UPDATE
SET
WHERE
CUSTOMER
CUSTOMER.Name = :new.Customer
CUSTOMER.Name = :old.Customer;
END;
Example INSTEAD OF Trigger for Updating a View
Figure 7-16
CREATE TRIGGER WORK_TRANSACTION_Check
AFTER INSERT ON WORK
DECLARE
rowcount as int;
BEGIN
/* First look for a related TRANSACTION row */
SELECT
FROM
WHERE
Count(*) INTO rowcount
TRANSACTION T
:new.WorkID = T.WorkID;
IF rowcount = 0 Then
/* remove just added WORK */
DELETE
FROM WORK
WHERE
WORK.WorkID = :new.WorkID
/* need some way to notify what has occurred here */
END IF;
END;
Example AFTER INSERT Trigger for Enforcing a
Required Child Constraint
Figure 7-17
CREATE TRIGGER WORK_Deletion
INSTEAD OF DELETE ON WORK
DECLARE
rowcount as int;
nullCount as int;
BEGIN
/* First check related TRANSACTION row counts*/
SELECT
FROM
WHERE
Count(*) INTO rowcount
TRANSACTION T
:old.WorkID = T.WorkID;
IF rowcount = 0 Then
/* this should never occur -- error */
/* write to error log and do nothing */
ELSE
IF rowcount = 1 THEN
/* Check for null CustomerID */
SELECT Count(*) into nullCount
FROM TRANSACTION T
WHERE :old.WorkID = T.WorkID
AND
T.CustomerID IS NULL;
IF nullCount = 1 THEN
/* Deletions must go in this order */
DELETE
FROM TRANSACTION T
WHERE :old.WorkID = T.WorkID;
DELETE
FROM WORK W
WHERE :old.WorkID = W.WorkID;
END IF;
END IF;
END IF;
END;
Example INSTEAD OF DELETE Trigger for Enforcing a
Deletion Rule
Figure 7-18
Download