The University of Texas
CS 327e Fall 2002 Test
2
NAME:
__________________________________ LAST 4 DIGITS of SSN: __________________
Date: 2002-10-28 Duration:
60 mins Total: 12 Qs (100 pts), 1
bonus Q (4 pts)
For
the multiple-choice questions 1 through 10, Use a pencil to circle the correct
answer. Each multiple-choice question carries 5 points.
1) The American
National Standards Institute prescribes a standard SQL - the most recent
version is known as SQL-99.
|
a. |
True. |
|
b. |
False. |
2) The difference between a data mart and a data warehouse is only
the size and scope of the problem being solved. The data definitions and data requirements are essentially the
same for both.
|
a. |
True. |
|
b. |
False. |
3) The basic SQL aggregate function that gives the number or rows
containing non-null values for the given column is
|
a. |
COUNT |
|
b. |
MIN |
|
c. |
MAX |
|
d. |
SUM |
|
e. |
AVG |
4) A trigger is
procedural SQL code that is automatically invoked by the RDBMS upon the
occurrence of a data manipulation event
|
a. |
A trigger is always associated with a
database table. |
|
b. |
Each database table may have zero or more
triggers. |
|
c. |
all of the above |
|
d. |
None of the above |
5) Operational data storage differs from decision support in main
areas which are:
|
a. |
timespan |
|
b. |
granularity |
|
c. |
dimensionality |
|
d. |
all of the above |
|
e. |
none of the above |
6) Data warehouse's components are
|
a. |
integrated, and subject-oriented. |
|
b. |
time-variant and nonvolatile. |
|
c. |
a and b |
7) A rule that defines the data warehouse is
|
a. |
data warehouse and operational
environments are separated and data are integrated. |
|
b. |
data warehouse contains historical data
over a time horizon. |
|
c. |
a and b |
8) ROLAP adds the following extensions to traditional RDMBS
technology:
|
a. |
multidimensional data schema support
within the RDMBS. |
|
b. |
data access language and query performance
are optimized for multidimensional data. |
|
c. |
support for small databases. |
|
d. |
a and c |
|
e. |
a and b |
9) GRANT statements are used
to give privileges on objects to users, whereas WITHDRAW statements are used to
take away the privileges.
|
a. |
True. |
|
b. |
False. |
10) All VIEWS are not
updateable.
|
a. |
True. |
|
b. |
False. |
For questions 11 and 12,
Consider the
suppliers-parts-projects database, sample data (same as lab1) for which is
shown in the last page. There are 4 tables containing relevant data:
1) SUPPLIER (SID, Name,
Status, City)
2) PART (PID, Name,
Color, Weight, City)
3) PROJECT (JID, Name,
City)
4) SHIPMENT (SID, PID, JID,
Qty)
Suppliers (S), parts (P), and
projects (J) are uniquely identified (PK) by supplier id (SID), part id (PID),
and project id (JID), respectively. The significance of an SPJ (shipment) row
is that the specified supplier supplies the specified part to the specified
project in the specified quantity (and the combination SID-PID-JID uniquely
identifies (PK) such a row). Assume none of the columns in all of the tables
allow NULLs.
Use the following SQL
Server CREATE PROCEDURE syntax:
CREATE PROC [ EDURE ] procedure_name
[ ; number ]
[ { @parameter data_type }
[ VARYING ] [ = default ]
[ OUTPUT ]
] [ ,...n ]
[ WITH
{ RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTION } ]
[ FOR REPLICATION ]
AS sql_statement [ ...n ]
Use the following SQL
Server CREATE TRIGGER syntax:
CREATE TRIGGER trigger_name
ON { table | view }
[ WITH ENCRYPTION ]
{
{ { FOR | AFTER | INSTEAD OF } { [ INSERT ] [ , ] [
UPDATE ] [ , ] [ DELETE ] }
[ WITH APPEND ]
[ NOT FOR REPLICATION ]
AS
[ { IF UPDATE ( column )
[ { AND
| OR } UPDATE ( column ) ]
[
...n ]
| IF ( COLUMNS_UPDATED ( ) { bitwise_operator
} updated_bitmask )
{
comparison_operator } column_bitmask [ ...n ]
} ]
sql_statement [ ...n ]
}
}
Use the following SQL
Server IF…ELSE syntax:
IF
Boolean_expression
{ sql_statement | statement_block }
[ ELSE
{ sql_statement | statement_block } ]
e.g.
IF (SELECT
AVG(price) FROM titles WHERE type = 'mod_cook') < $15
BEGIN
PRINT 'The following titles are excellent
mod_cook books:'
SELECT SUBSTRING(title, 1, 35) AS Title
FROM titles
WHERE type = 'mod_cook'
END
ELSE
IF
(SELECT AVG(price) FROM titles WHERE type = 'mod_cook') > $15
BEGIN
PRINT 'The following titles are expensive
mod_cook books:'
SELECT UPPER(RTRIM (title)) AS Title
FROM titles
WHERE type = 'mod_cook'
END
11) (30 points) Write a
procedure that inserts a new supplier in the SUPPLIER table. The procedure
will check for non-null input, and then return a new supplier id, along with a
count of suppliers that already existed in the same (case-insensitive) city.
Return a status of 0 for successful insert, and –1 for all other situations.
When the status is –1, the supplier ID should be set to ‘Unknown’, the returned
count of local suppliers to 0, and no INSERT statement should be executed.
Assume SUPPLIER table always
exist, SID is the PK, and there are all privileges on this table for the user
creating/executing this procedure. Assume all supplierIDs are of the form S1,
S2, S3,…..etc. Assume no supplierIDs can be deleted or updated from the table.
Assume all supplierIDs are in sequence as shown above. So, for example, if
there are 4 supplierIDs already in the SUPPLIER table, you can assume that they
will always be S1, S2, S3, S4; and hence the new supplierID should be S5. If
there are no suppliers to begin with, the new supplierID should be S1. Hence,
if there are “n” (where n is >= 1)
suppliers already in the table, you can assume that the corresponding
supplierIDs are S1, S2, S3, …. Sn.
Hence, for the data shown in
the last page, if we execute the following statements on Query Analyzer in SQLServer:
DECLARE @mySupplierID nvarchar(10)
DECLARE @cntLocalSups int
DECLARE @myStatus int
EXEC INS_SUPPLIER 'Jane', 20, 'PaRIs', @mySupplierID OUTPUT,
@cntLocalSups OUTPUT, @myStatus OUTPUT
IF @myStatus = 0
BEGIN
PRINT 'Your Supplier ID is : ' + @mySupplierID
PRINT 'There are ' + CAST(@cntLocalSups AS
nvarchar(20)) + ' other suppliers in your city.'
PRINT 'Your INSERT statement was successful !'
END
ELSE
BEGIN
PRINT 'Your INSERT statement was not successful. Please
check your input for non NULL values. '
END
GO
Should result in:
Your Supplier ID is : S6
There are 2 other suppliers in
your city.
Your INSERT statement was
successful !
And if you then executed
SELECT * FROM SUPPLIER ORDER BY SID, the result would look like
SID Name Status City
S1 Smith 20.0 London
S2 Jones 10.0 Paris
S3 Blake 30.0 Paris
S4 Clark 20.0 London
S5 Adams 30.0 Athens
S6 Jane 20.0 PaRIs
Clearly state any assumptions.
HINT: You may need to use the CAST, RTRIM, and UPPER built-in
functions, usage of which is shown above, syntax is shown below.
1)
CAST
CAST ( expression
AS data_type )
Returns the
“expression” converted as “data_type”
2) RTRIM
RTRIM ( character_expression
)
Returns a character string
after truncating all trailing blanks.
3) UPPER
UPPER ( character_expression
)
Returns
a character expression with any (lower, upper, or mixed) case character data
converted to uppercase.
Write the solution to this
problem on next page.
CREATE PROCEDURE
INS_SUPPLIER
@Name nvarchar (255),
@Status int,
@City nvarchar (255),
@SupplierID nvarchar(10) OUTPUT,
@cntLocalSuppliers int
OUTPUT,
@myStatus int OUTPUT
AS
BEGIN
--
Initialize my output variables
SELECT
@SupplierID = 'Unknown'
SELECT
@cntLocalSuppliers = 0
SELECT
@myStatus = -1
--
Validate non-null input
IF
@Name IS NOT NULL
BEGIN
IF @Status IS NOT NULL
BEGIN
IF @City IS NOT NULL
BEGIN
-- Get the count of existing suppliers
DECLARE @cntExistingSuppliers int
SELECT @cntExistingSuppliers = COUNT(*) FROM SUPPLIER
-- Manufacture the new SupplierID
SELECT @SupplierID = 'S' + CAST ((@cntExistingSuppliers
+ 1) AS nvarchar (9))
SELECT @SupplierID = RTRIM (@SupplierID)
-- Get the count of local suppliers, before INSERTing
the new one
SELECT @cntLocalSuppliers = COUNT(*) FROM SUPPLIER
WHERE UPPER(RTRIM(CITY)) = UPPER(RTRIM(@City))
-- Everything is all set to do an INSERT
INSERT INTO SUPPLIER (SID, Name, Status, City) VALUES
(@SupplierID, @Name, @Status, @City)
-- Finally set the successful status
SELECT @myStatus = 0
END -- City is
not null
END -- Status is not null
END
-- Name is not null
END
12) (20 points) Assume PKs and FKs are defined in
the schema shown on last page (same schema in lab1).
Also, assume the following
table exists:
SPJ_CHANGES (TableName
nvarchar (20), Cnt_UPD int, Cnt_DEL int, Cnt_INS int)
Initially, the table contains
following data:
TableName Cnt_UPD Cnt_DEL CntINS
PART 0 0 0
SUPPLIER 0 0 0
PROJECT 0 0 0
Write a trigger UPD_PID that updates the SPJ_CHANGES.Cnt_UPD, after a
successful UPDATE to the PART.PID takes place. Assume all 5 tables always exist, and there are all privileges on all
tables for the user creating this trigger.
Clearly state any
assumptions.
SOLUTION:
CREATE TRIGGER UPD_PID
ON PART
AFTER UPDATE
AS
IF UPDATE (PID)
BEGIN
UPDATE
SPJ_CHANGES
SET Cnt_UPD =
Cnt_UPD + 1
WHERE UPPER(RTRIM(TableName)) = 'PART'
END
13) BONUS QUESTION (4
points):
Consider the data shown on the
last page.
a) SELECT COUNT ('Paris')
FROM Supplier;
What would be the resultant
count returned from executing this query?
SOLUTION: 5
b) SELECT COUNT (DISTINCT
'Austin') FROM Supplier;
What would be the resultant
count returned from executing this query?
SOLUTION:
1
SUPPLIER
|
SID |
Name |
Status |
City |
|
S1 |
Smith |
20 |
London |
|
S2 |
Jones |
10 |
Paris |
|
S3 |
Blake |
30 |
Paris |
|
S4 |
Clark |
20 |
London |
|
S5 |
Adams |
30 |
Athens |
PART
|
PID |
Name |
Color |
Weight |
City |
|
P1 |
Nut |
Red |
12.2 |
London |
|
P2 |
Bolt |
Green |
17.0 |
Paris |
|
P3 |
Screw |
Blue |
17.0 |
Rome |
|
P4 |
Screw |
Red |
14.0 |
London |
|
P5 |
Cam |
Blue |
12.0 |
Paris |
|
P6 |
Cog |
Red |
19.0 |
London |
PROJECT
|
JID |
Name |
City |
|
J1 |
Sorter |
Paris |
|
J2 |
Display |
Rome |
|
J3 |
OCR |
Athens |
|
J4 |
Console |
Athens |
|
J5 |
RAID |
London |
|
J6 |
EDS |
Oslo |
|
J7 |
Tape |
London |
SHIPMENT
|
SID |
PID |
JID |
Qty |
|
S1 |
P1 |
J1 |
200 |
|
S1 |
P1 |
J4 |
700 |
|
S2 |
P3 |
J1 |
400 |
|
S2 |
P3 |
J2 |
200 |
|
S2 |
P3 |
J3 |
200 |
|
S2 |
P3 |
J4 |
500 |
|
S2 |
P3 |
J5 |
600 |
|
S2 |
P3 |
J6 |
400 |
|
S2 |
P3 |
J7 |
800 |
|
S2 |
P5 |
J2 |
100 |
|
S3 |
P3 |
J1 |
200 |
|
S3 |
P4 |
J2 |
500 |
|
S4 |
P6 |
J3 |
300 |
|
S4 |
P6 |
J7 |
300 |
|
S5 |
P2 |
J2 |
200 |
|
S5 |
P2 |
J4 |
100 |
|
S5 |
P5 |
J5 |
500 |
|
S5 |
P5 |
J7 |
100 |
|
S5 |
P6 |
J2 |
200 |
|
S5 |
P1 |
J4 |
100 |
|
S5 |
P3 |
J4 |
200 |
|
S5 |
P4 |
J4 |
800 |
|
S5 |
P5 |
J4 |
400 |
|
S5 |
P6 |
J4 |
500 |