多次更新一条记录时遇到错误。
SQL代码:
UPDATE EMPLOYEES
SET FIRST_NAME='J',
LAST_NAME='E',
EMAIL='asdfghjvbn789@yahoo.com',
PHONE_NUMBER='123456789',
HIRE_DATE='10/13/2015',
JOB_ID=(SELECT JOB_ID FROM JOBS WHERE JOB_TITLE='Programmer'),
SALARY=4000,
COMMISSION_PCT=0,
DEPARTMENT_ID=(SELECT DEPARTMENT_ID FROM DEPARTMENTS WHERE DEPARTMENT_NAME='IT'),
MANAGER_ID=(SELECT MANAGER_ID FROM DEPARTMENTS WHERE DEPARTMENT_NAME='IT')
WHERE EMPLOYEE_ID=15;
错误消息:
Error starting at line : 1 in command -
UPDATE EMPLOYEES SET FIRST_NAME='J', LAST_NAME='E', EMAIL='asdfghjvbn789@yahoo.com', PHONE_NUMBER='123456789',
HIRE_DATE='10/13/2015',
JOB_ID=(SELECT JOB_ID FROM JOBS WHERE JOB_TITLE='Programmer'), SALARY=4000, COMMISSION_PCT=0,
DEPARTMENT_ID=(SELECT DEPARTMENT_ID FROM DEPARTMENTS WHERE DEPARTMENT_NAME='IT'),
MANAGER_ID=(SELECT MANAGER_ID FROM DEPARTMENTS WHERE DEPARTMENT_NAME='IT') WHERE EMPLOYEE_ID=15
Error report -
SQL Error: ORA-00001: unique constraint (GAS.JHIST_EMP_ID_ST_DATE_PK) violated
ORA-06512: at "GAS.ADD_JOB_HISTORY", line 10
ORA-06512: at "GAS.UPDATE_JOB_HISTORY", line 2
ORA-04088: error during execution of trigger 'GAS.UPDATE_JOB_HISTORY'
00001. 00000 - "unique constraint (%s.%s) violated"
*Cause: An UPDATE or INSERT statement attempted to insert a duplicate key.
For Trusted Oracle configured in DBMS MAC mode, you may see
this message if a duplicate entry exists at a different level.
*Action: Either remove the unique restriction or do not insert the key.
这是触发器:(再次来自评论部分)
CREATE OR REPLACE TRIGGER "GAS"."UPDATE_JOB_HISTORY"
AFTER UPDATE OF job_id, department_id
ON employees FOR EACH ROW
BEGIN
add_job_history(:old.employee_id,
:old.hire_date,
sysdate,
:old.job_id,
:old.department_id);
END;
/
ALTER TRIGGER "GAS"."UPDATE_JOB_HISTORY" ENABLE;
以下是add_job_history
的代码。
create or replace PROCEDURE add_job_history ( p_emp_id job_history.employee_id%type ,
p_start_date job_history.start_date%type ,
p_end_date job_history.end_date%type , p_job_id job_history.job_id%type ,
p_department_id job_history.department_id%type )
IS
BEGIN
INSERT INTO job_history (employee_id,
start_date,
end_date,
job_id,
department_id)
VALUES(p_emp_id,
p_start_date,
p_end_date,
p_job_id,
p_department_id);
END add_job_history;
答案 0 :(得分:0)
错误消息告诉您更新失败的确切原因:
SQL Error: ORA-00001: unique constraint (GAS.JHIST_EMP_ID_ST_DATE_PK) violated
假设您的命名约定值得信赖,则表明您在(EMP_ID, START_DATE)
的JOB_HISTORY上有一个主键。请注意,触发器将EMPLOYEE.HIRE_DATE作为START_DATE传递,这意味着它对于JOB_HISTORY中的所有记录都是相同的。
因此,您只能为该表中的每位员工提供一条记录。对于日记表而言,这似乎过于严格,可能不是您的意图。
因此,正确的解决方案是使用START_DATE值来填充JOB_HISTORY,这些值代表每个赋值的开始,因此对于每个记录都是不同的。
或者,您需要向该键添加另一列。您可以使用END_DATE,因为它表示旧任务的结束。或者一个新列,例如序列ID或时间戳,您可以使用它来跟踪员工的历史记录。
您在评论中说,您根本无法更改数据结构。这样就可以正确设置START_DATE分配。鉴于“工作历史”代表已关闭分配的日记帐,您可以通过以下方式查找当前(即将关闭)分配的开始日期:
select max(end_date)
from job_history
where employee_id = 15;
此逻辑的正确位置在add_job_history()
,并忽略或删除p_start_date
参数。你可以把它放在触发器代码中,但那是笨重的。