Cannot insert NULL into, ERROR during execution of trigger - oracle
I have created a Trigger on table Customers so that every time a record is deleted from table customers this same record is inserted in table Customer_Archives with the current date as Deletion_Date.
I am have to insert a new customer into table Customers and then delete it. The record must be inserted correctly into table Customers_Archive.
Here's script I have so far:
CREATE TABLE Customer_Archives
(
customer_id NUMBER NOT NULL,
customer_first_name VARCHAR2(50),
customer_last_name VARCHAR2(50) NOT NULL,
customer_address VARCHAR2(255) NOT NULL,
customer_city VARCHAR2(50) NOT NULL,
customer_state CHAR(2) NOT NULL,
customer_zip VARCHAR2(20) NOT NULL,
customer_phone VARCHAR2(30) NOT NULL,
customer_fax VARCHAR2(30),
deletion_date DATE,
CONSTRAINT customer_archives_pk
PRIMARY KEY (customer_id)
);
CREATE OR REPLACE TRIGGER Customers_before_insert
BEFORE DELETE ON Customers
FOR EACH ROW
DECLARE
ar_row Customers%rowtype;
BEGIN
INSERT INTO Customer_Archives
VALUES(ar_row.Customer_id,
ar_row.Customer_First_Name,
ar_row.Customer_Last_Name,
ar_row.Customer_Address,
ar_row.Customer_City,
ar_row.Customer_State,
ar_row.Customer_Zip,
ar_row.Customer_Phone,
ar_row.Customer_Fax,
sysdate());
dbms_output.put_line('New row is added to Customers_Archive
Table with Customer_ID:' ||ar_row.Customer_id ||'on date:' || sysdate());
END;
/
SELECT trigger_name, status FROM user_triggers;
INSERT INTO CUSTOMERS
(customer_id, customer_first_name, customer_last_name, customer_address,
customer_city, customer_state, customer_zip, customer_phone, customer_fax)
VALUES (27,'Sofia','Chen','8888 Cowden St.','Philadelphia','PA',
'19149',7654321234',NULL);
DELETE FROM CUSTOMERS
WHERE customer_id = 27;
When I try to delete the customer that I just inserted I get an error:
Error starting at line : 47 in command -
DELETE FROM CUSTOMERS
WHERE customer_id = 27
Error report -
ORA-01400: cannot insert NULL into ("TUG81959"."CUSTOMER_ARCHIVES"."CUSTOMER_ID")
ORA-06512: at "TUG81959.CUSTOMERS_BEFORE_INSERT", line 4
ORA-04088: error during execution of trigger 'TUG81959.CUSTOMERS_BEFORE_INSERT'
In your DELETE trigger you should be using the :OLD values when creating your archive record:
CREATE OR REPLACE TRIGGER CUSTOMERS_BEFORE_INSERT
BEFORE DELETE ON CUSTOMERS
FOR EACH ROW
BEGIN
INSERT INTO CUSTOMER_ARCHIVES
(CUSTOMER_ID,
CUSTOMER_FIRST_NAME,
CUSTOMER_LAST_NAME,
CUSTOMER_ADDRESS,
CUSTOMER_CITY,
CUSTOMER_STATE,
CUSTOMER_ZIP,
CUSTOMER_PHONE,
CUSTOMER_FAX,
DELETION_DATE)
VALUES
(:OLD.CUSTOMER_ID,
:OLD.CUSTOMER_FIRST_NAME,
:OLD.CUSTOMER_LAST_NAME,
:OLD.CUSTOMER_ADDRESS,
:OLD.CUSTOMER_CITY,
:OLD.CUSTOMER_STATE,
:OLD.CUSTOMER_ZIP,
:OLD.CUSTOMER_PHONE,
:OLD.CUSTOMER_FAX,
SYSDATE());
DBMS_OUTPUT.PUT_LINE('New row is added to Customers_Archive
Table with Customer_ID:' ||:OLD.Customer_id ||'on date:' || SYSDATE());
END;
In your original trigger you'd declared a row variable named ar_row but hadn't assigned anything to any of the fields - therefore they were all NULL. When a BEFORE trigger is invoked during a DELETE, the :OLD values have the values prior to the deletion, and the :NEW values are all NULL.
Best of luck.
Related
Error "no data foun" on insert in my trigger ORACLE
I've three tables: create table person( id_per number(1) primary key not null, name_per varchar(15) not null); create table training( id_training number(1) primary key not null, start_training date not null, final_training date not null); create table training_person( id_tp number(3) primary key not null, id_per number(8) not null, id_training number(1) not null); I created a trigger whose function is verify that the user can't to insert in the table training_person if the user have a active training ... but when I want to insert a new register but the person don't have any training registered before, oracle show me the following error: "no data found". This is my trigger: CREATE OR REPLACE TRIGGER VERIFY_TRAINING BEFORE INSERT OR UPDATE ON training_person FOR EACH ROW DECLARE GET_FINAL_TRAINING DATE; GET_START_TRAINING DATE; BEGIN select MAX(final_training) into GET_FINAL_TRAINING from training t join training_person x on t.id_training=x.id_training join person e on e.id_per=x.id_per WHERE e.id_per=:new.id_per; select start_training into GET_START_TRAINING from training t join training_person x on t.id_training=x.id_training where t.id_training=:new.id_training; IF (GET_FINAL_TRAINING > GET_START_TRAINING) THEN RAISE_APPLICATION_ERROR(-20091,'U CANT INSERT TRAINING.'); END IF; EXCEPTION WHEN NO_DATA_FOUND THEN INSERT INTO training_person values(:new.id_tp,:new.id_per,:new.id_training); END; I'm learning Oracle, so I dunno which is the problem. Thanks.
table NISHAN.TBL_ADMIN is mutating, trigger/function may not see it
I have a trigger named tr_admin_user_role that automatically insert values into tbl_user_role table when we perform a insert in another table called tbl_admin. There is no error at compile time but whenever I insert a value into tbl_admin table it shows me an error and error is like This is my tbl_admin table CREATE TABLE tbl_admin( admin_id INTEGER, username VARCHAR2(50) NOT NULL UNIQUE, passwords VARCHAR2(50) NOT NULL, email VARCHAR2(100) UNIQUE, enabled CHAR(1) DEFAULT 1 NOT NULL, created_at DATE DEFAULT SYSDATE NOT NULL, CONSTRAINT pk_admin_id PRIMARY KEY(admin_id) ); tbl_user_role table CREATE TABLE tbl_user_role( user_role_id INTEGER, username VARCHAR2(50) NOT NULL, user_role VARCHAR2(50) DEFAULT 'ROLE_ADMIN' NOT NULL, CONSTRAINT pk_user_role_id PRIMARY KEY(user_role_id) ); Trigger that i have created CREATE OR REPLACE TRIGGER tr_admin_user_role AFTER INSERT ON tbl_admin FOR EACH ROW DECLARE new_username TBL_ADMIN.username%TYPE; BEGIN SELECT username INTO new_username FROM ( SELECT username FROM tbl_admin ORDER BY username DESC ) WHERE ROWNUM = 1; INSERT INTO tbl_user_role(username, user_role) VALUES(new_username, 'ROLE_ADMIN'); END; Insert statement INSERT INTO tbl_admin(username, passwords) VALUES('nisha', 'nisha');
That's not how you fetch the newly inserted / updated / previous value of a column in a Trigger. You should use the :OLD.column_name and :NEW.column_name to refer the old and new column values.Read the documentation to understand more. So, your Trigger could be rewritten as CREATE OR REPLACE TRIGGER tr_admin_user_role AFTER INSERT ON tbl_admin FOR EACH ROW BEGIN INSERT INTO tbl_user_role ( username, user_role ) VALUES ( :NEW.username, 'ROLE_ADMIN' ); END; / I assume you are using another trigger to generate admin_id and user_role_id since they are declared as PRIMARY KEYs and you are not including them in your inserts. Db fiddle demo Here I've used dummy values for those columns.
Trigger to raise raise an application error with a meaningful message if og_id refers to a cancelled Olympic Game
These are the following tables I have created: CREATE TABLE Country ( country_id NUMBER(3) PRIMARY KEY, country_name VARCHAR(3) UNIQUE NOT NULL, CONSTRAINT check_country_id CHECK (country_id > 0) ); CREATE TABLE OG_Type ( og_type_id NUMBER(3) PRIMARY KEY, og_type_title VARCHAR(20) UNIQUE NOT NULL ); CREATE TABLE Olympic_Game ( og_id NUMBER(3) PRIMARY KEY, og_type_id NUMBER(3) NOT NULL, og_year NUMBER(4) NOT NULL, og_website VARCHAR(150), og_cancel VARCHAR(1) NOT NULL, country_id NUMBER(3) NOT NULL, CONSTRAINT check_og_id CHECK (og_id > 0), CONSTRAINT check_og_year_og_type UNIQUE (og_type_id, og_year), CONSTRAINT fk_og_type_id FOREIGN KEY(og_type_id) REFERENCES OG_Type(og_type_id), CONSTRAINT fk_country_id FOREIGN KEY(country_id) REFERENCES Country(country_id) ); CREATE TABLE Sport ( sport_id NUMBER(3) PRIMARY KEY, sport_title VARCHAR(100) UNIQUE NOT NULL, CONSTRAINT check_sport_id CHECK (sport_id > 0) ); CREATE TABLE Event ( event_id NUMBER(6) PRIMARY KEY, sport_id NUMBER(3) NOT NULL, og_id NUMBER(3) NOT NULL, event_title VARCHAR(100) NOT NULL, event_team VARCHAR(1) NOT NULL, no_per_team NUMBER(2) NOT NULL, event_gender VARCHAR(1) NOT NULL, CONSTRAINT check_event_id CHECK (event_id > 0), CONSTRAINT check_event_title_sport_id_og_id_event_team_event_gender UNIQUE (event_title, sport_id, og_id, event_team, event_gender), CONSTRAINT check_event_team CHECK (event_team IN ('Y','N')), CONSTRAINT check_event_team_no_per_team CHECK ((event_team='N' AND no_per_team=1) OR (event_team='Y' AND no_per_team>1)), CONSTRAINT check_event_gender CHECK (event_gender IN ('M','F')), CONSTRAINT fk_sport_id FOREIGN KEY(sport_id) REFERENCES Sport(sport_id), CONSTRAINT fk_og_id FOREIGN KEY(og_id) REFERENCES Olympic_Game(og_id) ); After creating these 4 tables, I have inserted the values for these 4 tables: insert into country(country_id,country_name) values (country_seq.nextval,'FRA'); insert into country(country_id,country_name) values (country_seq.nextval,'GBR'); insert into country(country_id,country_name) values (country_seq.nextval,'GRE'); insert into country(country_id,country_name) values (country_seq.nextval,'USA'); insert into og_type(og_type_id, og_type_title) values(og_type_seq.nextval,'Summer'); insert into og_type(og_type_id, og_type_title) values(og_type_seq.nextval,'Winter'); insert into og_type(og_type_id, og_type_title) values(og_type_seq.nextval,'Special'); insert into og_type(og_type_id, og_type_title) values(og_type_seq.nextval,'Youth'); insert into og_type(og_type_id, og_type_title) values(og_type_seq.nextval,'Senior'); insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,1,1896,null,'N',3); insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,1,1900,null,'N',1); insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,1,1904,null,'N',4); insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,1,1908,'op1908.org','N',2); insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,2,1924,null,'N',1); insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,1,1944,null,'Y',2); insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,3,1944,null,'Y',2); insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,4,1944,null,'Y',2); insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,5,1944,null,'Y',2); insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,1,2012,'https://www.olympic.org/london-2012','N',2); insert into sport(sport_id,sport_title) values(sport_seq.nextval, 'Track and Field'); insert into sport(sport_id,sport_title) values(sport_seq.nextval, 'Tennis'); insert into sport(sport_id,sport_title) values(sport_seq.nextval, 'Speed Skating'); insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,1,'100m','N',1,'M'); insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,2,1,'Double','Y',2,'M'); insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,2,'200m','N',1,'M'); insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,2,2,'Single','N',1,'M'); insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,3,'400m','N',1,'F'); insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,3,'100m','N',1,'F'); insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,4,'1500m','N',1,'F'); insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,3,5,'800m','N',1,'F'); insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,10,'100m','N',1,'M'); insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,10,'100m','N',1,'F'); Now this is the question: Create a trigger called TR_event_on_cancelled_og. This trigger fires before inserting or updating a row in the Event table. The trigger should raise an application error with a meaningful message if og_id refers to a cancelled Olympic Game. Now this is the solution I came up with: CREATE OR REPLACE TRIGGER TR_event_on_cancelled BEFORE INSERT OR UPDATE ON Event FOR EACH ROW BEGIN DECLARE v_og_cancel Olympic_Game.og_cancel%TYPE; BEGIN SELECT og_cancel INTO V_og_cancel FROM Olympic_Game, Event WHERE Olympic_Game.og_id = Event.og_id AND Olympic_Game.og_id = :NEW.og_id; IF (v_og_cancel = 'N') THEN RAISE_APPLICATION_ERROR(-20001, 'This Olympic Game is cancelled already'); END IF; END; END; Trigger TR_EVENT_ON_CANCELLED compiled The trigger is compiled successfully but the problem is when I was trying to test the trigger I got the following error messages: insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,8,'400m','N',1,'F'); Error report - SQL Error: ORA-01403: no data found ORA-06512: at "OG_JC480454.TR_EVENT_ON_CANCELLED", line 5 ORA-04088: error during execution of trigger 'OG_JC480454.TR_EVENT_ON_CANCELLED' 01403. 00000 - "no data found" *Cause: No data was found from the objects. *Action: There was no data from the objects which may be due to end of fetch. insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,2,'400m','N',1,'F'); Error report - SQL Error: ORA-01422: exact fetch returns more than requested number of rows ORA-06512: at "OG_JC480454.TR_EVENT_ON_CANCELLED", line 5 ORA-04088: error during execution of trigger 'OG_JC480454.TR_EVENT_ON_CANCELLED' 01422. 00000 - "exact fetch returns more than requested number of rows" *Cause: The number specified in exact fetch is less than the rows returned. *Action: Rewrite the query or change number of rows requested Where did I exactly go wrong ? ... It would be really helpful if the trigger solution code is provided.
I think your problem is that your trigger code is selecting from EVENT. It doesn't need to do this because the rule applies only to the current event you're inserting or updating. So: SELECT og_cancel INTO V_og_cancel FROM Olympic_Game WHERE Olympic_Game.og_id = :NEW.og_id; Incidentally, the next test looks wrong: IF (v_og_cancel = 'N') Unless you're using Y/N flags in an odd manner this would be testing if the Games have not been cancelled. Surely that should be = 'Y'? " I want to get this error message" I have created an Oracle LiveSQL with your data and my version of the trigger. Find it here (but you will need an OTN account to look at it). When I attempt this INSERT ... insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,2,9,'Double','Y',2,'M'); it fails on ORA-20001: This Olympic Game is cancelled already Quite rightly, because the games where og_id = 9 has og_cancel='Y'. Now you say you're getting ORA-20977: the game was cancelled. That's a user-defined error (in the range -20999 to -20000. So it's some part of your codebase which is hurling it. If you don't know what part it is you will need to dig into your data dictionary. I can't solve that for you. But here's a thought: have you got more than one trigger on the table? Your homework says to create a trigger called TR_event_on_cancelled_og but the code you published does CREATE OR REPLACE TRIGGER TR_event_on_cancelled. Perhaps you previously created a trigger with the other name, and that's what is raising the ORA-20977.
Trigger error: ORA-01403 no data found on insert
My database is that of a hotel reservation system. My trigger will change the availability status of a room before any new reservations are made based on whether the current date falls between the check_in and check_out values of a room. I getting the error no data found when attempting to fire the trigger with an insert statement. I would appreciate any assistance with the problem. Error: SQL Error: ORA-01403: no data found ORA-06512: at "USER.ROOM_STATUS", line 5 ORA-04088 error during execution of trigger 'USER.ROOM_STATUS' - no data found *Cause: No data was found from the objects Trigger: create or replace trigger room_status before insert on reservation for each row declare status_in room.status%type; error1 exception; begin select status into status_in from room where room.room_id = :old.room_id; if sysdate between :old.check_in and :old.check_out then update room set status = 'F' where room_id = :old.room_id; else update room set status = 'T' where room_id = :old.room_id; end if; exception when error1 then raise_application_error(-20100,'Insert Cancelled'); end; Insert Statement: insert into reservation values(reservation_sequence.nextval,to_date('05-03-2017','mm/dd/yyyy'), to_date('05-07-2017','mm/dd/yyyy'), 116, 170); Tables: create table roomType (room_type varchar2(20) constraint roomType_pk primary key, room_rate number(4)); create table room (room_id number(3) constraint room_pk primary key, room_type varchar2(15) constraint room_fk references roomType, status char(1)); create table guest (guest_id varchar2(5) constraint guest_pk primary key, first_name varchar2(20), last_name varchar2(20), email varchar2(30), phone varchar2(10)); create table reservation (reservation_id number(6) constraint reservation_pk primary key, check_in date, check_out date, room_id number(3), guest_id varchar2(5), foreign key (room_id) references room(room_id), foreign key (guest_id) references guest(guest_id));
Oracle throws the NO_DATA_FOUND error when a SELECT statement finds no data. So, looking at your trigger, the obvious explanation might be there is no data in your ROOM table. However, there is a subtle bug in your trigger code: select status into status_in from room where room.room_id = :old.room_id; The :old namespace references the value of the column before the DML is applied. But your DML statement is an insert so the values of :old.room_id is null because there is no prior record. Anything = null is always false so the select fails to find anything. What you need to do is reference the :new value. select status into status_in from room where room.room_id = :new.room_id; :new applies to INSERT and UPDATE statements, :old applies to UPDATE and DELETE statements. Incidentally you have defined an exception error1 but you don't raise it anywhere so that exception handler will never execute.
Triggers in oracle PL/SQL
I am trying to do a trigger that updates a sum of all credits on update of the grade or a insert of a new one. That's my tables create table Department ( Department_ID varchar(4) not null, Name varchar(25) unique, Department_Head_ID varchar(9), College_ID varchar(4), Credits_To_Degree NUMBER(3), constraint pkDepartment primary key (Department_ID)); create table Enrollment ( Student_ID varchar(9) not null, Course_ID varchar(5) not null, Registered_Date date,Grade NUMBER, Status varchar(4),constraint pkEnrollment primary key (Student_ID, Course_ID)); create table Student ( Student_ID varchar(9) not null, First_Name varchar(25), Last_Name varchar(25), Phone char(11), Birth_Date date, Street varchar(100), Zip_Code char(5), Department varchar(4), Credits integer, Eligible char(4), constraint pkStudent primary key (Student_ID),constraint fkDeptId foreign key (Department) references Department(Department_ID)); ALTER TABLE Department ADD FOREIGN KEY (Department_Head_ID) REFERENCES Faculty(Faculty_Id) INITIALLY DEFERRED; ALTER TABLE Department ADD FOREIGN KEY(College_ID) REFERENCES College(College_ID) INITIALLY DEFERRED; the trigger: create or replace TRIGGER Credits after INSERT OR UPDATE ON enrollment REFERENCING NEW AS New OLD AS Old FOR EACH ROW BEGIN UPDATE STUDENT SET CREDITS=(SELECT SUM(c.CREDITS) FROM COURSE c,ENROLLMENT e WHERE c.COURSE_ID = e.COURSE_ID and e.STUDENT_ID = :new.student_id and e.GRADE>= 60 ) WHERE STUDENT.STUDENT_ID=:new.student_id; END; The trigger compiles but when i change value of the grade a get this error UPDATE "FELIX"."ENROLLMENT" SET GRADE = '60' WHERE ROWID = 'AAAGUSAABAAALKJAAF' AND ORA_ROWSCN = '3540016' ORA-20003: An error has occurred while performing credits trigger ORA-06512: at "FELIX.CREDITS", line 5 ORA-04088: error during execution of trigger 'FELIX.CREDITS' One error saving changes to table "FELIX"."ENROLLMENT": Row 6: ORA-20003: An error has occurred while performing credits trigger ORA-06512: at "FELIX.CREDITS", line 5 ORA-04088: error during execution of trigger 'FELIX.CREDITS' line 5 is a FOR EACH ROW command I figure out that the problem is in the :new.student_id. But how could i get the id of the row that the triggers fires upon. Thanks in advance for the help.