簡體   English   中英

缺少END-Mysql存儲過程

[英]Missing END - Mysql Stored Procedure

我非常習慣於使用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 ;

那只是第一次。 未經測試。 我們可能希望將<=>=更改為<> ,這取決於我們是否認為恰好在上午10點結束的預訂與在上午10點開始的期間重疊。

在過程頂部聲明變量。 同樣,您在IF語句之后不使用THEN 更正代碼。 另外,在關閉IF塊之前要關閉loop

CREATE PROCEDURE `Get_AvailRooms` (IN StartDate datetime, IN EndDate datetime, IN RoomType int)
BEGIN
    DECLARE PStartDate datetime;
    DECLARE PEndDate datetime;
    DECLARE PRoomType int;
    DECLARE AvailRooms CURSOR FOR SELECT * FROM AvaliableNowRooms;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    DECLARE RoomID INT;
    DECLARE Bookings CURSOR FOR SELECT BookingStartDate, BookingEndDate,   BookingRoomID FROM Booking WHERE BookingRoomID = RoomID AND BookingEndDate < PStartDate;
    DECLARE PBookingStartDate datetime;
    DECLARE PBookingEndDate datetime;
    DECLARE PBookingRoomID,
    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); 

    OPEN AvailRooms;

    read_loop: LOOP

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

            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 THEN
                LEAVE Booking_Read;
            ELSE IF PBookingEndDate BETWEEN PStartDate AND PEndDate THEN
                LEAVE Booking_Read;
            ELSE
                INSERT INTO ReturnAvalRooms (id) values (PBookingRoomid);
            END;
            END LOOP;
            CLOSE Bookings;
            END

    END LOOP;
    CLOSE AvailRooms;
    END

    SELECT * FROM ReturnAvalRooms

END

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM