can someone help with updating a trigger? I know I am supposed to use the alter clause but after that I am stuck. I would like to alter this trigger:
CREATE OR REPLACE TRIGGER "CR_SURGERY_AUDIT"
before insert or delete or update on CR_SURGERY
for each row
declare
V_user varchar2 (30);
V_date varchar2 (30);
begin
select user, to_char(sysdate, 'dd/mon/yyyy hh24:mi:SS') INTO v_user, v_date
from dual;
IF inserting THEN
insert into CR_SURGERY_AUDIT (new_name, old_name, user_name, entry_date, operation)
VALUES (:NEW.CR_SURGERY, NULL, v_user, v_date, 'insert');
ELSIF DELETING THEN
insert into CR_SURGERY_AUDIT (new_name, old_name, user_name, entry_date, operation)
VALUES (null, :OLD.CR_SURGERY, v_user, v_date, 'delete');
ELSIF UPDATING THEN
insert into CR_SURGERY_AUDIT (new_name, old_name, user_name, entry_date, operation)
VALUES (:NEW.CR_SURGERY, :OLD.CR_SURGERY, v_user, v_date, 'Update');
END IF;
END;
I know it's simple but I cannot find a way to compose it. I want to add FK_SOCRD_ID so it updates to:
select user, to_char(sysdate, 'dd/mon/yyyy') INTO v_user, v_date from dual;
IF inserting THEN
insert into CR_SURGERY_AUDIT (new_name, old_name, user_name, entry_date,
operation, FK_SOCRD_ID)
VALUES (:NEW.CR_SURGERY, NULL, v_user, v_date, 'insert');
There is no syntax to modify triggers, you just modify your create or replace trigger code and rerun it.
With your proposed change, I make it something like this:
create or replace trigger cr_surgery_audit
before insert or delete or update on cr_surgery
for each row
declare
k_user constant cr_surgery_audit.user_name%type := sys_context('userenv','os_user');
k_date constant cr_surgery_audit.entry_date%type := sysdate;
begin
if inserting then
insert into cr_surgery_audit (new_name, old_name, user_name, entry_date, operation, fk_socrd_id)
values (:new.cr_surgery, null, k_user, k_date, 'insert', 12345);
elsif deleting then
insert into cr_surgery_audit (new_name, old_name, user_name, entry_date, operation)
values (null, :old.cr_surgery, k_user, k_date, 'delete');
elsif updating then
insert into cr_surgery_audit (new_name, old_name, user_name, entry_date, operation)
values (:new.cr_surgery, :old.cr_surgery, k_user, k_date, 'update');
end if;
end;
I've assumed cr_surgery_audit.entry_date is actually a date and not a varchar2.
You need a value to populate fk_socrd_id with, so I put in 123456 as a dummy value.
Related
It give me error example image at below:
Trigger code:
CREATE OR REPLACE TRIGGER InsertNewStaffs
BEFORE INSERT ON Staffs
FOR EACH ROW
ENABLE
DECLARE
v_user varchar(255);
v_date varchar(255);
v_Staffs_ID Staffs.Staffs_ID%TYPE;
v_Staffs_Name Staffs.Staffs_Name%TYPE;
v_Staffs_Contact_Number Staffs.Staffs_Contact_Number%TYPE;
v_Staffs_Email Staffs.Staffs_Email%TYPE;
v_Orders_ID Staffs.Orders_ID%TYPE;
v_count INTEGER;
BEGIN
SELECT count(*) INTO v_count FROM Staffs
WHERE Staffs_ID = v_Staffs_ID OR
Staffs_Name = v_Staffs_Name OR
Staffs_Contact_Number = v_Staffs_Contact_Number OR
Staffs_Email = v_Staffs_Email;
IF v_count > 0 THEN
RAISE_APPLICATION_ERROR(-20000, 'Oops, some data is already exists. Please try again...');
DBMS_OUTPUT.PUT_LINE('Oops, some data is already exists. Please try again...');
SELECT user, TO_CHAR(sysdate, 'DD/MON/YYYY HH24:MI:SS') INTO v_user, v_date FROM dual;
ELSE
INSERT INTO Staffs(Staffs_ID, Staffs_Name, Staffs_Contact_Number, Staffs_Email, Orders_ID)
VALUES(v_Staffs_ID, v_Staffs_Name, v_Staffs_Contact_Number, v_Staffs_Email, v_Orders_ID);
DBMS_OUTPUT.PUT_LINE('One Row Inserted By ' || v_user || CHR(10));
DBMS_OUTPUT.PUT_LINE('Inserted data at ' || v_date);
INSERT INTO monitorInsertStaffs(user_name, entry_date, operation)
VALUES(v_user, v_date, 'Insert');
END IF;
END;
/
My Table:
CREATE TABLE Staffs(
Staffs_ID char(20) NOT NULL,
Staffs_Name varchar(255) NOT NULL,
Staffs_Contact_Number varchar(50) NOT NULL,
Staffs_Email varchar(255) NOT NULL,
Orders_ID char(20),
PRIMARY KEY (Staffs_ID),
FOREIGN KEY (Orders_ID) REFERENCES Orders(Orders_ID)
);
CREATE TABLE Orders(
Orders_ID char(20) NOT NULL,
Order_Date DATE NOT NULL,
Order_Status varchar(255) NOT NULL,
Order_Quantity int NOT NULL,
Order_TotalAmount NUMERIC(10,2) NOT NULL,
Order_TotalPrice NUMERIC(10,2) NOT NULL,
PRIMARY KEY (Orders_ID),
Pets_Products_ID char(20),
CustomerID char(20),
FOREIGN KEY (Pets_Products_ID) REFERENCES Pets_Products(Pets_Products_ID),
FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID)
);
I try to insert data and if the data has existed it will show RAISE_APPLICATION_ERROR(-20000, 'Oops, some data is already exists. Please try again...'); but it didn't show the message and also cannot insert data when no exists the data.
I don't know where is error code that I find.
The whole concept is just wrong.
you've based trigger on a table into which you're just inserting a row (staffs)
then you're selecting from the same table (it'll raise the mutating table error if you try to insert more than a single row)
the where clause uses local variables that have no values
insert into staffs cause the same trigger to fire over and over again, until Oracle concludes that that's enough and raises the error
Don't use a trigger. Use UNIQUE constraints:
CREATE TABLE Staffs(
Staffs_ID char(20) NOT NULL,
Staffs_Name varchar(255) NOT NULL,
Staffs_Contact_Number varchar(50) NOT NULL,
Staffs_Email varchar(255) NOT NULL,
Orders_ID char(20),
PRIMARY KEY (Staffs_ID),
UNIQUE (Staffs_Name),
UNIQUE (Staffs_Contact_Number),
UNIQUE (Staffs_Email),
FOREIGN KEY (Orders_ID) REFERENCES Orders(Orders_ID)
);
(However, you should also consider whether your business requirements make sense or if you can have multiple staff members called Jane Smith or if you can have two staff members who share an office with the same telephone number?)
If you want to use a logging table then use an autonomous transaction to just insert into that table:
CREATE OR REPLACE TRIGGER InsertNewStaffs
BEFORE INSERT ON Staffs
FOR EACH ROW
ENABLE
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO monitorInsertStaffs(
user_name, entry_date, operation
) VALUES(
:NEW.Staffs_ID, SYSDATE, 'Insert'
);
COMMIT;
END;
/
db<>fiddle here
I have this set of data. I want to develop a trigger which fires when rows with ICICUT = IB are updated. So far it's proving a challenge because of error "PLS-00201: identifier 'OLD.ICICUT' must be declared". What am I missing?
ICICUT ICICU ICAME
IB 11368 65625
V 711340 63808
V 711313 24812
IB 711265 60238
O 711322 21570
RB 711370 348590
my trigger....
CREATE OR REPLACE TRIGGER EOGONY.F0011_audit
BEFORE UPDATE
ON INVOICES
REFERENCING NEW AS New OLD AS Old
FOR EACH ROW
WHEN (OLD.ICICUT = 'IB')
ENABLE
DECLARE
v_date varchar2(30);
BEGIN
SELECT TO_CHAR(sysdate, 'DD/MON/YYYY HH24:MI:SS') INTO v_date from dual;
INSERT INTO AUDIT_HISTORY_F0011 (ICICUT, ICICU, ICUSER, ICDICJ, OLD_ICAME, NEW_ICAME, ENTRY_DATE, OPERATION)
VALUES (:OLD.ICICUT, :OLD.ICICU , :NEW.ICUSER, :OLD.ICDICJ, :OLD.ICAME, :NEW.ICAME, v_date, 'Updating');
END;
I managed to compile code without errors after applying these changes...
CREATE OR REPLACE TRIGGER EOGONY.F0011_audit
BEFORE UPDATE
ON INVOICES
REFERENCING NEW AS New OLD AS Old
FOR EACH ROW
ENABLE
DECLARE
v_date varchar2(30);
BEGIN
IF ( :OLD.ICICUT = 'IB' ) THEN
SELECT TO_CHAR(sysdate, 'DD/MON/YYYY HH24:MI:SS') INTO v_date from dual;
INSERT INTO AUDIT_HISTORY_F0011 (ICICUT, ICICU, ICUSER, ICDICJ, OLD_ICAME, NEW_ICAME, ENTRY_DATE, OPERATION)
VALUES (:OLD.ICICUT, :OLD.ICICU , :NEW.ICUSER, :OLD.ICDICJ, :OLD.ICAME, :NEW.ICAME, v_date, 'Updating');
END IF;
END;
/
I am not able to find the answer using search. How can I get the value for column FK_SOCRD_ID from table CR_MDT to insert into table CR_MDT_AUDIT using this trigger I have created:
CREATE OR REPLACE TRIGGER "CR_MDT_AUDIT"
before insert or delete or update on CR_MDT
for each row
declare
V_user varchar2 (30);
V_date varchar2 (30);
begin
IF inserting THEN
insert into CR_MDT_AUDIT (new_value, OLD_VALUE, user_name, entry_date, operation, FK_SOCRD_ID)
VALUES (:NEW.CR_MDT_ABSTRACTOR_DT, NULL, v_user, v_date, 'Abstraction Completed');
ELSIF DELETING THEN
insert into CR_MDT_AUDIT (new_value, OLD_VALUE, user_name, entry_date, operation, FK_SOCRD_ID)
VALUES (null, :OLD.CR_MDT_ABSTRACTOR_DT, v_user, v_date, 'delete');
ELSIF UPDATING THEN
insert into CR_MDT_AUDIT (new_value, OLD_VALUE, user_name, entry_date, operation, FK_SOCRD_ID)
VALUES (:NEW.CR_MDT_ABSTRACTOR_DT, :OLD.CR_MDT_ABSTRACTOR_DT, v_user, v_date, 'Update');
END IF;
END;
I don't know what clause or wording to use so that the FK_SOCRD_ID value from CR_MDT adds to CR_MDT_AUDIT table. Basically, I am trying to have a way to identify where the changes are being made.
Is it possible to have multiple tables in one TRIGGER? Let say I have Employee, Skill and Customer Tables and I have Eventlogs table to capture the audit. I tried to add Skill_T but I got ORA-04079 error. Any correction? Thank you!
NOTE: I am using Oracle SQL Developer Oracle11gEE
CREATE OR REPLACE TRIGGER AUDIT_REC
AFTER INSERT OR DELETE OR UPDATE ON EMPLOYEE_T, SKILL_T
FOR EACH ROW
DECLARE
V_LOGID NUMBER;
V_USER VARCHAR(30);
V_DATE VARCHAR(30);
BEGIN
SELECT EVENTLOG_ID_SEQ.NEXTVAL, USER, SYSDATE INTO V_LOGID, V_USER, V_DATE FROM DUAL;
IF INSERTING THEN
INSERT INTO EVENTLOGS(Eventlog_id, User_name, Date_done, Action_done)
VALUES (V_LOGID, V_USER, V_DATE, 'INSERT');
ELSIF DELETING THEN
INSERT INTO EVENTLOGS(Eventlog_id, User_name, Date_done, Action_done)
VALUES (V_LOGID, V_USER, V_DATE, 'DELETE');
ELSIF UPDATING THEN
INSERT INTO EVENTLOGS(Eventlog_id, User_name, Date_done, Action_done)
VALUES (V_LOGID, V_USER, V_DATE, 'UPDATE');
END IF;
END;
/
A DML Trigger is associated (tied to) with only ONE table. It executes when DML is submitted against that table only.
See http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/triggers.htm#LNPLS99888
DROP TRIGGER EPI_BOREHOLE_INI;
CREATE OR REPLACE TRIGGER EPI_BOREHOLE_INI
INSTEAD of Insert ON EPI_BOREHOLE for each row
DECLARE
V_ID number(10);
V_USER varchar2(100);
BEGIN
if (:new.UBHI is null or :new.NAME is null or) then
Raise_Application_Error(-20101, 'Insert failed. The key values of BOREHOLE(UBHI, NAME) cannot be null');
end if;
begin
select BOREHOLE_ID.nextval into V_ID from dual;
SELECT USER INTO V_USER FROM DUAL;
INSERT INTO EPI_BOREHOLE (ID, UBHI, NAME, INSERT_DATE ,INSERT_NAME, UPDATE_DATE,UPDATE_NAME) VALUES (V_ID,:NEW.UBHI, :NEW.NAME, SYSDATE, V_USER, SYSDATE, V_USER);
end;
END;
I see little error in your code: Please see below:
if (:new.UBHI is null or :new.NAME is null or) then <-- An additional OR written.
remove it and try or put one more condition.
I dont see any issue with the code.
Try doing
SET DEFINE OFF