Oracle PL/SQL触发器,用于根据列中的值与其他表中的值进行比较,防止一个表中的条目

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

我有以下两个表格:

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   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;