Triggers

Embed Size (px)

DESCRIPTION

Triggers

Citation preview

DatabaseTrigger:(It cannot be used in Application i.e frontend):-----------------------------------------------------------------------------------Database Trigger is Event Based database Object From PL/SQL. This Object is used to apply business rules on database. Business rules are user specific validation.Database Trigger execution is decided by Oracle server based on the event defined for trigger. These events are (i.e)Database Events are categorised into four groups:-------------------------------------------------------------------1)DML Events:(Used On Table)-INSERT-UPDATE-DELETE2)Instead Of Event (Used On view)3)DDL Events:(Used On Any Database Object)-CREATE-ALTER-DROP4)Database Events:-After Startup-Before Shutdown-After Login-Before Logout-ON Server Error.DML Triggers:==========*)Are Used to protect Data Manipulation on tables.*)DML Triggers have:-->Two Execution Time --> BEFORE /AFTER EVENT--> Three Events (INSERT or DELETE or UPDATE)( INSERT or DELETE)( INSERT or UPDATE)(UPDATE or DELETE)-->Two Types (Statement Trigger(table level trigger) / Row Trigger)--> Trigger Condition:(is not allowed for Table Trigger) If the trigger is row trigger it is executed. If trigger condition is True,then only trigger body (Anonymous Block) is processed.*) For DML Trigger PL/SQL provides Three variables to know the Current Event :They are-->INSERTING-->DELETING-->UPDATINGall the above are boolean variables and any one will be true.*)For Row Trigger Server Provides Two variables and they keep current record values. These variables are :--> OLD(%ROWTYPE of table)--> NEW(%ROWTYPE of table)OLD-->keeps value for cuurent record from table.NEW --> keeps value for current record from user.OLD NEW----------------------INSERT x okDELETE ok xUPDATE ok okDML Trigger Syntax:-----------------------------CREATE [OR REPLACE] TRIGGER BEFORE / AFTERINSERT OR DELETE OR UPDATE ON [FOR EACH ROW[WHEN ()]];How To Raise Error for Oracle Server:---------------------------------------------------Syntax:RAISE_APPLICATION_ERROR(,); Note:Error Code must be between -20,000 and -20,999.Q)Check employee table against Data Manipulation as per the -----------------------------------------------------------------------------------following Criteria:------------------------->Insert shoud be allowed before 12'O clock-->Delete should not be allowed before 12'O clock--> Update should not be allowed before 9.00 amafter 5.00 pm.sol):CREATE OR REPLACE TRIGGER Check_EmpBEFORE INSERT OR DELETE OR UPDATE ON empDECLARE vSeconds NUMBER :=(To_Char(sysdate,'hh24')*3600) + (To_Char(sysdate,'mi')*60) + To_Char(sysdate,'ss');BEGIN IF INSERTING=true AND vSeconds < (12*3600) THENRaise_Application_Error (-20001,'Insert Not allowed before 12 Noon'); ELSIF DELETING =true AND vSeconds > (12*3600) THENRaise_Application_Error (-20002,'Delete Not allowed after 12 Noon'); ELSIF UPDATING =true AND vSeconds NOT BETWEEN (9*3600) AND (17*3600) THENRaise_Application_Error (-20003,'No Update before 9 am after 5pm'); END IF;END;/Checking:-------------SQL> Delete emp;Delete emp *ERROR at line 1:ORA-20002: Delete Not allowed after 12 NoonORA-06512: at "SIVA1.CHECK_EMP", line 10ORA-04088: error during execution of trigger 'SIVA1.CHECK_EMP'SQL> Update emp set sal=2000;Update emp set sal=2000 *ERROR at line 1:ORA-20003: No Update before 9 am after 5pmORA-06512: at "SIVA1.CHECK_EMP", line 14ORA-04088: error during execution of trigger 'SIVA1.CHECK_EMP'Note:------If check requires any data from the table then it is row trigger.or validations values are comming from table is is row trigger.or otherwise it is statement trigger.Q2)Protect employee table -for insert of new records for manager and president.-delete should not be allowed for who joiner after year 80-update should not be allowed for salaryCREATE OR REPLACE TRIGGER Check_EmpBEFORE INSERT OR DELETE OR UPDATE ON empFOR EACH ROWBEGIN IF INSERTING=true AND :NEW.job IN('MANAGER','PRESIDENT') THENRaise_Application_Error (-20001,'No Insert For Manager And President'); ELSIF DELETING =true AND To_Char(:OLD.hiredate,'yy') > 80 THENRaise_Application_Error (-20002,'No delete for employee joined after 80'); ELSIF UPDATING =true AND NVL(:OLD.sal,0)NVL(:NEW.sal,0) THENRaise_Application_Error (-20003,'No Update for salary'); END IF;END;/execution:-------------SQL> drop trigger Check_Emp;Trigger dropped.Trigger Created SQL> update emp set sal=4000;update emp set sal=4000 *ERROR at line 1:ORA-20003: No Update for salaryORA-06512: at "SIVA1.CHECK_EMP", line 12ORA-04088: error during execution of trigger 'SIVA1.CHECK_EMP'SQL> CREATE TABLE deptback 2 as 3 SELECT * FROM dept WHERE 1=2;Table created.Note: For deleted records we have to dump in a separate table.For that we need another trigger i.e given below.CREATE OR REPLACE TRIGGER Backup_DeptAFTER DELETE ON deptFOR EACH ROWBEGIN INSERT INTO deptback(deptno,dname,loc) VALUES(:OLD.deptno,:OLD.dname,:old.loc);END;/Note: ------Maximum Number of Triggers on a table:------------------------------------------------------BEFORE INSERT FOR STATEMENTAFTER INSERT FOR STATEMENTBEFORE DELETE FOR STATEMENTAFTER DELETE FOR STATEMENTBEFORE UPDATE FOR STATEMENTAFTER UPDATE FOR STATEMENTBEFORE INSERT FOR ROWLEVELAFTER INSERT FOR ROWLEVELBEFORE DELETE FOR ROWLEVELAFTER DELETE FOR ROWLEVELBEFORE UPDATE FOR ROWLEVELAFTER UPDATE FOR ROWLEVELInstead Of Trigger:==============*)This Trigger is used on view Object to allow data manipulation on the base table(s).*)Within the trigger we have to write DML commands to manipulate the base table(s)*)This trigger always fire BEFORE the event and it is always ROW TRIGGER.Instead Of Trigger Syntax:---------------------------------CREATE [OR REPLACE] TRIGGER INSTEAD OF INSERT OR DELETE OR UPDATEON FOR EACH ROW[WHEN ();Note:------A table can have maximum of three triggers.*)First Create a view:---------------------------CREATE VIEW v1ASSELECT emp.empno,emp.ename,dept.deptno,dept.dnameFROM emp,deptWHERE emp.deptno=dept.deptno;check:DELETE FROM v1;INSERT INTO v1 values(1,'aa',10,'sales');*)Create trigger on view:-------------------------------CREATE OR REPLACE TRIGGER ins1INSTEAD OF INSERT ON v1FOR EACH ROWBEGINIF Check_empno(:NEW.empno) =1 THEN Raise_application_Error (-20001,'Duplicate Empno');END IF;--IF Check_deptno(:NEW.deptno) =1 THEN INSERT INTO dept(deptno,dname) VALUES(:NEW.deptno,:NEW.dname);END IF;--INSERT INTO emp(empno,ename,deptno) VALUES(:NEW.empno,:NEW.ename,:new.deptno);END;*)To Delete records From view:------------------------------------------CREATE OR REPLACE FUNCTION Count_emp_for_deptno(pDeptno IN NUMBER) RETURN NUMBERIS vTemp NUMBER;BEGIN SELECT COUNT(*) INTO vTemp FROM emp WHERE deptno=pDeptno; RETURN (vTemp);END Count_emp_for_deptno;checking:------------SQL> SELECT Count_emp_for_deptno(10) FROM Dual;COUNT_EMP_FOR_DEPTNO(10)------------------------ 4CREATE OR REPLACE TRIGGER del1INSTEAD OF DELETE ON v1FOR EACH ROWBEGINDELETE FROM EMPWHERE empno=:OLD.empno;IF Count_emp_for_deptno(:OLD.deptno)=0THENDELETE FROM deptWHERE deptno=:OLD.deptno;END IF;END;/*)Updating the view using trigger:---------------------------------------------CREATE OR REPLACE TRIGGER upd1INSTEAD OF UPDATE ON v1FOR EACH ROWBEGIN UPDATE emp SETename= :NEW.ename;deptno= :NEW.deptnoWHERE empno= :OLD.empno;--UPDATE dept SETdname= :NEW.dnameWHERE deptno= :=OLD.deptno;END;/