0

我正在尝试创建一个触发器,当将记录插入员工表(新员工)时,触发器会触发并将记录作为“N/A”插入到employee_dept_history 表中(因为该员工是新员工)并且没有以前的部门)。此外,如果当前员工切换部门,则触发器应在 employee_dept_history 表中插入一条记录,并且员工 depatment_id 会更改。我在创建此触发器时遇到问题。我想知道是否有人可以用我的代码引导我走向正确的方向。我无法让下面的触发器显示“N/A”。我怎样才能使这个触发器工作?我需要为新旧部门创建局部变量吗?

CREATE OR REPLACE TRIGGER employee_dept_trigger
   BEFORE INSERT OR UPDATE ON employee
   FOR EACH ROW

BEGIN
   INSERT INTO employee_dept_history
   VALUES(:NEW.employee_id, 
       :NEW.employee_name, 
        from_department_name (NEEDS TO OUTPUT 'N/A'),
        to_department_name, 
        sysdate);
 END employee_dept_trigger;

EMPLOYEE_DEPT_HISTORY 表如下所示:

CREATE TABLE empployee_dept_history
(
    EMPLOYEE_ID NUMBER(4)
    EMPLOYEE_NAME VARCHAR2(50)
    FROM_DEPARTMENT_NAME VARCHAR2(50)
    TO_DEPARTMENT_NAME VARCHAR2(50)
    OPERATION_TIME DATE
);

员工表:

(
    EMPLOYEE_ID NUMBER(4)
    EMPLOYEE_NAME VARCHAR2(20)
    JOB VARCHAR2(50)
    MANAGER_ID NUMBER(4)
    HIRE_DATE DATE
    SALARY NUMBER(9)
    COMMISION NUMBER(9)
    DEPARTMENT_ID NUMBER(4)
);
4

3 回答 3

2

注意:这个答案与其他两个类似,但我还是会发布它,因为它以一种可能有用的方式不同地定义了触发器。请注意,我已经对其他两个答案投了赞成票,因为它们会很好地完成这项工作。

首先,如果您只对DEPARTMENT_ID列的更改感兴趣,您可以在触发器定义中指定:

CREATE OR REPLACE TRIGGER employee_dept_trigger
   BEFORE INSERT OR UPDATE OF department_id ON employee
   FOR EACH ROW
....

触发器可以使用“自动”逻辑值INSERTINGUPDATING确定是插入还是更新调用它。您可以使用该INSERTING值来指示这是一个新员工:

IF INSERTING THEN
   -- set old department name = 'N/A'
ELSE
   -- set old department name = whatever
END IF;

您的问题没有描述部门名称的来源,因此当涉及部门名称时,此示例下降为伪代码:

CREATE OR REPLACE TRIGGER employee_dept_trigger
   BEFORE INSERT OR UPDATE OF department_id ON employee
   FOR EACH ROW
BEGIN
  IF INSERTING THEN
    -- New employee
    INSERT INTO employee_dept_history VALUES (
       :NEW.employee_id,
       :NEW.employee_name,
       'N/A',
       (SELECT department_name from ...), <-- based on :NEW.department_id
       SYSDATE);
  ELSE
    -- Existing employee
    INSERT INTO employee_dept_history VALUES (
       :NEW.employee_id,
       :NEW.employee_name,
       (SELECT department_name from ...), <-- based on :OLD.department_id
       (SELECT department_name from ...), <-- based on :NEW.department_id
       SYSDATE);
  END IF;
END employee_dept_trigger;
于 2013-06-06T18:42:20.883 回答
1

你可能想要这样的东西:

CREATE OR REPLACE TRIGGER employee_dept_trigger
   BEFORE INSERT OR UPDATE ON employee
   FOR EACH ROW

BEGIN

IF INSERTING THEN
   INSERT INTO employee_dept_history
   VALUES(:NEW.employee_id, 
       :NEW.employee_name, 
        'N/A',
        :NEW.DEPARTMENT_ID, 
        sysdate);
ELSE
   INSERT INTO employee_dept_history
   VALUES(:NEW.employee_id, 
       :NEW.employee_name, 
       :OLD.DEPARTMENT_ID, 
       :NEW.DEPARTMENT_ID,
        sysdate);
END IF;
 END employee_dept_trigger;

虽然您还没有指出部门名称的来源,但它还不是很正确。我使用部门 ID 只是为了给你一个想法..

于 2013-06-06T18:39:04.117 回答
1

要么是

CREATE OR REPLACE TRIGGER employee_dept_trigger
   BEFORE INSERT OR UPDATE ON employee
   FOR EACH ROW
DECLARE
  from_department_name varchar(255);
  to_department_name varchar(255);
BEGIN
   select from DEPARTMENT where DEPARTMENT_ID=:NEW.DEPARTMENT_ID into to_department_name;
   IF INSERTING THEN
   INSERT INTO employee_dept_history
   VALUES(:NEW.employee_id, 
       :NEW.employee_name, 
        'N/A',
        to_department_name, 
        sysdate);
   end if;
   IF UPDATING THEN
   select from DEPARTMENT where DEPARTMENT_ID=:OLD.DEPARTMENT_ID into from_department_name;
   INSERT INTO employee_dept_history
   VALUES(:NEW.employee_id, 
        :NEW.employee_name, 
        from_department_name ,
        to_department_name, 
        sysdate);
   end if;
 END employee_dept_trig;

或者我不明白你的问题。

于 2013-06-06T18:30:41.213 回答