CREATE TRIGGER Background_Process_Report_trit
AFTER INSERT
ON Background_Process_Report
FOR EACH ROW
IF INSERT(PROCESS_NAME)
BEGIN
SET EXECUTION_TIMESTAMP := NEW.TIMESTAMP;
END;
/
process_name -- column in my Background_Process_Report table.but i want to update the each time the process_name is created(by java application), trigger update the time in the EXECUTION_TIMESTAMP table.
but it is throwing the compliation error..
error:
IF INSERT(PROCESS_NAME)
*
ERROR at line 5:
ORA-04079: invalid trigger specification
how to reslove this error
If EXECUTION_TIMESTAMP is a table as you say, then it must have a column you want to update, let's call it TIMESTAMP_COL. The the trigger would be something like:
CREATE TRIGGER Background_Process_Report_trit
AFTER INSERT
ON Background_Process_Report
FOR EACH ROW
WHEN (NEW.PROCESS_NAME IS NOT NULL)
BEGIN
UPDATE EXECUTION_TIMESTAMP
SET TIMESTAMP_COL = NEW.TIMESTAMP
WHERE ???; -- Change ??? to the appropriate condition
END;
/
I have assumed that by "IF INSERT(PROCESS_NAME)" you mean "if a non-null value is inserted into PROCESS_NAME" and created a WHEN clause to match.
Related
I had trouble converting the following command to the oracle command.
I will be glad if you help!
Create Trigger sales_stock_reduction
On SalesMovements
After insert
as
Declare #ProductId int
Declare #Piece int
Select #ProductId=ProductId, #Piece=Piece from inserted
Update Uruns set stock=stock - #Piece where ProductId=#ProductId
In this code, when sales are made, the number of stocks in the product table is reduced through the sales movement table.
I could not write this code in oracle. Wonder how to write in Oracle
You can convert that like this
CREATE OR REPLACE TRIGGER sales_stock_reduction
AFTER INSERT ON SalesMovements
FOR EACH ROW
DECLARE
v_ProductId inserted.ProductId%type;
v_Piece inserted.Piece%type;
BEGIN
BEGIN
SELECT ProductId, Piece
INTO v_ProductId, v_Piece
FROM inserted;
EXCEPTION WHEN NO_DATA_FOUND THEN NULL;
END;
UPDATE Uruns
SET stock=stock - v_Piece
WHERE ProductId=v_ProductId;
END;
/
In Oracle :
OR REPLACE clause is used whenever the trigger needs to be edited
local variables might be defined as the data type of those have
within the table
each individual statements end with a semi-colon
exception handling for NO_DATA_FOUND is added due to presuming at most one
row returns from the current query for the inserted table which doesn't have
a WHERE condition to restrict the result set
I'm trying to create Oracle after insert trigger with the following code:
CREATE OR REPLACE TRIGGER AutoManhour
AFTER INSERT ON TBL_MSTPROJECT
FOR EACH ROW
DECLARE
CURSOR c_Section IS
SELECT IDSECTION AS IDSECTION FROM TBL_MSTSECTIONHR;
v_Section c_Section%ROWTYPE;
BEGIN
OPEN c_Section;
LOOP
FETCH c_Section INTO v_Section;
INSERT INTO TBL_TRXMANHOURS (ID_SECTION,INPUTBY_TRXMANHOURS,INPUTON_TRXMANHOURS,ID_PROJECT)
VALUES (v_Section.IDSECTION,'IT_ROBOT',SYSDATE,:new.IDPROJECT);
END LOOP;
CLOSE c_Section;
END AutoManhour;
/
But it retrieve an error :
ORA-04098: trigger 'DEPEEL.AUTOMANHOUR' is invalid and failed
re-validation
Why does this happen?
I think you must have used the incorrect column/table names or incorrect datatypes are used while inserting data into TBL_TRXMANHOURS. And of course, there is an infinite loop, You should make some condition to make it finite
Oracle will try to recompile invalid objects as they are referred to. Here the trigger is invalid
select * from user_errors where type = 'TRIGGER' and name = 'AUTOMANHOUR'
You can try the above query to find the actual error.
Cheers!!
I am having an issue when creating the auto increment trigger in Oracle 11g. If someone can point out what I am doing wrong, I would really appreciate it. My script for the sequence is this :
CREATE SEQUENCE SPSS_QUOTE_LINE_ITEMS_SEQ start with 1
increment by 1
minvalue 1;
The script for trigger:
CREATE OR REPLACE TRIGGER SPSSQUOTELINEITEMS_ON_INSERT
BEFORE INSERT ON SPSS_QUOTE_LINE_ITEMS
FOR EACH ROW
BEGIN
SELECT SPSS_QUOTE_LINE_ITEMS_SEQ.NEXTVAL
INTO :new.line_num
FROM dual;
END;
The error I am getting:
[Code: 900, SQL State: 42000] ORA-00900: invalid SQL statement
Thanks a lot.
The correct way of doing this to modify your trigger as below:
CREATE OR REPLACE TRIGGER SPSSQUOTELINEITEMS_ON_INSERT
BEFORE INSERT ON SPSS_QUOTE_LINE_ITEMS
FOR EACH ROW
BEGIN
:new.line_num := SPSS_QUOTE_LINE_ITEMS_SEQ.NEXTVAL;
--No need to write any Select Into statement here.
END;
Or if i follow your way then it goes like
CREATE OR REPLACE TRIGGER SPSSQUOTELINEITEMS_ON_INSERT
BEFORE INSERT ON SPSS_QUOTE_LINE_ITEMS
FOR EACH ROW
declare
var number;
BEGIN
SELECT SPSS_QUOTE_LINE_ITEMS_SEQ.NEXTVAL
INTO var
FROM dual;
:new.line_num :=var;
END;
You normally use the terms in a trigger using :old to reference the old value of the column and :new to reference the new value.
I need to insert a 'regist' in Historic data table , when I insert something in 'ALUGUER' the trigger should insert one row in 'HISTORICO':
My Trigger:
create or replace
trigger ADD_HISTORICO
AFTER INSERT
ON ALUGUER
FOR EACH ROW
DECLARE
cod_aluguer_p NUMBER(6,0);
cod_veiculo_p NUMBER(6,0);
BEGIN
SELECT ID_ALUGUER INTO cod_aluguer_p
FROM ALUGUER;
SELECT COD_VEICULO INTO cod_veiculo_p
FROM ALUGUER;
INSERT INTO HISTORICO(ID_ENTRADA,DESCRICAO,DATA_REGISTO,NOVO_VEICULO,NOVO_ALUGUER)
VALUES(SEQ_HISTORICO.nextval,'NOVA DESCRIÇÃO','21/11/2013',cod_veiculo_p,cod_aluguer_p);
END;
Error report:
SQL Error:
ORA-04091: BDDAD_DL1.ALUGUER table is mutating, trigger can
not read or modify
ORA-06512: at "BDDAD_DL1.ADD_HISTORICO", line 6
ORA-04088: error during execution of trigger 'BDDAD_DL1.ADD_HISTORICO'
04091. 00000 -. "Table% s% s is mutating, trigger / function may not see it"
* Cause: A trigger (or a user defined plsql function that is referenced in
this statement) attempted to look at (or modify) a table que was
in the middle of being modified by the statement Which fired it.
* Action: Rewrite the trigger (or function) so it does not read that table.
You are trying to read a record from the table that the trigger has fired on. This is a no-no. So, this code:
SELECT ID_ALUGUER INTO cod_aluguer_p
FROM ALUGUER;
SELECT COD_VEICULO INTO cod_veiculo_p
FROM ALUGUER;
is not allowed. Also, it makes no sense, as there is no WHERE clause on the select, so
all rows would be returned. Moot point, as you can't do this anyway. What you want to do is reference the :NEW values of the triggered row istead. Example:
cod_aluguer_p := :new.ID_ALUGUER ;
cod_veiculo_p L= :NEW.COD_VEICULO;
Further, you don't even needs those local variables, and just use :new directly.
INSERT INTO HISTORICO(ID_ENTRADA,DESCRICAO,DATA_REGISTO,NOVO_VEICULO,NOVO_ALUGUER)
VALUES(SEQ_HISTORICO.nextval,'NOVA DESCRIÇÃO','21/11/2013',:NEW.COD_VEICULO,:new.ID_ALUGUER );
I would recommend to read the Oracle docs on triggers
No SELECT is required, just refer to the :NEW values in the trigger. Also, you can use TRUNC(SYSDATE) to get the current date assuming that's what you intended:
create or replace
trigger ADD_HISTORICO
AFTER INSERT
ON ALUGUER
FOR EACH ROW
BEGIN
INSERT INTO HISTORICO(ID_ENTRADA,DESCRICAO,DATA_REGISTO,
NOVO_VEICULO,NOVO_ALUGUER)
VALUES(SEQ_HISTORICO.nextval,'NOVA DESCRIÇÃO',
TRUNC(SYSDATE),:NEW.COD_VEICULO ,:NEW.ID_ALUGUER );
END;
I want to keep track of changes to one table in another table. What I need is an after update trigger which writes the name of changed column (if multiple columns are changed then there will be multiple inserts to the CHANGES table),the column's old and new values. How do I do that. I tried this but got an error after updating the table.So I'm giving you just the body.
IF :NEW.STAJYEAR!=:OLD.STAJYEAR THEN
INSERT INTO X_STAJ (USERID,EDITDATE,CHANGEDCOLUMN,OLDVALUE,NEWVALUE)
VALUES (:NEW.USERID,SYSDATE,'STAJYEAR',:OLD.STAJYEAR,:NEW.STAJYEAR);
END IF;
the error code is :ORA-04098: trigger 'SYS.TR__TRACK_CHANGES' is invalid and failed re-validation
CREATE OR REPLACE TRIGGER STAJCHANGER.TR_TRACK_CHANGES
AFTER UPDATE
OF STAJYEAR
,STAJMONTH
,STAJDAY
ON STAJCHANGER.STAJ
REFERENCING NEW AS New OLD AS Old
FOR EACH ROW
DECLARE
OLDVALUE NUMBER;
NEWVALUE NUMBER;
COLUMNID NUMBER;
BEGIN
IF :NEW.STAJYEAR!=:OLD.STAJYEAR THEN
INSERT INTO X_STAJ (USERID,EDITDATE,CHANGEDCOLUMN,OLDVALUE,NEWVALUE)
VALUES (:NEW.USERID,SYSDATE,'STAJYEAR',:OLD.STAJYEAR,:NEW.STAJYEAR);
END IF;
IF :NEW.STAJMONTH!=:OLD.STAJMONTH THEN
INSERT INTO X_STAJ (USERID,EDITDATE,CHANGEDCOLUMN,OLDVALUE,NEWVALUE)
VALUES (:NEW.USERID,SYSDATE,'STAJMONTH',:OLD.STAJMONTH,:NEW.STAJMONTH);
END IF;
IF :NEW.STAJDAY!=:OLD.STAJDAY THEN
INSERT INTO X_STAJ (USERID,EDITDATE,CHANGEDCOLUMN,OLDVALUE,NEWVALUE)
VALUES (:NEW.USERID,SYSDATE,'STAJDAY',:OLD.STAJDAY,:NEW.STAJDAY);
END IF;
END TR_TRACK_CHANGES;
/
The error appears to indicates that the trigger owner is SYS, but the creation statement you show explicitly gives the owner as STAJCHANGER.
This makes me wonder, did you accidentally create an (invalid) version of the trigger in SYS at some point, and forget to drop it?
This SQL Plus command will show the error:
SHOW ERROR TRIGGER STAJCHANGER.TR_TRACK_CHANGES