= Stored Functions and Procedures = == Description == This section contains reusable SQL functions and procedures used for calculations, validation, and reporting. == 1. calculate_wedding_total_cost() == === Description === Calculates the total cost of a wedding using venue, photographer, and band bookings. === SQL Code ===
CREATE OR REPLACE FUNCTION calculate_wedding_total_cost(p_wedding_id INTEGER)
RETURNS NUMERIC AS $$
DECLARE
total_cost NUMERIC;
BEGIN
SELECT
COALESCE(SUM(vb.price), 0)
INTO total_cost
FROM wedding w
LEFT JOIN venue_booking vb ON w.wedding_id = vb.wedding_id
WHERE w.wedding_id = p_wedding_id;
RETURN total_cost;
END;
$$ LANGUAGE plpgsql;
== 2. is_venue_available() ==
=== Description ===
Checks whether a venue is available for a selected date and time interval.
=== SQL Code ===
CREATE OR REPLACE FUNCTION is_venue_available(
p_venue_id INTEGER,
p_date DATE,
p_start TIME,
p_end TIME
)
RETURNS BOOLEAN AS $$
BEGIN
RETURN NOT EXISTS (
SELECT 1
FROM venue_booking
WHERE venue_id = p_venue_id
AND "date" = p_date
AND (
p_start < end_time
AND p_end > start_time
)
);
END;
$$ LANGUAGE plpgsql;
This function does not only compare equal dates. It compares complete timestamp intervals using:
{{{
#!sql
(new_start < existing_end) AND (new_end > existing_start)
}}}
This condition detects all possible overlap cases:
* the new interval starts inside an existing interval
* the new interval ends inside an existing interval
* the new interval completely contains an existing interval
* the existing interval completely contains the new interval
* both intervals are exactly the same
* intervals that only touch at the boundary are not treated as overlapping
== 3. is_photographer_available() ==
=== Description ===
Checks whether a photographer is available for a selected date and time interval.
=== SQL Code ===
CREATE OR REPLACE FUNCTION is_photographer_available(
p_photographer_id INTEGER,
p_date DATE,
p_start TIME,
p_end TIME
)
RETURNS BOOLEAN AS $$
BEGIN
RETURN NOT EXISTS (
SELECT 1
FROM photographer_booking
WHERE photographer_id = p_photographer_id
AND "date" = p_date
AND (
p_start < end_time
AND p_end > start_time
)
);
END;
$$ LANGUAGE plpgsql;
== 4. is_band_available() ==
=== Description ===
Checks whether a band is available for a selected date and time interval.
This function uses full timestamp interval comparison by combining the booking date with start and end time. This avoids incorrect availability results when intervals overlap in different ways.
=== SQL Code ===
{{{
#!sql
CREATE OR REPLACE FUNCTION is_band_available(
p_band_id INTEGER,
p_date DATE,
p_start TIME,
p_end TIME
)
RETURNS BOOLEAN AS $$
BEGIN
IF p_end <= p_start THEN
RAISE EXCEPTION 'Invalid interval: end time must be after start time.';
END IF;
RETURN NOT EXISTS (
SELECT 1
FROM band_booking bb
WHERE bb.band_id = p_band_id
AND bb.status <> 'cancelled'
AND (
(p_date + p_start) < (bb."date" + bb.end_time)
AND (p_date + p_end) > (bb."date" + bb.start_time)
)
);
END;
$$ LANGUAGE plpgsql;
}}}
== 5. generate_rsvp_summary() ==
=== Description ===
Returns RSVP statistics for a selected event.
=== SQL Code ===
CREATE OR REPLACE PROCEDURE generate_rsvp_summary(p_event_id INTEGER)
LANGUAGE plpgsql
AS $$
BEGIN
RAISE NOTICE 'Accepted: %',
(
SELECT COUNT(*)
FROM event_rsvp
WHERE event_id = p_event_id
AND status = 'accepted'
);
END;
$$;