0

嗨,我有以下脚本

CREATE OR REPLACE TRIGGER DOUBLE_BOOKINGS
BEFORE INSERT OR UPDATE ON BOOKING_SESSION
FOR EACH ROW
DECLARE
    session_date TIMESTAMP;
    session_room NUMBER;
BEGIN
    SELECT start_session
        INTO session_date --- EXISTING SESSION
        FROM booking_session
    WHERE bk_room = :NEW.bk_room;
    IF session_date = :NEW.start_session THEN
    RAISE_APPLICATION_ERROR
    (-1000, 'Room is already booked');
    END IF;
END;
/

该脚本假设将任何新预订与同一房间和同一日期的现有预订相匹配(以停止重复预订)

但是它不能正常工作。

SQL> INSERT INTO BOOKING_SESSION VALUES (45,TO_TIMESTAMP('18/03/2012 10:00', '
INSERT INTO BOOKING_SESSION VALUES (45,TO_TIMESTAMP('18/03/2012 10:00', 'DD/MM
            *
ERROR at line 1:
ORA-04098: trigger 'U1146815.ROOM_BOOKED' is invalid and failed re-validation

start_session是我存储预订日期和时间的数据库列名称,并且是时间戳。是booking_session保存预订的名称,bk_room包含房间号。

因此,在提交预订之前,我试图将new预订日期与同一房间的旧预订日期相匹配,然后显示错误消息。

更新

新错误,似乎返回了太多行我怎么能一次做一个。

ERROR at line 1:
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at "U1146815.DOUBLE_BOOKINGS", line 5
ORA-04088: error during execution of trigger 'U1146815.DOUBLE_BOOKINGS'
4

2 回答 2

0

如果您SELECT...INTO在代码中使用,则选择必须返回准确的一行。在其他情况下,它会抛出 NO_DATA_FOUND 异常或 TOO_MANY_ROWS (您的情况)。您可以捕获这些异常,但它会使代码不清楚。更好地使用游标来查询您的记录。

尝试这个

CREATE OR REPLACE TRIGGER DOUBLE_BOOKINGS
BEFORE INSERT OR UPDATE ON BOOKING_SESSION
FOR EACH ROW
DECLARE
    session_date TIMESTAMP;
    session_room NUMBER;
    CURSOR c_existing IS
        SELECT start_session
            FROM booking_session
        WHERE bk_room = :NEW.bk_room and
              session_date = :NEW.start_session;
    dummy_session c_existing.start_session%TYPE;
BEGIN
    OPEN c_existing;
    FETCH c_existing INTO dummy_session;
    IF c_existing%FOUND THEN
       CLOSE c_existing;
       RAISE_APPLICATION_ERROR
          (-1000, 'Room is already booked');
    END IF;
    CLOSE c_existing;
END;

/

于 2012-11-21T04:24:08.480 回答
0

您显然ROOM_BOOKEDBOOKING_SESSION桌子上调用了另一个触发器。并且该触发器处于无效(未编译)状态。

如果您只是想防止具有重复 bk_room/start_session 值的记录,只需向表中添加唯一约束:

ALTER TABLE booking_session
add CONSTRAINT my_constraint UNIQUE (bk_room, start_session);

编辑:您的新错误是因为您在表中有多个具有相同 bk_room 值的记录,这是可以预期的。但是,正如我上面所说,您不需要触发器来防止重复,只需一个独特的约束。

于 2012-11-20T21:50:57.210 回答