I want to create a trigger that will store the timing of when a new row is inserted into a my employee's table.
so far this is my code, but i keep getting errors.
trigger:
CREATE OR REPLACE TRIGGER insert_new_employee
AFTER INSERT ON employees
BEGIN
insert into audit_cheker (date_create) values (sysdate());
END;
my table to store the timing for when inserting a new element:
create table audit_cheker(
date_create date
)
the error I've received is
00000 - "trigger '%s.%s' is invalid and failed re-validation"
Cause:
A trigger was attempted to be retrieved for execution and was
found to be invalid. This also means that compilation/authorization
failed for the trigger.
Action:
Options are to resolve the compilation/authorization errors,
disable the trigger, or drop the trigger.
Based on information you posted so far, it should work. Here's a test case:
SQL> create table audit_cheker
2 (date_create date);
Table created.
SQL> create table employees as select empno, ename, deptno From emp;
Table created.
Trigger:
SQL> CREATE OR REPLACE TRIGGER insert_new_employee
2 AFTER INSERT ON employees
3 BEGIN
4 insert into audit_cheker (date_create) values (sysdate());
5 END;
6 /
Trigger created.
No problems so far. Let's test it:
SQL> insert into employees (empno, ename, deptno) values (1, 'LF', 10);
1 row created.
SQL> select * from employees where empno = 1;
EMPNO ENAME DEPTNO
---------- ---------- ----------
1 LF 10
SQL> select * From audit_cheker;
DATE_CREATE
----------------
2020-04-24 07:18
As you can see, it works.
If trigger is invalid, try to recompile it:
SQL> alter trigger insert_new_employee compile;
Trigger altered.
If it still doesn't help, please, edit your initial message (the question you posted) and copy/paste your SQL*Plus session so that we could see what you did and how Oracle responded.
Related
How can I get the table name inside trigger function?
Something similar to TG_TABLE_NAME in Postgres, like this
Oracle 10g or above.
That's user_triggers view (if I understood the question correctly).
SQL> create table test (id number, name varchar2(20));
Table created.
SQL> create or replace trigger trg_test
2 before insert on test
3 for each row
4 begin
5 null;
6 end;
7 /
Trigger created.
SQL> select trigger_name, table_name from user_triggers;
TRIGGER_NAME TABLE_NAME
------------------------------ ------------------------------
TRG_TEST TEST --> this is the one I've just created
TRG_AIUD_EMP EMPLOYEES
SQL>
I have a table EMP in my apex oracle database that contains an attribute of salary named sal. I have another table EMPSAL that has 3 attributes named averageSal, minSal, maxSal which are to be updated using triggers whenever any DML operation is performed on the EMP table's sal column. Here is the trigger used for upgrading:
create or replace trigger empsal_update_trigger
AFTER update on emp
for each row
declare
avgSal2 emp.sal%type;
minSal2 emp.sal%type;
maxSal2 emp.sal%type;
begin
select avg(sal), min(sal), max(sal) into avgSal2, minSal2, maxSal2 from emp;
delete from empsal;
insert into empsal values(avgSal2, minSal2, maxSal2);
end;
The insert and delete triggers work fine, but the update one given above gives error whenever A record is updated in EMPSAL. I have tried using before keyword instead of after but it's no use.
You don't need a row level trigger for this case, but use a statement level one. Even no need to use local variable definition through use of INSERT INTO ... SELECT... statement.
So, just remove FOR EACH ROW such as
CREATE OR REPLACE TRIGGER empsal_update_trigger AFTER UPDATE ON emp
BEGIN
DELETE empsal;
INSERT INTO empsal
SELECT AVG(sal), MIN(sal), MAX(sal)
FROM emp;
END;
/
I am trying to create a trigger in oracle that ensures that the value of ExpDate from the table ExpIt is less than or equal to the ERSubDate from the ExpReport on INSERT and UPDATE statements that change the ExpDate in the ExpIt table.
When ran in the command prompt, the following comes up
warning: Trigger created with compilation errors.
Here is what I have tried so far, where am I going wrong?
Thank you in advance.
CREATE OR REPLACE TRIGGER Expense_Date
BEFORE INSERT OR UPDATE OF ExpDate
ON ExpIt
FOR EACH ROW
DECLARE
anExpDate ExpIts.ExpDate%TYPE;
anERSubDate ExpReport.ERSubDate%TYPE;
DateError EXCEPTION;
ExMessage VARCHAR(200);
BEGIN
SELECT ExpDate, ERSubDate
INTO anExpDate, anERSubDate
FROM ExpIt, ExpReport
WHERE ExpIt.ExpDate = :NEW.ExpDate;
IF anExpDate <= anERSubDate THEN
RAISE DateError;
END IF;
EXCEPTION
WHEN DateError THEN
ExMessage := ExMessage || 'Expense Date is Incorrect as it is after the Expense Report Submition date' ||
to_date(anExpDate);
raise_application_error(-20001, ExMessage);
END;
/
Before you go too far down this track - be aware that you generally cannot access the table you are triggering on from within the trigger itself.
In your case, your trigger is on EXPIT and you want to query EXPIT. That won't work.
Here's a trivial example of that:
SQL> create table t (x int );
Table created.
SQL> insert into t values (1);
1 row created.
SQL> commit;
Commit complete.
SQL>
SQL> create or replace
2 trigger TRG
3 before insert on T
4 for each row
5 declare
6 blah int;
7 begin
8 select count(*) into blah from t;
9 end;
10 /
Trigger created.
SQL>
SQL> insert into t values (2);
1 row created.
It looks fine, but in reality, there are plenty of cases where it will NOT work
SQL> insert into t
2 select rownum from dual
3 connect by level <= 5;
insert into t
*
ERROR at line 1:
ORA-04091: table MCDONAC.T is mutating, trigger/function may not see it
ORA-06512: at "MCDONAC.TRG", line 4
ORA-04088: error during execution of trigger 'MCDONAC.TRG'
This is a big topic, and more details on the issue and how to work around it are here
https://asktom.oracle.com/pls/apex/asktom.search?file=MutatingTable.html#presentation-downloads-reg
Ca you please suggest if I can create the db view using triggers in Oracle?
E.g. I have a trigger trig_cust and I want to create a view:
Create or replace view vw_cust as select * from trig_cust;
P.S. need to use this view in loop
Triggers are an even of action. You cannot create a view out of trigger.
Triggers are used to perform an action insert/ update / delete based on particular event where as views are used to select set of columns with the combination of multiple tables.
View is used to display a combined set of required columns from various tables in order to reduce the querying effort. View is majorly used for reporting purpose. You can have a trigger on the view, but not view out of trigger.
suggest if I can create the db view using triggers in Oracle?
Can you? Yes, you can. Should you? No, you shouldn't.
Anyway, just for amusement, here you go: table and its trigger which is supposed to create a view once a new row is inserted into a table. Pay attention to pragma; without it, it wouldn't work as you can't commit in a trigger. True, there's no explicit commit there, but create view is a DDL and it implicitly commits.
SQL> create table test (empno number, ename varchar2(20));
Table created.
SQL> create or replace trigger trg_ai_test
2 after insert on test
3 for each row
4 declare
5 pragma autonomous_transaction;
6 begin
7 execute immediate 'create or replace view v_test_' || to_char(:new.empno) ||
8 ' as select * from test where empno = ' || :new.empno;
9 end;
10 /
Trigger created.
Testing:
SQL> insert into test (empno, ename) values (1, 'Little');
1 row created.
SQL> insert into test (empno, ename) values (2, 'Foot');
1 row created.
SQL> select * from v_test_1;
EMPNO ENAME
---------- --------------------
1 Little
SQL> select * from v_test_2;
EMPNO ENAME
---------- --------------------
2 Foot
SQL>
I have emp table in schema1 and emp_fianl in schema2.
emp
empid ename estatus
1 abc incomplete
2 xyz complete
3 ifg incomplete
4 mno incomplete
Emp_final
empid ename estatus
2 xyz complete
I have to create a trigger to insert data in Schema2 emp_final table when the estatus in schema1 emp table changes to complete.
I have written below trigger for the same:
Create or replace trigger tri_emp_final
After update on emp
BEGIN
IF :new.estatus='complete' then
Insert into emp_final
(select :old.empid,:old.ename,:new.estatus from schem1.emp);
END IF;
END;
/
I am getting mutating error message for the above code. When I am trying to update the status in emp table. I am a java developer and do not have much experience in Oracle, SQL. Can anyone please help?
First thing: we you want to use :old and :new, your trigger MUST be FOR EACH ROW. So you need to change : before update on emp for each row.
Second: like Goran Stefanović wrote, you don't make that select to insert, just use the :old values.
Use
Create or replace trigger tri_emp_final
After update on emp for each row
BEGIN
IF :new.estatus='complete' then
Insert into emp_final ( empid , ename , estatus)
Values
(:old.empid,:old.ename,:new.estatus );
END IF;
END;
/
You can find a working demo here