Sql _应用程序错误(-20000,‘审核日期不能早于测试结束日期’); 如果结束; 结束; /

Sql _应用程序错误(-20000,‘审核日期不能早于测试结束日期’); 如果结束; 结束; /,sql,oracle,database-trigger,Sql,Oracle,Database Trigger,干杯 首先,您必须返回到某个变量中此外,如果您的查询返回多行,则无法执行此操作。如果驾驶员多次检查或测试同一辆车会发生什么情况?@GordonLinoff假设驾驶员不会对同一辆车进行两次测试。当然,这不是一个现实的假设,但这是问题中给我的限制之一。 CREATE TABLE review ( review_id NUMBER(2) NOT NULL, review_date DATE NOT NULL, review_rating NUMBER(1) NOT NULL,

干杯

首先,您必须返回到某个变量中此外,如果您的查询返回多行,则无法执行此操作。如果驾驶员多次检查或测试同一辆车会发生什么情况?@GordonLinoff假设驾驶员不会对同一辆车进行两次测试。当然,这不是一个现实的假设,但这是问题中给我的限制之一。
CREATE TABLE review 
(
    review_id NUMBER(2) NOT NULL,
    review_date DATE NOT NULL,
    review_rating NUMBER(1) NOT NULL,
    driver_no NUMBER(2) NOT NULL,
    vehicle_id NUMBER(3) NOT NULL
);

CREATE TABLE testing 
(
    testing_id NUMBER(2) NOT NULL,
    testing_start DATE NOT NULL,
    testing_end DATE NOT NULL
    driver_no NUMBER(2) NOT NULL,
    vehicle_id NUMBER(3) NOT NULL
);
CREATE OR REPLACE TRIGGER review_check_validity
AFTER INSERT ON review
FOR EACH ROW
BEGIN
    SELECT testing_start
    FROM testing
    WHERE driver_no = :new.driver_no;

    SELECT vehicle_id
    FROM testing
    WHERE driver_no = :new.driver_no;

    IF :new.review_date < testing_end THEN
    raise_application_error(-20000, 'Review date cannot be before 
    testing end date');

    END IF;

    IF :new.vehicle_id != vehicle_id THEN
    raise_application_error(-20000, 'Driver has never driven this 
    vehicle');

    END IF;
END;
/
CREATE OR REPLACE TRIGGER review_check_validity
AFTER INSERT ON review
FOR EACH ROW

-- Need to declare variables for usage in your SELECT fetches.
DECLARE
var_revdate number; -- or date, if applicable
var_revvehi number; -- or varchar(n), if applicable

BEGIN
    -- In here you should have an INTO clause to assign your date parameter into 
    -- the predefined variable. As well, you need to ensure this fetch will provide
    -- only one row.

    SELECT testing_start INTO var_revdate -- why are you fetching "testing_start"?
        FROM testing
            WHERE driver_no = :new.driver_no;

    -- Same case, it can only retrieve one row. If you need to do more than one row, 
    -- you may need to use a BULK & a LOOP.

    SELECT vehicle_id INTO var_vehicid
        FROM testing
            WHERE driver_no = :new.driver_no;

    IF :new.review_date < testing_end THEN
    raise_application_error(-20000, 'Review date cannot be before testing end date');

    END IF;

    IF :new.vehicle_id != var_vehicid THEN
    raise_application_error(-20000, 'Driver has never driven this vehicle');

    END IF;
END;
/
CREATE OR REPLACE TRIGGER review_check_validity
AFTER INSERT ON review
FOR EACH ROW
DECLARE
    testEnd DATE;
    vehicleTestCount NUMBER;
BEGIN

    SELECT COUNT(*)
      INTO vehicleTestCount
      FROM testing
      WHERE vehicle_id = :new.vehicle_id;

    IF vehicleTestCount = 0 THEN
      raise_application_error(-20000, 'Driver has never driven this vehicle');
    END IF;

    -- Assumes one test per driver per vehicle
    SELECT testing_end
      INTO testEnd
      FROM testing
      WHERE driver_no = :new.driver_no
        AND vehicle_id = :new.vehicle_id;

    IF :new.review_date < testEnd THEN
      raise_application_error(-20000, 'Review date cannot be before 
    testing end date');

    END IF;

END;
/
CREATE OR REPLACE TRIGGER REVIEW_CHECK_VALIDITY 
BEFORE INSERT ON REVIEW -- USING BEFORE INSERT TRIGGER TO AVOID ANY UNDOs
    FOR EACH ROW
DECLARE
    LV_TEST_END_DATE   DATE;
    LV_TEST_COUNT      NUMBER;
BEGIN
    -- FETCHING RELEVANT DATA USING SINGLE QUERY
    SELECT
        COUNT(1),
        MAX(TESTING_END) -- PLEASE HANDLE THE SCENARIO WHERE THE TESTING END DATE IS NULL
    INTO
        LV_TEST_COUNT,
        LV_TEST_END_DATE
    FROM
        TESTING
    WHERE
        VEHICLE_ID = :NEW.VEHICLE_ID
        AND DRIVER_NO = :NEW.DRIVER_NO;

    IF LV_TEST_COUNT = 0 THEN
        RAISE_APPLICATION_ERROR(-20000, 'Driver has never driven this vehicle');
    ELSIF :NEW.REVIEW_DATE < LV_TEST_END_DATE THEN
        RAISE_APPLICATION_ERROR(-20000, 'Review date cannot be before testing end date');
    END IF;

END;
/