I've created a trigger which should fire everey time I update the firstName of a worker in my table:
CREATE OR REPLACE TRIGGER trigger_before_update
BEFORE UPDATE ON t_workers
FOR EACH ROW
BEGIN
insert into t_logtable
values (pk_workerid , sysdate, :old.firstName)
END;
But every time I try to update a row, this is the error I got:
ora-04098 trigger is invalid and failed re-validation
What is wrong with the trigger?
And as you can see, the point would be to insert old values before update, isn't there any oracle solution, for an universial variable/column name? I mean not :old.firstName, but something, that would check any column, and gets any old value, that has been updated. It could be firstName, lastName, salary anything.
try this:
CREATE OR REPLACE TRIGGER trigger_before_update
BEFORE UPDATE ON t_workers
FOR EACH ROW
BEGIN
insert into t_logtable
values (pk_workerid , sysdate, :old.firstName);
END;
add ; after insert code
Related
I trying to write a trigger that will update a column when user insert or updates a row, within the same table.
Example:
insert into user(ID, F_NM, L_NM, EMAIL) values ('1', 'John','Doe','john.doe#market.org.com');
after the insert, i want to call: update user set ORG = 'market' where ID = '1'.
create or replace trigger user_change
after insert or update of EMAIL on USER
for each row
declare
NEW_ORG VARCHAR(10);
BEGIN
CASE
when :NEW.EMAIL like '$#market.org.com' then
NEW_ORG := 'market';
........
END CASE;
UPDATE USER set ORG = NEW_ORG where ID = :NEW.ID
END;
Calculating the new ORG work, but I can't get the update statement to work.
I get 'ORA-04091 table USER is mutating, trigger/funtion may not see it', figure its due to me inserting/updating the same record at same time. Tried adding 'pragma autonomous_transaction' and 'commit' to the trigger, the insert/update of fields works but the ORG does not get updated.
Also tried changing to INSTEAD OF INSERT OR UPDATE OF EMAIL but I keep getting 'ORA-04073 column list not valid for this trigger type'
create or replace trigger user_change
instead of insert or update of EMAIL on USER
while i get 'ORA-25002 cannot create instead of triggers on tables'
create or replace trigger user_change
instead of insert on USER
Why not simply turn the trigger to a before trigger, when you can set the value before it is written? This way, you don't need to run a new DML statement on the table, which avoid the "mutating" error.
create or replace trigger user_change
after insert or update of email on user
for each row
begin
if :new.email like '%#market.org.com' then
:new.org := 'market';
end if;
end;
Looks like your org column can be calculated virtual column. In this case it would be better to create user-defined deterministic pl/sql function that returns correct calculated value and add it to your table, for example:
Alter table t add org varchar2(30) generated always as (f_get_org(email))
Problem Statement:
Create a trigger named trigger_contact_af_update that is triggered whenever the contact table is updated. This trigger will insert the org_name and action into the table contact_log_history after the update of contact details. The action name in the affected log table contact_log_history is After_Update_Contact.
The query I have at the moment is:
CREATE OR REPLACE TRIGGER trigger_contact_af_update
AFTER UPDATE ON contact
FOR EACH ROW
BEGIN
INSERT INTO contact_log_history (org_name, action) Values (:OLD.org_name, 'After_Update_Contact');
END;
But it's not working. Can someone please tell me why?
The table contact_log_history has only two columns.
Using the :OLD variable only works when using a before trigger. I would recommend you to do that in your case.
CREATE OR REPLACE TRIGGER trigger_contact_af_update
BEFORE UPDATE ON contact
FOR EACH ROW
BEGIN
INSERT INTO contact_log_history (org_name, action) Values (:old.org_name, 'After_Update_Contact');
END;
This is my create trigger statement:
CREATE OR REPLACE TRIGGER time_of_inserts
AFTER INSERT ON t_workers
FOR EACH ROW
BEGIN
SELECT pk_workerid, sysdate archivetime
into t_logtable
from t_workers
END;
What I want is, every time when I insert a new row into the t_workers table, I want to insert a new primary key (it could be unique from 1, or copying the inserted data), and the time of the insert into a new table (T_logTable). But I don't know how to insert this into a new table every time. You can see above, what I've came up so far.
"my main problem is inserting into a new table, every time it's triggered"
But you're not inserting, you're selecting. To insert you need to specify the insert keyword :)
Also, you don't want to select from the triggering table: use the :NEW namespace instead.
CREATE OR REPLACE TRIGGER time_of_inserts
AFTER INSERT ON t_workers
FOR EACH ROW
BEGIN
insert into t_logtable
values (:new.pk_workerid , sysdate );
END;
To remove the apparent confusion, SELECT ... INTO populates a local (PL/SQL) variable. It is not the syntax we use for inserting into a table.
I'm using pl\sql developer and I have a report table with a number(38) ID column.
I want to keep track of all updates for this table so I created another table like this:
CREATE TABLE reportUpdate (report_id number(38), updatedate number(32));
And I created a trigger:
CREATE or REPLACE TRIGGER BeforeUpdateReport
BEFORE
UPDATE ON REPORT
FOR EACH ROW
Begin
INSERT INTO reportUpdate
Values(old.ID,sysdate);
END;
And when I run it, I get an error, saying: trigger 'SYSTEM.BEFOREUPDATEREPORT' is invalidand failed re-validation.
Can someone please help
You can use show errors after you see compiled with warnings, or query the user_errors view to see what is wrong later.
One obvious thing is that you haven't prefixed the old reference with a colon:
CREATE or REPLACE TRIGGER BeforeUpdateReport
BEFORE
UPDATE ON REPORT
FOR EACH ROW
Begin
INSERT INTO reportUpdate
Values(:old.ID,sysdate);
END;
/
It's also better to specify the target table fields in the insert statement:
INSERT INTO reportUpdate (report_id, updatedate)
Values(:old.ID,sysdate);
But you have update_date defined in your table creation script as number(32), which doesn't make sense. As #realspirituals pointed out, it should be:
CREATE TABLE reportUpdate (report_id number, updatedate date);
create or replace trigger "STUDENT_PERSONAL_DETAIL_T1"
AFTER insert or update or delete on "STUDENT_PERSONAL_DETAIL"
for each row
begin
insert into fa1 (s_id,name,class,sec)
select reg_no,name,class,sec
from inserted
end;
This is the trigger created using Oracle xe trigger creating interface.
It is created without error but when a insert is called on the table trigger error is shown
trigger failed -ORA-04098 is invalid and failed re-validation.
Guidance and suggestions will help a lot.
You should use:
REFERENCING new AS new
...
BEGIN
INSERT INTO fa1(s_id, name, class, sec)
VALUES (:new.reg_no, :new.name, :new.class, :new.sec);
...
see, this select statement is invalid, because there is no such table as inserted
select reg_no,name,class,sec
from inserted
EDIT if you want to log the inserted values into table fa1, you would do something like, if you had the following columns in table STUDENT_PERSONAL_DETAIL: reg_no,name,class,sec
create or replace trigger "STUDENT_PERSONAL_DETAIL_T1"
AFTER insert on "STUDENT_PERSONAL_DETAIL"
for each row
begin
insert into fa1 (s_id,name,class,sec)
values (:new.reg_no, :new.name, :new.class, :new.sec)
end;
Note the clause AFTER insert on "STUDENT_PERSONAL_DETAIL". I have omitted or update or delete to make sure this will only be triggered for newly inserted records. (because you tried to select from table 'inserted', I have concluded that's what you want to do)