代码之家  ›  专栏  ›  技术社区  ›  sens31

触发允许每个客户拥有一辆车,并且在租赁和归还日期之间不允许另一个客户租赁已经租赁的车辆

  •  0
  • sens31  · 技术社区  · 4 年前

    我有一个基于数据库(Oracle)的项目,创建一个汽车租赁店。到目前为止,一切都很顺利,但我被一个触发器卡住了,它必须在租车和归还日期之间检查客户和车辆,这样已经租车的客户就不能再租车,而另一个客户就不能再租车了。

    租金表:

    CREATE TABLE RentAuto
    (
    auto_id INT,
    customer_id INT,
    employee_id INT,
    date_rent DATE,
    date_return DATE,
    rent_days VARCHAR2(5)
    );
    

    汽车表:

    CREATE TABLE Automobile 
    (
    auto_id INTEGER NOT NULL,
    year_of_production VARCHAR(10),
    auto_current_km VARCHAR(20),
    price_per_day VARCHAR(20),
    color_id INT,
    is_auto_av INT,
    model_id INT,
    PRIMARY KEY(auto_id)
    );
    

    在表格中插入:

    INSERT INTO RentAuto (auto_id,customer_id,employee_id,date_rent,date_return, rent_days)
    VALUES(14,13,3,TO_DATE(sysdate, 'dd-mm-yyyy'), '29-03-2022','2');
    

    我在下面写的触发器在IF语句中给了我一个错误,我不知道如何修复它。 ( PLS-00201:标识符“新”。必须声明“客户ID”

    create or replace TRIGGER RENTINGTRIGGER
    BEFORE INSERT OR UPDATE OF AUTO_ID,CUSTOMER_ID,DATE_RENT,DATE_RETURN ON RENTAUTO
    FOR EACH ROW
    BEGIN
    IF RENTAUTO.CUSTOMER_ID = :NEW.CUSTOMER_ID
    and ((new.DATE_RENT >= RentAuto.DATE_RETURN and new.DATE_RENT < RentAuto.DATE_RETURN)
            or (new.DATE_RETURN > RentAuto.DATE_RENT and new.DATE_RETURN < RentAuto.DATE_RETURN))
    THEN
    RAISE_APPLICATION_ERROR(-2099, 'You can only book one car per single customer a day');
    IF RentAuto.AUTO_ID = :NEW.AUTO_ID
    and 
     ((new.date_rent >= RentAuto.date_return and new.date_rent < RentAuto.date_return)
        or (new.date_return > RentAuto.date_rent and new.date_return < RentAuto.date_return))
    THEN
    RAISE_APPLICATION_ERROR(-2099, 'Car has already been rented by another customer!');
    END IF;
    END IF;
    END;
    
    0 回复  |  直到 4 年前
        1
  •  0
  •   Thorsten Kettner    4 年前

    下面是一个简单的after语句触发器,当insert或update导致客户每天预订多辆车或一辆车每天预订不止一次时,它会引发一个异常。

    如果insert或update语句位于多行上,触发器不会告诉我们哪个预订导致了失败。此外,每次插入或更新时,我们都必须扫描整个表以查找冲突。如果只想对插入或更新的行做出反应,则需要一个复合触发器,在该触发器中,您可以记住“每行之后”部分中有问题的行,然后将它们与“after statement”部分中表中的其他行进行比较。

    CREATE OR REPLACE TRIGGER rentingtrigger
    AFTER INSERT OR UPDATE OF auto_id, customer_id, date_rent, date_return ON rentauto
      v_count INTEGER;
    BEGIN
      select count(*)
      into v_count
      from rentauto
      where exists
      (
        select null
        from rentauto other
        where other.customer_id = rentauto.customer_id
        and other.date_rent <= rentauto.date_return
        and other.date_return >= rentauto.date_rent
        and other.rowid <> rentauto.rowid
      );
    
      IF v_count > 0 THEN
        RAISE_APPLICATION_ERROR(-20099, 'You can only book one car per single customer a day');
      END IF;
    
      select count(*)
      into v_count
      from rentauto
      where exists
      (
        select null
        from rentauto other
        where other.auto_id = rentauto.auto_id
        and other.date_rent <= rentauto.date_return
        and other.date_return >= rentauto.date_rent
        and other.rowid <> rentauto.rowid
      );
    
      IF v_count > 0 THEN
        RAISE_APPLICATION_ERROR(-20099, 'Car has already been rented by another customer!');
      END IF;
    END rentingtrigger;