简体   繁体   中英

Replacing a subquery in a PL/SQL trigger

I have 2 tables. One called Employee and the other Employee_jobs . One of the fields in the Employee table is job_name . The Employee_jobs table contains 2 fields, job_name , and Emp_count (number of employees per job). What i'm trying to do is whenever i perform an operation on the Employee table then it would automatically adjust the Employee_jobs table. This basically means i have to add all the job names from the first table and count the amount of people per job into the second table. This is what i've come up with.

CREATE OR REPLACE TRIGGER TR_JOB_UPDATE
    AFTER INSERT OR UPDATE OR DELETE
    ON EMPLOYEE
    FOR EACH ROW
    BEGIN
        IF inserting THEN
            IF :NEW.JOB_NAME IN(Select JOB_NAME FROM EMPLOYEE_JOBS) THEN
                UPDATE EMPLOYEE_JOBS
                SET EMP_COUNT = EMP_COUNT + 1 WHERE JOB_NAME = :NEW.JOB_NAME;
            ELSE
                insert into EMPLOYEE_JOBS(JOB_NAME)
                VALUES(:NEW.JOB_NAME);
            END IF;
        ELSIF deleting THEN
            UPDATE EMPLOYEE_JOBS
            SET EMP_COUNT = EMP_COUNT - 1 WHERE JOB_NAME = :NEW.JOB_NAME;
        END IF;
    END;
/

I still have to do the update part but i want to get this to work first. I realized using a subquery within the logic block is not allowed but i am not sure how to replace that statement. I figured that i would need to check if the job is already present or not in the second table and take different actions based on that.

I am required to use a Trigger to make this possible.

You can use the MERGE statement as follows:

merge into EMPLOYEE_JOBS ej
using (select :NEW.JOB_NAME as new_job_name from dual) as j
   on (ej.JOB_NAME = j.new_job_name)
when matched then
     update set ej.emp_count = ej.emp_count + case when deleting then -1 else 1 end
when not matched then
     insert (job_name, emp_count) values (:NEW.JOB_NAME, 1)

You can simplify the trigger. First check if the value exists in the table. Then do a single update:

CREATE OR REPLACE TRIGGER TR_JOB_UPDATE
    AFTER INSERT OR UPDATE OR DELETE
    ON EMPLOYEE
    FOR EACH ROW
BEGIN
    INSERT INTO EMPLOYEE_JOBS (JOB_NAME, EMP_COUNT)
        SELECT :NEW.JOB_NAME, 0
        FROM dual
        :NEW.JOB_NAME NOT IN (Select JOB_NAME FROM EMPLOYEE_JOBS) ;

    UPDATE EMPLOYEE_JOBS
        SET EMP_COUNT = EMP_COUNT +
                        (CASE WHEN inserting THEN 1 ELSE 0 END) +
                        (CASE WHEN deleting THEN -1 ELSE 0 END);
        WHERE JOB_NAME = :NEW.JOB_NAME;
    END IF;
END;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM