Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Exercises
01 - Authorship
Consider the following relational schema:
The operation that most typically will violate the rule is the first one.
P6 P7 P8 P9
1
Define a trigger for the following task:
When a product is deleted, all the sub-products
(at any level) must be deleted as well.
create trigger DeleteProduct
after delete on Product
for each row
delete from Product
where SuperProduct = old.Code
Deleting a product activates the trigger that deletes all the
directly connected subproducts (that is, the direct children
of the product). In turn, each of these activates again the
trigger for deleting the sub-subproduct (grandchildren) of
the originally deleted product. At the end, all the descendant
are deleted.
2
Write a trigger that calculates the value of the
attribute Level when a new Product is created. Note
that the new product may be child of an existing
one.
create trigger ProductLevel
after insert on Product
for each row
begin
update Product
set Level = 1 + ( select Level
from Product
where Code = new.SuperProduct )
where Code = new.Code and new.SuperProduct is not null;
update Product
set Level = 0
where Code = new.Code and new.SuperProduct is null;
end;
Some comments:
The calculation for a root product (level 0) must be
managed separately from a product positioned within
higher levels
The condition Code=new.Code is used for identifying
the tuple that has been inserted and needs to be modified.
WARNING!! Writing set new.Level = is a terribly
wrong solution! new is not a pointer to the newly
created element.
This rule calculates automatically the level of a new
product. If a product is inserted with a value for the
attribute Level, this is overwritten.
If we allow updates of the suprProduct attribute (changing the
hierarchy over time) then we should also maintain the Level
A, B
33
A side thought
non overlapping intervals... How to?
A, B
This is the simplest option: the field is updated at each insertion, possibly with a zero-
increment when users are on time.
Capturing zero-increments may be done in the when clause (but is as heavy as the update)
Play with me
create trigger UpdateWastedHours
after insert into Usage
for each row
declare X integer;
when 0 < ( select EndTime StartTime ( new.EndTime new.StartTime ) into X
from Reservation
where RoomCode=new.RoomCode and Date = new.Date
and StartTime>= new.StartTime and EndTime <= new.EndTime )
update User
set WastedHours = WastedHours + X
where SSN = new.UserSSN
ATTENTION:
were not considering the case in which bands do not show up at all !
Play with me
How to deal with users who dont show up at all?
- We may not accept new any new reservation for users who didnt
show up in the past (but this would be a new business rule we
should simply try to count the hours as wasted hours... What we
miss, in this case, is the triggering event)
- We may consider a new reservation a triggering event and, before
reserving, check for previous dangling reservations
- And delete them, once dealt with (in order not to count them again in
the future)
- Or, more likely, in order not to delete potentially useful data, mark
them with a flag that needs to be added to the schema
- Most likely (and simply), periodically check for these situations
we need a triggering event that is not a data modification, but rather
a system event (example: check all reservations daily, after the
change of date), as in the following trigger
Play with me
create trigger InelegantNonPortable_GhostMusicians
after change-date() // each vendor has its own extended event language
do
select * into PENDING
from Reservation R
where R.date = today()1 and not exists( select * from Usage U
where U.Date = R.Date
and R.StartTime <= U.StartTime
and U.EndTime >= R.EndTime )
for-each X in PENDING
do
update User
set WastedHours = WastedHours + X.EndTime X.StartTime
end;
Please note that the bindings on P and U take the place of the iteration, and each
user has its counter updated by the quantity depending on their specific faults.
Also note that this solution, by means of aggregation, also accounts for the case in
which the same user has left more than one pending reservation in the same day.
06 - The social concert hall
A concert hall manages information about the shows using a set of row-level triggers.
Visitors to the Web site can create an account and register a set of keywords matching
their interests. When (a) a new show is inserted into the Website, with a set of
keywords, registers users with a match with their set of keywords will receive an
email. Some of them will buy a ticket for the event. In case of (b) show cancellation or
(c) change of starting time, a notification is sent to users who bought a ticket for the
affected show. Write only the triggers for the management of events (a,b,c). Assume
that a function send-mail(ReceiverEmail, Subject, ... OtherAttributes ...) is available,
which is invoked with all the parameters required for email creation. The database
schema is:
sqliteonline: https://goo.gl/Mw4rYB
ProdProc Obtained Starting
Qty
Id ProdId ProdId
1000 1 2 4
1001 1 3 1
1002 2 4 2
1003 2 5 1
sqliteonline: https://goo.gl/QiOS01
We have to define at least the following triggers:
ELSE
INSERT INTO PurchaseOrder VALUES
(GenerateId(), new.ProductId, new.Qty, new.OrderId);
END;
END;
sqliteonline: https://goo.gl/9QGmtp
T1 considerations:
UPDATE ClientOrder
SET TotalSubItems = TotalSubItems + new.Qty
WHERE OrderId = new.OrderId;
END;
sqliteonline: https://goo.gl/JXiSXC
T3 (UpdateSubItemsAfterProduction) reacts to insertion on ProductionPlan
UPDATE ClientOrder
SET TotalSubItems = TotalSubItems + new.Qty
WHERE OrderId = new.OrderId;
END;
sqliteonline: https://goo.gl/PKyDlJ
T4 (InsertSubProducts) reacts to insertion on ProductionPlan
T5 (Validate Order)
Validates TotalSubItems = 0
Validates Qty > 0
T6 (Delete Order)
Delete all associated PurchaseOrders
Delete all associated ProductionPlans
sqliteonline: https://goo.gl/JwhKT2
T5 (Validate Order)
END
T6 (Delete Order)
END;
T7 (Disable Order Updates)
END;