Trigger inserting date as 30/05/9305 22:58 - oracle

In my application, I have a trigger defined to do insertion for a table and a view, all the entries inserted are perfect, except for the date parameter, which gets inserted as '30/05/9305 22:58'. The values that the trigger gets is through the UI, I have checked the entire workflow from the java code from getting the values from the UI to passing it to the trigger, everything looks perfect.
Can anyone help me identify what is going wrong and where?
Date selected was 07/02/2018 which got transformed to 30/05/9305 22:58
Here is a short snap of the trigger that is being used for this:
create or replace trigger "TEST_TRIGGER"
instead of insert on "MY_VIEW"
referencing NEW as n
for each row
BEGIN
insert into DEMO_TABLE
(id, emp_name,report_date,insert_date)
select
demo.table_seq.nextval,:n.id,:n.emp_name,:n.report_date,sysdate from dual;
END;

Your insert statement could be wrong. it has extra column in the select
insert into DEMO_TABLE
(id, emp_name,report_date,insert_date)
select
:n.id,:n.emp_name,:n.report_date,sysdate from dual;

Related

oracle : Trigger not inserting records into table

I have a trigger but it's not inserting the records into target table.
create or replace trigger ins_det_trig1
after insert on Table_a
declare
pragma autonomous_transaction;
---
begin
insert into inf_det
select
a.loc_id,
a.genre_id,
to_char(a.emp_date,'yyyy-mm-dd'),
a.san_seq
from Table_b a ,
Table_a b
where
b.emp_date=a.emp_date
and b.genre_id=a.genre_id
and b.san_seq=a.san_seq;
commit;
exception
when others
Rollback;
end;
pls help me on this
First of all the trigger is invalid, so it won't do anything. You are using a variable named v_err that you don't declare.
Then, you are swallowing all exceptions. If something goes wrong, you fill that variable with the error code and then silently end the trigger. Thus you'll never get informed when the trigger fails.
But the main problem is that you are not using the trigger as you should use triggers in Oracle. The trigger is an after row trigger (AFTER INSERT ... FOR EACH ROW) and hence fires once per row on inserts of table_a rows. The values that got inserted in a new row can be accessed with :new, e.g. :new.business_date.
You, however, ignore these values and select from the table instead. But at the moment of your select the table is mutating. Let's say we write an insert statement that inserts two rows. The trigger fires two times. It is left to chance which row gets inserted first. Oracle sees this and when you are inside the trigger and try to select, it tells us that the content of the table is not deterministic, as the other row may already be in the table or not. We get a mutating table exception.
Having said this: It seems you want an after statement trigger. A trigger that fires after the insert of the rows is complete. For this to happen remove the FOR EACH ROW clause and the related REFERENCING clause, too.
create or replace trigger ins_det_trig1
after insert on Table_a
declare
...
begin
...
end;

How to look at the table whose insertion fired the trigger?

I have a table of bids and everytime a bid is added in an auction I want to create new notifications to every bidder in that auction. As this is for a class of databases I though of doing a trigger to show some skills in oracle pl/sql.
My trigger is like this:
CREATE OR REPLACE TRIGGER create_notifs
AFTER INSERT ON bid
FOR EACH ROW
BEGIN
INSERT INTO notification(id_notif, id_auction, username, time, seen_state)
SELECT notif_id_seq.NEXTVAL, :NEW.id_auction, username, SYSDATE, 0
FROM bid
WHERE bid.id_auction = :NEW.id_leilao;
END;
/
Now this trigger won't work because it's accessing the table that fired it. It is not a problem though because I'm not changing it and it really needs to be after the insertion because I need to see if it passes the constraints. How can I do this?
You can't do a SELECT from the table on which a row trigger is declared or you get the dreaded "mutating table" error, but it doesn't look to me like you need to SELECT anything. Try rewriting your trigger as:
CREATE OR REPLACE TRIGGER create_notifs
AFTER INSERT ON bid
FOR EACH ROW
BEGIN
INSERT INTO notification
(id_notif, id_auction, username, time, seen_state)
VALUES
(notif_id_seq.NEXTVAL, :NEW.id_auction, username, SYSDATE, 0);
END;
Best of luck.

Oracle_Trigger: Auto Update Of a Column Based Upon INSERT/UPDATE

This might appear a simple query for most of you, but I am a beginner in Oracle DB.
A table has been created with below script-
CREATE TABLE PLAN_TABLE
(
PL_ID DECIMAL(10,0) PRIMARY KEY NOT NULL
,PL_NAME VARCHAR2(300) DEFAULT NULL
,UPDATED_TS TIMESTAMP DEFAULT SYSDATE NOT NULL
,DELETE_FLAG DECIMAL(10,0) DEFAULT 0 NOT NULL
);
The requirement is to have SYSDATE for UPDATED_TS for any new record inserted into the table and also in case when the DELETE_FLAG is updated to 1. Can it be done by trigger?
The below trigger was created-
CREATE OR REPLACE TRIGGER PT_BEFORE_INSERT_TR
BEFORE INSERT ON PLAN_TABLE
FOR EACH ROW
BEGIN
SELECT SYSDATE INTO :new.UPDATED_TS FROM DUAL;
dbms_output.put_line('Inserted');
END;
/
Below error was encountered while inserting record into the table-
error: ORA-04091: table I60_SCH04.PLAN_TABLE is mutating, trigger/function may not see it
Can you please help in letting me know that where am I committing the mistake? Is there any better way to achieve the requirement based upon INSERT/UPDATE?
The actual error you get is due to the fact that you try to select from a table that you actually are changing. To prevent the issue there are a couple of methods, but in you case things are really simple.
SYSDATE is a function, that you could call directly inside PL/SQL block (which a trigger actually is) and use the value returned to update the set the column value
CREATE OR REPLACE TRIGGER PT_BEFORE_INSERT_TR
BEFORE INSERT ON PLAN_TABLE
FOR EACH ROW
BEGIN
:new.UPDATED_TS := sysdate;
dbms_output.put_line('Inserted');
END;
/
OK, this covers the insert part.
For updating - once again, many options. One could be - change your trigger to BEFORE INSERT OR UPDATE ON PLAN_TABLE.
In this case whenever you issue update or insert - this trigger is fired for each row and updates the date column accordingly.
And of course you could use particular checks available in triggers, something like
IF INSERTING OR UPDATING('DELETE_FLAG') THEN
...
END IF;
and code in the logic you need.

Mutating error on after insert trigger

The below code is giving a mutating error.
Can any1 pls help in solving this.
CREATE OR REPLACE TRIGGER aso_quote_cuhk_trigger
BEFORE INSERT
ON aso.aso_quote_headers_all
FOR EACH ROW
BEGIN
UPDATE aso.aso_quote_headers_all
SET quote_expiration_date=sysdate+90
where quote_header_id=:new.quote_header_id;
END;
/
In oracle there are two levels of triggers: row level and table level.
Row level triggers are executed for each row. Table level triggers executed per statement, even if a statement changed more then one row.
In a row level trigger, you cannot select/update the table itself that has the trigger: you will get a mutating error.
In this case, there is no need for an UPDATE statement. Just try this:
CREATE OR REPLACE TRIGGER aso_quote_cuhk_trigger
BEFORE INSERT
ON aso.aso_quote_headers_all
FOR EACH ROW
BEGIN
:new.quote_expiration_date=sysdate+90;
END;
/
EDIT Rajesh mentioned it is possible, that before inserting a new row, OP wants to update all other records in the aso_quote_headers_all table.
Well, this is feasible, but it's a little tricky. To do this properly, you will need
A pl/sql package and a variable in the package header that is modified by the triggers. This variable could be a list holding the IDs of newly inserted records. Row level after insert trigger would add a new ID to the list. The content of this package variable will be different for each different session, so let's call this variable session_variable.
Row level after insert trigger, that would add new ID to the session_variable.
Table level after insert trigger that would get IDs from the session_variable, process the ID and then remove it from the session_variable. This trigger could execute necessary selects/updates on the aso_quote_headers_all. After a newly inserted ID is processed, this trigger should make sure it gets removed from the session_variable.
I realise you must have resolved your issue by now. However I am adding this answer below to help anyone else facing similar problem as you and I faced.
I recently encountered mutating table (ORA-04091: table XXXX is mutating, trigger/function may not see it) issue and after searching around realised the Compound Triggers feature available in 11g. If you're on 11g following compound trigger would have solved your issue.
CREATE OR REPLACE TRIGGER aso_quote_cuhk_trigger
FOR INSERT ON aso.aso_quote_headers_all
COMPOUND TRIGGER
row_id rowid;
AFTER EACH ROW IS
BEGIN
row_id := :new.rowid;
END AFTER EACH ROW;
AFTER STATEMENT IS
BEGIN
UPDATE aso.aso_quote_headers_all
SET quote_expiration_date = sysdate+90
WHERE rowid = row_id;
END AFTER STATEMENT;
END aso_quote_cuhk_trigger;
/
A word about how it works. This compound trigger fires 2 events :
First is AFTER EACH ROW where we capture the rowid of newly inserted row
Next is AFTER STATEMENT where we update the table using rowid (captured during first event) in the WHERE clause.
A useful link if you want to read more about Compound Triggers.

Oracle APEX Trigger - Can I affect 'Table A' when I execute a trigger on the insert of 'Table B'?

OK guys, here is my problem. I am trying to create a Trigger in Oracle APEX that will insert the 1st row on table 'APEX_LOGS' with the default values spelled out below when I submit a row for table 'MAIN_APEX'. Here is the trigger I am trying to run:
CREATE OR REPLACE TRIGGER "DEFAULT_LOG_ENTRY" AFTER insert on "MAIN_APEX" for each row
begin
:new.APEX_LOGS.LOG_ENTRY:= 'This log page was established. Actions and communcations are captured from this date and time onward.';
:new.APEX_LOGS.LOG_DATE:= sysdate();
:new.APEX_LOGS.CIRCULATION:= 'External';
:new.APEX_LOGS.MAIN_PK_REF:= &MAIN_APEX.MAIN_PK;
:new.APEX_LOGS.TECHWRITER:= &MAIN_APEX.TECHWRITER;
end;
Thoughts? This topic seems to be incredibly poorly documented. Even the 'Help' section gives no insight into proper formatting. Thanks guys.
You are confusing Apex and database concepts: triggers are part of the database, not of Apex.
The syntax for the trigger would be:
CREATE OR REPLACE TRIGGER "DEFAULT_LOG_ENTRY" AFTER insert on "MAIN_APEX"
for each row
begin
insert into apex_logs (log_entry, log_date, circulation,
main_pk_ref, techwriter)
values ('This log page was established. Actions and communcations are captured from this date and time onward.'
, sysdate
, 'External'
, :new.main_pk
, :new.TECHWRITER);
end;

Resources