223 Final Lecture - 2024
223 Final Lecture - 2024
Prac Test 2
More Case Statements
Project Deliverable 2
• Part 1 (3%) due 31 May
• Part 2 (12%) due 7th June
• Demonstration of D2 part 2 in labs
Prac Test 2
• Mock test is on Moodle
• 5th June
• 20% of final mark
• 105 min test
• Open book test
• SQL tables and test data provided
Test Topics
• Views
• Stored Procedures
• Triggers
• Case Statements
• More on these today
Views
• Creating View by joining multiple tables
Views
• Creating View by joining multiple tables
Begin transaction
test statements {INSERT | UPDATE | DELETE }
Rollback transaction
CREATE TRIGGER general ON table FOR|AFTER Operation
AS
DECLARE @RC int = @@ROWCOUNT
IF @RC = 0
RETURN -- nothing happened (efficient)
IF @RC = 1
BEGIN
-- Single row operation
END
ELSE
BEGIN
-- Multi-row operation
END
CREATE TRIGGER general ON table FOR|AFTER Operation
AS
DECLARE @RC int = @@ROWCOUNT
IF @RC = 0
RETURN -- nothing happened (efficient)
IF EXISTS|NOT EXISTS (SELECT * FROM tablename WHERE … ) BEGIN
RAISERROR('You cannot do this ….',16,1)
ROLLBACK TRAN
END
IF EXISTS|NOT EXISTS (SELECT * FROM tablename WHERE … ) BEGIN
RAISERROR('You cannot do this too ….',16,1)
ROLLBACK TRAN
END
….
RETURN
19
CREATE TRIGGER ThirtyMin ON scheduleSlot After update, insert
AS
DECLARE @RC int = @@ROWCOUNT
IF @RC = 0
RETURN -- nothing happened (efficient)
IF EXISTS|NOT EXISTS (SELECT * FROM tablename WHERE … ) BEGIN
RAISERROR('You cannot do this ….',16,1)
ROLLBACK TRAN
END
IF EXISTS|NOT EXISTS (SELECT * FROM tablename WHERE … ) BEGIN
RAISERROR('You cannot do this too ….',16,1)
ROLLBACK TRAN
END
….
RETURN
20
two conditions
(1) must be half an hour long
CREATE TRIGGER ThirtyMin ON scheduleSlot After update, insert (2) start on hour or at half past
AS
DECLARE @RC int = @@ROWCOUNT
IF @RC = 0
RETURN -- nothing happened (efficient)
IF EXISTS|NOT EXISTS (SELECT * FROM tablename WHERE … ) BEGIN
RAISERROR('You cannot do this ….',16,1)
ROLLBACK TRAN
END
IF EXISTS|NOT EXISTS (SELECT * FROM tablename WHERE … ) BEGIN
RAISERROR('You cannot do this too ….',16,1)
ROLLBACK TRAN
END
….
RETURN
21
CREATE TRIGGER ThirtyMin ON scheduleSlot After update, insert
AS
DECLARE @RC int = @@ROWCOUNT
IF @RC = 0
RETURN -- nothing happened (efficient)
IF EXISTS (SELECT appointment_id FROM INSERTED
WHERE DATEDIFF(MINUTE, startTime, endTime) != 30 ) BEGIN
RAISERROR('This time slot is not thirty minutes long',16,1)
ROLLBACK TRAN
END
Test 1
Begin Transaction
INSERT INTO scheduleSlot(room, dayDate, startTime, endTime) VALUES (1, ‘2024-5-27', '8:00', '8:30');
Rollback Transaction
24
CREATE TRIGGER ThirtyMin ON scheduleSlot After update, insert
Write 3 safe tests for question 6. AS
DECLARE @RC int = @@ROWCOUNT
1. One safe test must insert a schedule slot at a correct IF @RC = 0
start time and length RETURN -- nothing happened (efficient)
IF EXISTS (SELECT appointment_id FROM INSERTED
2. Test 2 must not fire. The second safe test must attempt WHERE DATEDIFF(MINUTE, startTime, endTime) != 30 ) BEGIN
to update a timeSlot to an incorrect start time so the RAISERROR('This time slot is not thirty minutes long',16,1)
ROLLBACK TRAN
trigger must fire. END
3. The third safe test must attempt to insert a timeSlot IF EXISTS (SELECT appointment_id FROM INSERTED
WHERE NOT (startTime LIKE ’%:00:00’ OR startTime LIKE ’%:30:00’ )) BEGIN
with an incorrect length so the trigger must fire. RAISERROR(‘This time slot does not start at a valid time’, 16,1)
ROLLBACK TRAN
END
….
RETURN
Test 3
Begin Transaction
INSERT INTO scheduleSlot(room, dayDate, startTime, endTime) VALUES (2, ‘2024-5-28', '8:00', ‘8:40');
Rollback Transaction
26
CREATE TRIGGER SnakeVet ON scheduleSlot After update
AS
DECLARE @RC int = @@ROWCOUNT
IF @RC = 0
RETURN -- nothing happened (efficient)
IF EXISTS|NOT EXISTS (SELECT * FROM tablename WHERE … ) BEGIN
RAISERROR('You cannot do this ….',16,1)
ROLLBACK TRAN
END
IF EXISTS|NOT EXISTS (SELECT * FROM tablename WHERE … ) BEGIN
RAISERROR('You cannot do this too ….',16,1)
ROLLBACK TRAN
END
….
RETURN 27
CREATE TRIGGER SnakeVet ON scheduleSlot After update
AS
DECLARE @RC int = @@ROWCOUNT
IF @RC = 0
RETURN -- nothing happened (efficient)
IF NOT EXISTS (SELECT appointment_id FROM
FROM inserted, appointment, animal
WHERE inserted.appointment_id = appointment. appointment_id
and appointment.animal_id = animal.animal_id
and category = 'snake’)
RETURN -- do nothing for non snake (efficient)
…
RETURN
28
CREATE TRIGGER SnakeVet ON scheduleSlot After update
AS
DECLARE @RC int = @@ROWCOUNT
IF @RC = 0
RETURN -- nothing happened (efficient)
IF (SELECT appointment_id FROM INSERTED) NOT IN (
select appointment_id FROM appointment, animal
WHERE appointment.animal_id = animal.animal_id
and category = 'snake’)
RETURN -- do nothing for non snake (efficient)
…
RETURN
29
CREATE TRIGGER SnakeVet ON scheduleSlot After update
AS
DECLARE @RC int = @@ROWCOUNT
IF @RC = 0
RETURN -- nothing happened (efficient)
IF NOT EXISTS (SELECT appointment_id FROM …)
RETURN -- do nothing for non snake (efficient)
Test 1
Begin Transaction
Update scheduleSlot
Set appointment_id = 10 where slot_id = 3
Rollback Transaction 31
select appointment_id
from appointment
where animal_id IN (select animal_id
from animal where category = 'snake')
select slot_id
from scheduleSlot
Test 2 where staff_id IN (select staff_id
Begin Transaction from staff where role like ‘%serpentine%')
Update scheduleSlot
Set appointment_id = 19 where slot_id = 41
Rollback Transaction 32
select appointment_id
from appointment
where animal_id IN (select animal_id
from animal where category = 'snake')
select slot_id
from scheduleSlot
Test 3 where staff_id IN (select staff_id
Begin Transaction from staff where role like ‘%serpentine%')
Update scheduleSlot
Set appointment_id = 19 where slot_id = 3
Rollback Transaction 33
Case Statements
CASE
WHEN Boolean_expression THEN result_expression
WHEN Boolean_expression THEN result_expression
ELSE result_expression
END
34
Case Statement Example
CASE
WHEN price = 0 THEN ‘Free’
WHEN price < 10 THEN ‘Cheap’
ELSE ‘Expensive’
END
35
Case Statement Select Example
SELECT productName, “Cost” =
CASE
WHEN price = 0 THEN ‘Free’
WHEN price < 10 THEN ‘Cheap’
ELSE ‘Expensive’
END
FROM products
36
Making choices using CASE
GO
SELECT Title, borrowed =
CASE
WHEN count(MoveID) = 0 THEN 'has never been borrowed'
WHEN count(MoveID) = 1 THEN 'has been borrowed once'
ELSE 'has been borrowed lots of times'
END
FROM Book left outer join Movement on Book.BookID = Movement.BookID
group by Book.BookID, Title
GO
37
38
SELECT st.fName, st.lName, an.category
FROM staff st join schedulSlot ss on st.staff_id = ss.staff_id
join appointment app on ss.appointment_id = app.appointment_id
join animal an on app.animal_id = an.animal_id
WHERE st.fName = 'Phil' and st.lName = 'Treweek'
39
SELECT st.fName, st.lName,
Cow = (case when an.category = 'cow' then 1 ELSE 0 END),
Sheep = (case when an.category = 'sheep' then 1 ELSE 0 END),
Pig = (case when an.category = 'Pig' then 1 ELSE 0 END),
Fish = (case when an.category = 'Fish' then 1 ELSE 0 END)
FROM staff st join scheduleSlot ss on st.staff_id = ss.staff_id
join appointment app on ss.appointment_id = app.appointment_id
join animal an on app.animal_id = an.animal_id
where st.fName = 'Phil' and st.lName = 'Treweek'
40
SELECT st.fName, st.lName,
Cow = sum(case when an.category = 'cow' then 1 ELSE 0 END),
Sheep = sum(case when an.category = 'sheep' then 1 ELSE 0 END),
Pig = sum(case when an.category = 'Pig' then 1 ELSE 0 END),
Fish = sum(case when an.category = 'Fish' then 1 ELSE 0 END)
FROM staff st join scheduleSlot ss on st.staff_id = ss.staff_id
join appointment app on ss.appointment_id = app.appointment_id
join animal an on app.animal_id = an.animal_id
where st.fName = 'Phil' and st.lName = 'Treweek'
group by st.staff_id, st.fName, st.lName 41
Any Questions?
42