查看Oracle的两个日期是否超过6个月

时间:2011-11-12 13:21:44

标签: sql oracle plsql triggers

所以对于我的大学课程,我必须为航空公司创建一个oracle数据库。 (这是我第一次使用oracle)

我的部分要求是确定飞行员是否适合飞行。为此,我的员工和pilot_test表格设置如下:

CREATE TABLE PILOT_TEST (
  TEST_ID NUMBER(11) PRIMARY KEY,
  TEST_DATE DATE NOT NULL,
  EMPLOYEE_ID NUMBER(11) NOT NULL
);

CREATE TABLE EMPLOYEE (
  EMPLOYEE_ID NUMBER(5) PRIMARY KEY,
  FIRST_NAME VARCHAR2(15) NOT NULL,
  LAST_NAME VARCHAR2(20) NOT NULL,
  MIDDLE_NAME VARCHAR2(15) NULL,
  POSITION VARCHAR2(13) NOT NULL, /* pilot, booking clerk, maintenance staff*/
  EMPLOYED_FROM DATE NOT NULL,
  EMPLOYED_TO DATE NOT NULL,
  TELEPHONE NUMBER(11) NOT NULL,
  EMAIL VARCHAR2(40) NULL,
  ADDRESS_LINE1 VARCHAR2(20) NOT NULL,
  ADDRESS_LINE2 VARCHAR2(20) NULL,
  TOWN VARCHAR2(20) NOT NULL,
  POST_CODE VARCHAR2(9) NOT NULL,
  SALARY NUMBER(6,2) NOT NULL,
  STATUS VARCHAR2(16) NOT NULL /*working, on leave, contract expired, fired*/
);

无论何时向系统添加新航班,我都会使用触发器来检查分配给飞机的人员是否实际上是飞行员。 在这个触发器中,我想检查一下,如果他是一名飞行员,那么他的最后一个TEST_DATE是否不到6个月。关于如何做到这一点的任何想法?

我当前的触发器看起来像这样

CREATE OR REPLACE TRIGGER CHECK_PILOT_ALLOCATION
BEFORE INSERT ON FLIGHT
FOR EACH ROW
DECLARE 
    TEMP_POSITION VARCHAR2(13);
BEGIN

SELECT POSITION INTO TEMP_POSITION 
FROM EMPLOYEE
WHERE EMPLOYEE_ID = :NEW.PILOT_ID;

IF UPPER (TEMP_POSITION) <> 'PILOT' THEN
RAISE_APPLICATION_ERROR (-20001, 'Assigned employee is not a pilot');

ELSIF   
END IF;
END;
/

2 个答案:

答案 0 :(得分:2)

DECLARE 
    TEMP_POSITION VARCHAR2(13);
    TEMP_TESTDATE DATE;
BEGIN

SELECT E.POSITION, 
       (SELECT MAX (TEST_DATE) 
          FROM PILOT_TEST PT 
         WHERE PT.TEST_DATE <= SYSDATE 
           AND PT.EMPLOYEE_ID = E.EMPLOYEE_ID) TEST_DATE 
  INTO TEMP_POSITION, 
       TEMP_TESTDATE 
  FROM EMPLOYEE E
 WHERE E.EMPLOYEE_ID = :NEW.PILOT_ID;

IF UPPER (TEMP_POSITION) <> 'PILOT' 
THEN
   RAISE_APPLICATION_ERROR (-20001, 'Assigned employee is not a pilot');
END IF;

IF ( SYSDATE - TEMP_TESTDATE ) > 182 
THEN
   RAISE_APPLICATION_ERROR (-20001, 'Assigned pilot has not been tested in the last 6 months');
END IF;

END;

答案 1 :(得分:2)

我只是将两张桌子连在一起,检查他们是否是飞行员。可以使用案例陈述来检查证书日期。请注意是否存在内置的ADD_MONTHS函数来为您执行日期算术运算。我喜欢在select语句中尽我所能。最后,我会检查员工是否存在以及异常处理程序。一般来说,您应始终为SQL提供异常处理程序。我已经看到太多的情况,有人认为,因为记录应该在那里他们没有处理异常,当然它最终确实发生了。此时,Oracle会以一种不正常的方式生成异常。

BEGIN

  SELECT e.employee_id, NVL(UPPER(e.position),'xx')
       , CASE WHEN ADD_MONTHS(MAX(test_date), 6) > SYSDATE THEN 1 ELSE 0 END date_ck
    INTO v_id, v_pos, v_date_ck
    FROM employee e LEFT JOIN pilot_test p ON e.employee_id = p.employee_id
   WHERE e.employee_id = :new.pilot_id
   GROUP BY e.employee_id, NVL(UPPER(e.position),'xx');

  IF v_pos <> 'PILOT' THEN
    RAISE_APPLICATION_ERROR (-20001, 'Not a pilot');
  ELSIF v_date_ck = 0 THEN
    RAISE_APPLICATION_ERROR (-20002, 'Not recently tested');
  END IF;

EXCEPTION
  WHEN OTHERS THEN
    RAISE_APPLICATION_ERROR (-20003, 'Not an employee');
END;