Oracle PL/SQL触发器,用于根据列中的值与其他表中的值进行比较,防止一个表中的条目
我有以下两个表格: TBL_员工Oracle PL/SQL触发器,用于根据列中的值与其他表中的值进行比较,防止一个表中的条目,oracle,plsql,triggers,sql-update,sql-insert,Oracle,Plsql,Triggers,Sql Update,Sql Insert,我有以下两个表格: TBL_员工 EMP_ID| FIRST_NAME| LAST_NAME| PPS| SALARY| JOB_ID| OFFICE_ID| MANAGER_ID| IND_ID E001 JOHN KENNEDY 12345ABCDE 90000 J001 IN01 E002 BILL CLINTON 12345ABCXE 80000 J0
EMP_ID| FIRST_NAME| LAST_NAME| PPS| SALARY| JOB_ID| OFFICE_ID| MANAGER_ID| IND_ID
E001 JOHN KENNEDY 12345ABCDE 90000 J001 IN01
E002 BILL CLINTON 12345ABCXE 80000 J002 OF01 E001 IN02
E003 BARAK OBAMA 18745ABCXE 80000 J002 OF02 E001 IN03
E004 GORGE BUSH 88745ABCXF 60000 J004 OF04 E002 IN04
E005 GORGE SR. BUSH 45745ABCXS 70000 J003 OF03 E003 IN04
E006 LYNDON JOHNSON 85345ABCYT 75000 J004 OF04 E002 IN06
TBL_客户
CUST_ID| CUST_NAME| CREATED_DATE| TRUSTED| IND_ID| EMP_ID| CUST_SCONT_ID| CUST_PCONT_ID
C100 ACCENTURE 23-DEC-19 N IN04 E004 PA02
C200 PWC 23-DEC-19 N IN05 E005 PA03
C300 ANDERSON 23-DEC-19 N IN03 E003 SA01 PA04
C400 VODAFONE 23-DEC-19 N IN02 E002 SA03 PA01
C500 GOODMAN 23-DEC-19 N IN01 E001 SA05 PA05
我还开发了一个PL/SQL触发器,如果TBL_CUST中的“IND_ID”与TBL_EMPLOYEE不同,它将阻止插入或更新。TBL_CUST表的EMP_ID是外键
CREATE OR REPLACE TRIGGER TRG_check_consistency_of_the_industry
BEFORE INSERT OR UPDATE
ON tbl_cust
FOR EACH ROW
DECLARE
v_industry_type1 varchar2(4);
v_industry_type2 varchar2(4);
BEGIN
IF :new.cust_id IS NOT NULL THEN
v_industry_type1 := :NEW.ind_id;
SELECT e.ind_id INTO v_industry_type2
FROM tbl_cust c
INNER JOIN tbl_employee e ON c.emp_id = e.emp_id
WHERE e.emp_id = :new.emp_id;
IF v_industry_type1 <> v_industry_type2 THEN
raise_application_error(-20025, 'The industry of the customer is not the same the account manager');
END IF;
END IF;
END;
我得到了这个错误
Error starting at line : 56 in command -
INSERT INTO tbl_cust(cust_id, cust_name, ind_id, emp_id,cust_pcont_id) VALUES ('C600', 'DISNEY', 'IN03', 'E006', 'PA06')
Error report -
ORA-01403: no data found
ORA-06512: at "TTAPADAR.TRG_CHECK_CONSISTENCY_OF_THE_INDUSTRY", line 8
ORA-04088: error during execution of trigger 'TTAPADAR.TRG_CHECK_CONSISTENCY_OF_THE_INDUSTRY'
既然你说:
SELECT e.ind_id INTO v_industry_type2
FROM tbl_cust c
INNER JOIN tbl_employee e ON c.emp_id = e.emp_id
WHERE e.emp_id = :new.emp_id;
。。。如果没有插入具有新id的员工,选择将引发“无数据”异常
您需要做的是处理此异常:
CREATE OR REPLACE TRIGGER TRG_check_consistency_of_the_industry
BEFORE INSERT OR UPDATE
ON tbl_cust
FOR EACH ROW
DECLARE
v_industry_type1 varchar2(4);
v_industry_type2 varchar2(4);
BEGIN
IF :new.cust_id IS NOT NULL THEN
v_industry_type1 := :NEW.ind_id;
SELECT e.ind_id INTO v_industry_type2
FROM tbl_cust c
INNER JOIN tbl_employee e ON c.emp_id = e.emp_id
WHERE e.emp_id = :new.emp_id;
IF v_industry_type1 <> v_industry_type2 THEN
raise_application_error(-20025, 'The industry of the customer is not the same the account manager');
END IF;
END IF;
-- handle the exception here
EXCEPTION
WHEN OTHERS THEN
NULL; --> DO NOTHING
END;
希望这能有所帮助。在插入时,tbl_cust表中将不存在现有的员工id,因此我不确定在异常处理中是否能考虑到这一点。我是不是遗漏了什么?我不知道你的评论是什么意思。如果你能解释清楚一点的话。从我所看到的,异常将涵盖它。我很抱歉我之前的评论,但当我使用异常处理时,触发器并没有阻止错误的输入。例如,客户C600与员工E006关联,员工È006与IN06关联,但在这里,我输入了IN03,这是不正确的。基本上,除了ind_id=IN06之外,它应该可以防止我在任何情况下使用员工E006。我希望我现在能说清楚。谢谢我现在明白了。这意味着您应该找到另一种方法来处理逻辑,因为您当前的逻辑没有。我的答案是消除触发错误。
CREATE OR REPLACE TRIGGER TRG_check_consistency_of_the_industry
BEFORE INSERT OR UPDATE
ON tbl_cust
FOR EACH ROW
DECLARE
v_industry_type1 varchar2(4);
v_industry_type2 varchar2(4);
BEGIN
IF :new.cust_id IS NOT NULL THEN
v_industry_type1 := :NEW.ind_id;
SELECT e.ind_id INTO v_industry_type2
FROM tbl_cust c
INNER JOIN tbl_employee e ON c.emp_id = e.emp_id
WHERE e.emp_id = :new.emp_id;
IF v_industry_type1 <> v_industry_type2 THEN
raise_application_error(-20025, 'The industry of the customer is not the same the account manager');
END IF;
END IF;
-- handle the exception here
EXCEPTION
WHEN OTHERS THEN
NULL; --> DO NOTHING
END;