If I am reading your question properly, 1 contract has 12 child records in the appointment table, if that is correct then I would have 2 processes,
P1 -> FIND Appointments where Appointment.ob_Contract = Contract
then call P2 with the Appointment BO as input
P2 -> Find the contacts and do whatever with them. (if necessary, have a P3 called for each Appointment
This way, you are not re-reading anything
Of course, would be easy - peasy to do in a SP.
Bruce