我非常习惯于使用TSQL进行编写,而MySQL会进行一些调整,但我想我已经掌握了大部分。我有一个存储过程,但是不会让步,我已经读取并重新读取了100次,读取了所有可以发现的错误,但仍然没有运气。

在第11行以及该语句的结尾:

CREATE TEMPORARY TABLE ReturnAvalRooms (roomID int);


即使出现在查询的开头,我也会收到错误“ Missing End”。
我检查并仔细检查了所有内容是否都已声明并设置了适当的内容;但无法弄清楚为什么我会收到此错误。

以下是存储过程的完整副本。

    CREATE PROCEDURE `Get_AvailRooms` (IN StartDate datetime, IN EndDate datetime, IN RoomType int)
BEGIN
    DECLARE PStartDate datetime;
    DECLARE PEndDate datetime;
    DECLARE PRoomType int;
    SET PStartDate = StartDate;
    SET PEndDate = EndDate;
    SET PRoomType = RoomType;

        CREATE TEMPORARY TABLE AvaliableNowRooms AS (SELECT idRooms FROM rooms WHERE RoomNextAvail < PStartDate AND RoomTypeID = PRoomType);
        CREATE TEMPORARY TABLE ReturnAvalRooms (roomID int);

    DECLARE AvailRooms CURSOR FOR SELECT * FROM AvaliableNowRooms;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    DECLARE RoomID INT;

    OPEN AvailRooms;

    read_loop: LOOP

    FETCH AvailRooms INTO RoomID;
        IF done THEN
            LEAVE read_loop;
        END IF;

            DECLARE Bookings CURSOR FOR SELECT BookingStartDate, BookingEndDate, BookingRoomID FROM Booking WHERE BookingRoomID = RoomID AND BookingEndDate < PStartDate;
            DECLARE PBookingStartDate datetime;
            DECLARE PBookingEndDate datetime;
            DECLARE PBookingRoomID,

            OPEN Bookings

            Booking_Read: LOOP
            FETCH Bookings INTO PBookingStartDate, PBookingEndDate, PBookingRoomID;
            IF done THEN
                LEAVE Booking_Read;
            END IF;

            IF PBookingStartDate BETWEEN PStartDate AND PEndDate
                LEAVE Booking_Read;
            ELSE IF PBookingEndDate BETWEEN PStartDate AND PEndDate
                LEAVE Booking_Read;
            ELSE
                INSERT INTO ReturnAvalRooms (id) values (PBookingRoomid);
            END LOOP;
            CLOSE Bookings;
            END

    END LOOP;
    CLOSE AvailRooms;
    END

    SELECT * FROM ReturnAvalRooms

END

最佳答案

MySQL特别注重DECLARE语句的顺序。在一个区块内,这些必须首先出现。而且(我相信)处理程序必须是最后的声明。

我对您打算返回的程序感到困惑。似乎您想返回指定类型的所有房间,对于这些房间,没有与指定时间段重叠的预订。

但是,看一下过程中的逻辑,似乎如果预订给定房间的行没有排,该房间将不会被退回。这似乎很奇怪。令我感到困惑的是,这到底应该返回什么。大量不必要的混乱使规范变得模糊。

整个操作过程可以通过一条简单的SQL语句来完成,该语句更简单,更清晰并且启动效率更高。

DELIMITER $$

CREATE PROCEDURE `Get_AvailRooms` (IN PStartDate datetime, IN PEndDate datetime, IN PRoomType int)
BEGIN
-- rooms of the specified type which are "available" for the
-- specified period.  A room is considered not available if
-- the RoomNextAvail col has a date value later than the beginning
-- of the specified period, or there are one or more bookings that
-- overlap that period. If the specified StartDate is later than
-- the specified EndDate, then no rooms are available.
--
-- This query uses an "anti-join" pattern to return only rows
-- in rooms which don't have a overlapping booking

   SELECT r.idRooms
     FROM rooms r
     LEFT
     JOIN Booking b
       ON b.BookingRoomID = r.idRooms
      AND b.BookingEndDate    >= PStartDate
      AND b.BookingStartDate  <= PEndDate
    WHERE b.idRooms IS NULL
      AND r.RoomTypeID        = PRoomType
      AND r.RoomNextAvail     < PStartDate
      AND          PStartDate < PEndDate
    ORDER BY r.idRooms;

END$$

DELIMITER ;


那只是第一次。未经测试。我们可能希望将<=>=分别更改为<>,这取决于我们是否认为恰好在10AM结束的预订与从10AM开始的时间段重叠。

关于mysql - 缺少END-Mysql存储过程,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35715757/

10-11 04:50
查看更多