我试图在oracle中使用游标来迭代guest表中的GuestID,如果Booking表中没有相应的GuestID,则删除该条目。这样,如果客人取消预订,这是他们所做的唯一预订,它将从客人表中删除客人的详细信息。
程序如果如下并编译没有任何问题:
-- Remove a guest from the guest table if no booking exists for their guestID
CREATE OR REPLACE PROCEDURE RemoveGuest (Selection IN Booking.GuestID%TYPE)
IS
guest_id Guest.GuestID%type;
CURSOR c_guests is
SELECT GuestID FROM GUEST;
BEGIN
OPEN c_guests;
LOOP
FETCH c_guests into guest_id;
IF c_guests%notfound THEN
DELETE FROM Guest WHERE Guest.GuestID = Selection;
ELSIF c_guests%found THEN
DBMS_OUTPUT.PUT_LINE('Guest ' || Selection || ' is associated with a booking, cannot remove');
END IF;
END LOOP;
CLOSE c_guests;
END;
/
但是当我运行它时,它就会像卡在无限循环中一样挂起:
有人能看到此代码中的问题所在吗?我知道我也可以做一个触发器以获得相同的功能,而且我比Cursor更适应那些,但我只是想知道为什么它不起作用?
答案 0 :(得分:1)
如果您将光标用作练习,那么您希望光标检查访客是否存在于Booking
表而不是Guest
表中。当您打开光标时,您不需要循环,因为您只需要检查一件事:是否找到了记录?如果没有,请从Guest
删除,但在任何一种情况下,您都不需要再查看任何记录。
CREATE OR REPLACE PROCEDURE RemoveGuest (Selection IN Booking.GuestID%TYPE)
IS
guest_id Guest.GuestID%type;
CURSOR c_bookings_for_guest is
SELECT GuestID
FROM Booking
WHERE GuestID = Selection;
BEGIN
OPEN c_guests;
FETCH c_guests into guest_id;
IF c_guests%notfound THEN
DELETE FROM Guest WHERE Guest.GuestID = Selection;
END IF;
CLOSE c_guests;
END;
没有游标(可能需要检查语法):
DELETE FROM Guest
WHERE GuestID = Selection
AND NOT EXISTS (SELECT Selection FROM Booking WHERE GuestID = Selection) ;