You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

酒店单房预订函数开发:如何校验预订日期无冲突

酒店单房预订日期冲突校验函数实现

我来帮你搞定这个单房预订的日期冲突校验问题,核心就是准确判断新预订的时间段和已有记录是否重叠,同时保证函数的健壮性和性能。

核心思路:区间重叠判断

酒店预订的日期区间通常是左闭右开(比如住1号到3号,实际占用1、2号,3号退房后不影响当天的新预订),所以判断两个区间[A_start, A_end)和[B_start, B_end)是否重叠的通用规则是:

A_start < B_end 并且 A_end > B_start

这个条件能覆盖所有重叠场景:完全包含、部分重叠、首尾衔接之外的所有情况(首尾衔接比如A_end=B_start,这种不算冲突)。

完整函数实现(PostgreSQL)

以下是基于你的需求写的完整函数,包含基础校验、冲突检查和预订插入:

CREATE OR REPLACE FUNCTION book_single_room(
    p_starting_date DATE,
    p_ending_date DATE
) RETURNS BOOLEAN AS $$
BEGIN
    -- 第一步:基础校验,确保日期区间合法
    IF p_starting_date >= p_ending_date THEN
        RAISE EXCEPTION 'Invalid date range: starting date must be earlier than ending date';
        RETURN FALSE;
    END IF;

    -- 第二步:检查是否存在冲突的已有预订
    IF EXISTS (
        SELECT 1
        FROM reservations
        -- 核心冲突判断逻辑
        WHERE starting_date < p_ending_date
          AND ending_date > p_starting_date
    ) THEN
        RAISE EXCEPTION 'Booking conflict: the requested dates overlap with an existing reservation';
        RETURN FALSE;
    END IF;

    -- 第三步:无冲突则插入新预订(根据实际表结构调整字段)
    INSERT INTO reservations (starting_date, ending_date)
    VALUES (p_starting_date, p_ending_date);

    RETURN TRUE;
END;
$$ LANGUAGE plpgsql;

关键细节解释

  1. 基础校验:先过滤掉起始日期晚于/等于结束日期的无效请求,避免后续无效查询。
  2. 高效冲突检查:用EXISTS子查询代替COUNT(*),因为只要找到一条冲突记录就会停止查询,性能更优。
  3. 原子性保障:PostgreSQL函数默认运行在单个事务中,所以“检查冲突→插入预订”是原子操作,不会出现并发请求同时通过检查、重复插入的问题。
  4. 异常处理:通过RAISE EXCEPTION抛出明确的错误信息,方便调用方捕获和处理;也可以改成返回错误码或字符串,根据你的业务需求调整。

扩展说明(如果是多房间场景)

如果你的reservations表是多房间共用的(表中有room_id字段),只需修改函数添加房间ID参数,并在查询和插入时加上过滤:

CREATE OR REPLACE FUNCTION book_room(
    p_room_id INT,
    p_starting_date DATE,
    p_ending_date DATE
) RETURNS BOOLEAN AS $$
BEGIN
    IF p_starting_date >= p_ending_date THEN
        RAISE EXCEPTION 'Invalid date range: starting date must be earlier than ending date';
        RETURN FALSE;
    END IF;

    IF EXISTS (
        SELECT 1
        FROM reservations
        WHERE room_id = p_room_id
          AND starting_date < p_ending_date
          AND ending_date > p_starting_date
    ) THEN
        RAISE EXCEPTION 'Booking conflict for room %: dates overlap with existing reservation', p_room_id;
        RETURN FALSE;
    END IF;

    INSERT INTO reservations (room_id, starting_date, ending_date)
    VALUES (p_room_id, p_starting_date, p_ending_date);

    RETURN TRUE;
END;
$$ LANGUAGE plpgsql;

内容的提问来源于stack exchange,提问作者Adrian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 11:13:53