Oracle中的游标

时间:2014-04-24 23:14:48

标签: oracle

我试图在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;
/

但是当我运行它时,它就会像卡在无限循环中一样挂起: Anonymous PL/SQL block calling stored procedure and hanging

有人能看到此代码中的问题所在吗?我知道我也可以做一个触发器以获得相同的功能,而且我比Cursor更适应那些,但我只是想知道为什么它不起作用?

1 个答案:

答案 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) ;