我正在尝试创建一个触发器,当一个记录插入到employee表(一个新员工)时,触发器触发并将一条记录作为'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表:
(
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)
);
答案 0 :(得分:2)
注意:这个答案类似于其他两个,但我会发布它,因为它以一种可能有用的方式不同地定义触发器。 请注意,我已经对其他两个答案进行了投票,因为他们会很好地完成这项工作。
首先,如果您只对DEPARTMENT_ID
列的更改感兴趣,可以在触发器定义中指定:
CREATE OR REPLACE TRIGGER employee_dept_trigger
BEFORE INSERT OR UPDATE OF department_id ON employee
FOR EACH ROW
....
触发器可以使用“自动”逻辑值INSERTING
和UPDATING
来确定插入或更新是否称为它。您可以使用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;
答案 1 :(得分: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;
或者我不明白你的问题。
答案 2 :(得分: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只是为了给你一个想法..