CREATE TABLE table_001(
Day_date date
);
CREATE TABLE table_002(
new_Day_date date
);
CREATE OR REPLACE TRIGGERS trigger
AFTER INSERT ON table_001
FOR EACH ROW
BEGIN
INSERT INTO table_002 VALUES(SYSDATE)
END;
You have a few syntax errors. It's not "TRIGGERS". Also, give a valid trigger name. A semicolon was missing after the insert.
CREATE OR REPLACE TRIGGER trigger_name
AFTER INSERT ON table_001
FOR EACH ROW
BEGIN
INSERT INTO table_002(new_Day_date) VALUES(SYSDATE);
END;
/
CREATE OR REPLACE TRIGGER trigger_name
AFTER INSERT ON table_001
FOR EACH ROW
BEGIN
INSERT INTO table_002 VALUES(SYSDATE);
END;
Related
Oracle 11.1
I have custom logging table where I insert data:
CREATE TABLE log_table
(
message VARCHAR2(255),
created_by VARCHAR2(40) NOT NULL,
created_at DATE NOT NULL,
);
I have a trigger that runs on a specific table which does some checkings. My problem is: when the trigger fails, I want to be able to log some data into the log_table.
Trigger:
CREATE OR REPLACE TRIGGER my_trigger
FOR INSERT OR UPDATE OF column
ON my_table
COMPOUND TRIGGER
BEFORE STATEMENT IS
BEGIN
// code
END BEFORE STATEMENT;
BEFORE EACH ROW IS
BEGIN
IF (/*condition for failing*/) THEN
EXECUTE IMMEDIATE 'INSERT INTO mesaj_ama VALUES (:my_message, :my_user, :my_data)'
USING 'custom error message', SYS.LOGIN_USER, SYSDATE;
RAISE_APPLICATION_ERROR(-20001, 'some error');
END IF;
END BEFORE EACH ROW;
END my_trigger;
/
The following code doesn't work. I tried to use EXECUTE IMMEDIATE maybe to force it, but didn't work. I know that in case of an error, there is automatically a table rollback (which means that the INSERT command is cancelled), but I need a way to do this. Any help?
The concept you're looking for is an Autonomous Trasnaction, eg
CREATE OR REPLACE TRIGGER log_sal
BEFORE UPDATE OF salary ON emp FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO log (
log_id,
up_date,
new_sal,
old_sal
)
VALUES (
:old.employee_id,
SYSDATE,
:new.salary,
:old.salary
);
COMMIT;
END;
Yes, PRAGMA AUTONOMOUS_TRANSACTION seems to be the answer. Here is the working code:
Defined a procedure for logging:
CREATE OR REPLACE PROCEDURE log_error(p_error log_table.message % TYPE) AS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO log_table
VALUES (p_error, SYS.LOGIN_USER, SYSDATE);
COMMIT;
END;
and the trigger which calls the procedure:
CREATE OR REPLACE TRIGGER my_trigger
FOR INSERT OR UPDATE OF column
ON my_table
COMPOUND TRIGGER
BEFORE STATEMENT IS
BEGIN
// code
END BEFORE STATEMENT;
BEFORE EACH ROW IS
BEGIN
IF (/*condition for failing*/) THEN
log_error('custom error message');
RAISE_APPLICATION_ERROR(-20001, 'custom error message');
END IF;
END BEFORE EACH ROW;
END my_trigger;
/
Please Find below Table structure:-
CREATE TABLE emp (
empname text NOT NULL,
salary integer,
salary1 integer
);
Whenever i will insert data into emp table using below query salary1 column should be filled automatically using trigger in postgres ?
insert into emp(empname,salary) values('Tarik','1200');
I have tried below code,But it is not working for me.
CREATE OR REPLACE FUNCTION employee_insert_trigger_fnc()
RETURNS trigger AS
$$
BEGIN
update emp set salary1=NEW.salary where NEW.salary=NEW.salary;
RETURN NEW;
END;
$$
LANGUAGE 'plpgsql';
create TRIGGER employee_insert_trigger
AFTER Insert
ON emp
FOR EACH ROW
EXECUTE PROCEDURE employee_insert_trigger_fnc();
Please help..
Thanks in advance.
Issue resolved after my R&D:-
CREATE OR REPLACE FUNCTION employee_insert_trigger_fnc()
RETURNS trigger AS
$$
BEGIN
NEW.salary1 := NEW.salary;
RETURN NEW;
END;
$$
LANGUAGE 'plpgsql';
create TRIGGER employee_insert_trigger
BEFORE INSERT OR UPDATE
ON ami_master.emp
FOR EACH ROW
EXECUTE PROCEDURE employee_insert_trigger_fnc();
I have created a trigger, that will autoincrement the id, according to the sequence, every time a new record is inserted. Like this:
create sequence test_seq
start with 1
increment by 1
nomaxvalue;
--drop trigger test_trigger;
create or replace trigger test_trigger
before insert on myTable
for each row
begin
select test_seq.nextval into :new.tab_id from dual;
end;
However, I'd like to insert a factorial of the row index instead. How could I achieve this?
Edit:
create or replace trigger test_trigger
after insert on myT
for each row
begin
select fac(test_seq.nextval) into :new.tab_id from dual;
end;
Added fac function which works fine:
create or replace function fac(n in number)
return number
is
v number :=1;
begin
for i in 1..n
loop
v :=v * i;
end loop;
return v;
end;
But I still only see 1,2,3,4 in the table instead of 1,2,6,24...
From Oracle's documentation. You want to use a BEFORE trigger in this instance, an AFTER trigger won't actually change the table's data just from setting it in NEW:
Because the trigger uses the BEFORE keyword, it can access the new
values before they go into the table, and can change the values if
there is an easily-corrected error by assigning to :NEW.column_name.
My guess is that you are still seeing the same old values from the sequence because your BEFORE trigger still exists; the AFTER trigger won't change those values.
So what you want is the following:
CREATE OR REPLACE TRIGGER test_trigger
BEFORE INSERT ON myt
FOR EACH ROW
BEGIN
SELECT FAC(test_seq.nextval) INTO :new.tab_id FROM dual;
END;
/
I think as of Oracle 11g (or maybe it's 10g; can't remember) you can also do the following:
CREATE OR REPLACE TRIGGER test_trigger
BEFORE INSERT ON myt
FOR EACH ROW
BEGIN
:new.tab_id := FAC(test_seq.nextval);
END;
/
Do something like
create function factorial (n integer) return integer as
...
create or replace trigger test_trigger
after insert on mytable
-- don't do this for each row
begin
update mytable set
tab_id = factorial((select count(*) from mytable))
where tab_id is null;
end;
/
I'm trying to execute the following SQL statement on Oracle 11g. I'm not experienced when it comes to Oracle and I'm not sure why this is failing. This query was provided to me by our developer.
I was attempting to execute this through the SQL worksheet in OEM.
CREATE OR REPLACE TRIGGER TBL_ADMINCOMMAND_TRG BEFORE
INSERT OR UPDATE ON tbl_AdminCommands FOR EACH ROW
BEGIN
IF inserting
AND :new.ADMINCOMMANDID IS NULL THEN
SELECT TBL_ADMINCOMMANDS_SEQ.nextval INTO :new.ADMINCOMMANDID FROM DUAL;
END IF;
END;
ALTER TRIGGER TBL_ADMINCOMMAND_TRG ENABLE;
The code you show works for me, but only as two separate commands:
1)
CREATE OR REPLACE TRIGGER TBL_ADMINCOMMAND_TRG BEFORE
INSERT OR UPDATE ON tbl_AdminCommands FOR EACH ROW
BEGIN
IF inserting
AND :new.ADMINCOMMANDID IS NULL THEN
SELECT TBL_ADMINCOMMANDS_SEQ.nextval INTO :new.ADMINCOMMANDID FROM DUAL;
END IF;
END;
2)
ALTER TRIGGER TBL_ADMINCOMMAND_TRG ENABLE;
Try doing them one at a time.
As an aside, this line:
SELECT TBL_ADMINCOMMANDS_SEQ.nextval INTO :new.ADMINCOMMANDID FROM DUAL;
can be simplified to this in 11G:
:new.ADMINCOMMANDID := TBL_ADMINCOMMANDS_SEQ.nextval;
In fact, the whole trigger can be simplified to:
CREATE OR REPLACE TRIGGER TBL_ADMINCOMMAND_TRG
BEFORE INSERT ON tbl_AdminCommands
FOR EACH ROW
WHEN (NEW.ADMINCOMMANDID IS NULL)
BEGIN
:new.ADMINCOMMANDID := TBL_ADMINCOMMANDS_SEQ.nextval;
END;
If you are using SQL*Plus, you should end your PL/SQL commands with a single forward slash on a line by itself:
CREATE OR REPLACE TRIGGER TBL_ADMINCOMMAND_TRG
BEFORE INSERT OR UPDATE ON tbl_AdminCommands
FOR EACH ROW
BEGIN
IF inserting AND :new.ADMINCOMMANDID IS NULL
THEN
SELECT TBL_ADMINCOMMANDS_SEQ.nextval
INTO :new.ADMINCOMMANDID
FROM DUAL;
END IF;
END;
/
ALTER TRIGGER TBL_ADMINCOMMAND_TRG ENABLE;
Also note that if your trigger uses IF inserting you could do only a trigger BEFORE INSERT.
I created a trigger as below:
CREATE OR REPLACE TRIGGER trigger_test
AFTER INSERT ON trigger_1
FOR EACH ROW
DECLARE
t_identifier VARCHAR2(10);
t_name VARCHAR2(20);
BEGIN
t_identifier := (:NEW.IDENTIFIER);
t_name := (:NEW.NAME);
INSERT INTO trigger_2(IDENTIFIER,NAME)VALUES(t_identifier,t_name);
COMMIT;
END;
I am trying to insert a row in trigger_1
INSERT INTO trigger_1(IDENTIFIER,NAME)
VALUES('1234567','Vijay');
It is giving me the errors:
ORA-04092: cannot COMMIT in a trigger
ORA-06512: at "LVSDBO46.TRIGGER_TEST", line 8
ORA-04088: error during execution of trigger 'LVSDBO46.TRIGGER_TEST'
Could nybody please help?
Just remove
COMMIT;
from the trigger code. Trigger execute in an ongoing transaction, so you cannot do a separate commit. When the transaction is commited, your insert in trigger_2 will also be commited.
Might I suggest shortening it a bit.
CREATE OR REPLACE TRIGGER trigger_test
AFTER INSERT ON trigger_1
FOR EACH ROW
BEGIN
INSERT INTO trigger_2 (IDENTIFIER,NAME) VALUES (:NEW.IDENTIFIER,:NEW.NAME);
END;
In case you really really need to commit (chances are you don't have to, but just in case...) you can create a procedure with the AUTONOMOUS_TRANSACTION PRAGMA.