Triggers in oracle PL/SQL - oracle

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.

Related

Cannot insert NULL into, ERROR during execution of trigger

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.

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.

Coding a COUNT in a VIEW in Oracle

I am stuck in a programming problem in Oracle, that I am trying to solve. I am suppose to create a View that will give me the Number of unreserved/Available seats on FBN001 ON 27TH October 2016
This is the Flight Table:
CREATE TABLE Flight(
Flight_ID VARCHAR(25),
Route_ID VARCHAR(25),
Airplane_ID VARCHAR(10),
Departure_Time DATE,
Arrival_Time DATE,
CONSTRAINT FlightIDPK PRIMARY KEY(Flight_ID),
CONSTRAINT RouteIDFK FOREIGN KEY(Route_ID) REFERENCES Route(Route_ID),
CONSTRAINT AirplaneIDFK FOREIGN KEY(Airplane_ID) REFERENCES Airplane(Airplane_ID));
This is the Airplane Table:
CREATE TABLE Airplane(
Airplane_ID VARCHAR(10),
Capacity NUMBER(5) NOT NULL,
Model VARCHAR(15) NOT NULL,
CONSTRAINT AirplaneIDPK PRIMARY KEY(Airplane_ID));
This is the Booking Table:
CREATE TABLE Booking(
Booking_ID NUMBER(10),
Flight_ID VARCHAR(25),
Customer_ID NUMBER(10),
Payment_Method VARCHAR(10) NOT NULL,
CreditCard_Details NUMBER(18),
CONSTRAINT BookingIDPK PRIMARY KEY(Booking_ID),
CONSTRAINT FlightIDFK FOREIGN KEY(Flight_ID) REFERENCES Flight(Flight_ID),
CONSTRAINT CustomerIDFK FOREIGN KEY(Customer_ID) REFERENCES Customer(Customer_ID));
I thought i would use the COUNT function to count the Bookings
CREATE VIEW ViewB AS(
SELECT Flight.Route_ID, Flight.Departure_Time, Airplane.Capacity, COUNT(Flight_ID) AS NumberOfBooking
FROM Flight, Airplane, Booking
WHERE Flight.Airplane_ID = Airplane.Airplane_ID
AND Flight.Route_ID = 'FBN001'
GROUP BY Flight.Route_ID, Airplane.Capacity);
But that did not work,
It is giving me the Error
Error report -
SQL Error: ORA-00918: column ambiguously defined
00000 - "column ambiguously defined"
*Cause:
*Action:
What could be the solution?
Thank you
You didn't add a statement to properly join the booking table:
CREATE VIEW ViewB AS(
SELECT Flight.Route_ID, Flight.Departure_Time, Airplane.Capacity, COUNT(Flight_ID) AS NumberOfBooking
FROM Flight, Airplane, Booking
WHERE Flight.Airplane_ID = Airplane.Airplane_ID
AND Flight.Flight_ID=Booking.Flight_ID
AND Flight.Route_ID = 'FBN001'
GROUP BY Flight.Route_ID, Airplane.Capacity);

ORA-02291: integrity constraint violated - parent key not found

SO here is my Database:
CREATE TABLE courses (
ccode VARCHAR2(10) CONSTRAINT courses_PK PRIMARY KEY,
cname VARCHAR2(50),
coursefee NUMBER(6)
);
CREATE TABLE faculty (
fcode VARCHAR2(5) CONSTRAINT faculty_PK PRIMARY KEY,
name VARCHAR2(50)
);
CREATE TABLE batches (
bcode varchar2(5) CONSTRAINT batches_PK PRIMARY KEY,
ccode varchar2(5) CONSTRAINT batches_ccode_FK REFERENCES COURSES(ccode),
fcode varchar2(5) CONSTRAINT batches_fcode_FK REFERENCES FACULTY(fcode),
stdate date CONSTRAINT batches_stdate_nn not null,
enddate date,
timing number(1) CONSTRAINT batches_timing_chk check( timing in (1,2,3) ),
CONSTRAINT batches_date_chk check ( stdate <= enddate)
);
CREATE TABLE students (
rollno number(5) CONSTRAINT students_PK PRIMARY KEY,
bcode varchar2(5) CONSTRAINT students_bcode_FK REFERENCES batches(bcode),
name varchar2(30),
gender char(1) CONSTRAINT students_gender_chk check( upper(gender) in ('M','F')),
dj date,
phone varchar2(10),
email varchar2(30)
);
Insert Table:
INSERT INTO batches VALUES('A0001','A0016','A0031','08-05-13','08-06-17',1);
INSERT INTO batches VALUES('B0002','E0017','B0032','08-05-13','08-06-26',2);
INSERT INTO batches VALUES('C0003','C0018','C0033','08-06-27','08-06-28',2);
INSERT INTO batches VALUES('D0004','D0019','D0034','08-06-27','08-08-11',3);
INSERT INTO batches VALUES('E0005','E0020','E0035','08-07-01','08-08-09',2);
INSERT INTO batches VALUES('F0006','F0021','F0036','08-07-21','08-08-11',1);
INSERT INTO batches VALUES('G0007','V0022','G0037','08-08-31','08-09-21',3);
INSERT INTO batches VALUES('H0008','H0023','H0038','08-09-17','08-10-14',3);
INSERT INTO batches VALUES('I0009','I0024','I0039','08-09-23','08-10-20',2);
INSERT INTO batches VALUES('J0010','P0025','J0040','08-10-04','08-11-26',1);
INSERT INTO batches VALUES('K0011','F0026','K0041','08-10-10','08-11-17',2);
INSERT INTO batches VALUES('L0012','C0027','L0042','08-11-02','09-02-23',2);
INSERT INTO batches VALUES('M0013','M0028','M0043','08-12-09','09-01-02',3);
INSERT INTO batches VALUES('N0014','N0029','N0044','08-12-11','09-01-08',3);
INSERT INTO batches VALUES('O0015','O0030','O0045','08-12-15','09-01-12',2);
INSERT INTO students VALUES(001,'A0001','Andrew Johnson','M','08-01-10','677-0323','AndyJ#hotmail.com');
INSERT INTO students VALUES(002,'B0002','Dionne Peterson','F','08-01-10','324-9705','dionnepet#gmail.com');
INSERT INTO students VALUES(003,'C0003','Sydney Peters','F','08-01-10','624-9664','SydersP#yahoo.com');
INSERT INTO students VALUES(004,'D0004','Tsian Figaro','F','08-09-01','310-4957','tsianfigaro#hotmail.com');
INSERT INTO students VALUES(005,'E0005','Jewel Forbes','F','08-09-01','666-5948','Jewel#gmail.com');
INSERT INTO students VALUES(006,'F0006','Jason Fitzpatrick','M','08-01-02','657-4958','JasonFitz#hotmail.com');
INSERT INTO students VALUES(007,'G0007','Ali Maharaj','M','08-01-02','674-4437','AliMaharaj#gmail.com');
INSERT INTO students VALUES(008,'H0008','Mariah Sunderstone','F','08-01-02','707-4056','mariahS#yahoo.com');
INSERT INTO students VALUES(009,'I0009','Ariah Baron','F','08-01-02','673-9685','AriBar#yahoo.com');
INSERT INTO students VALUES(010,'J0010','Joe Zheng ','M','08-09-01','348-4567','Zhengdo#hotmail.com');
INSERT INTO students VALUES(011,'K0011','Donald Yen','M','08-09-01','328-4749','DonnieYen#gmail.com');
INSERT INTO students VALUES(012,'L0012','Jackson Chang','M','08-08-27','345-6847','JackieChang#yahoo.com');
INSERT INTO students VALUES(013,'M0013','Scott Smith','M','08-01-02','702-9903','Scottsmith#hotmail.com');
INSERT INTO students VALUES(014,'N0014','Michelle Shareef','F','08-02-27','321-0589','michelleShareef#gmail.com');
INSERT INTO students VALUES(015,'O0015','Jean Louis Pierre ','M','08-09-01','428-8378','JLPierre#gmail.com');
The error that keeps coming up for batches Table is :
ORA-02290: check constraint (EJAY.BATCHES_DATE_CHK) violated
ANd the error that comes up for students Table is:
ORA-02291: integrity constraint violated - parent key not found
What I'm confused about is that it only shows up for some rows in the tables. faculty and courses are fine, it's just these two.
If the answers is obvious, I apologize, I'm a beginner. Please help
Insert in Batches is failing because you have your dates mixed up; they're dd-mm-yy.
For example, INSERT INTO batches VALUES('D0004','D0019','D0034','08-06-27','08-08-11',3); fails the test stdate <= enddate.
The insert in Students is failing because you're referring to a value in Batches that does not exist (because the inserts failed?).

Employee/History - Part of composite key as foreign key

I've got 2 entities:
1) EMPLOYEES (Parent)
CREATE TABLE EMPLOYEES (
employee_id NUMBER (3) NOT NULL,
first_name VARCHAR (20) NOT NULL,
last_name VARCHAR (20) NOT NULL,
job_title VARCHAR (20) NOT NULL,
employee_type VARCHAR (1) NOT NULL,
salary NUMBER (5),
hourly_pay NUMBER (5,2),
bonus_pay NUMBER (5,2),
CONSTRAINT employee_pk PRIMARY KEY(employee_id));
2) EMPLOYEE_HISTORY (Child)
CREATE TABLE EMPLOYEE_HISTORY (
start_date DATE NOT NULL,
employee_id NUMBER (3) NOT NULL,
end_date DATE,
job_title VARCHAR (10) NOT NULL,
hourly_rate NUMBER (5,2) NOT NULL,
CONSTRAINT employee_history_pk PRIMARY KEY(start_date, employee_id));
I'm trying to create:
ALTER TABLE employee_history
ADD CONSTRAINT employee_history_fk
FOREIGN KEY (employee_id)
REFERENCES employee_history(employee_id);
When I do this, I get an error
ORA-02270: no matching unique or primary key for this column-list
My guess is that I cannot create the constraint on just employee_id because I have a composite key in my child table. I understand when an employee gets put into the database, the parent table is filled out and the "start date" should be filled out along with everything else. However, I do not understand how this would work if I had start_date in my parent table as well. I would be able to create my constraint, yes, but how will I be able to keep a record of changes in start_date if my start_date was inputted at the time of when the employee was entered into the database.I thought about using job_title as a primary key instead of start_date because it's present in both tables, but what happens when an employee gets promoted and demoted again? Won't a duplicate value constraint come up when the same employee_id and job_title is getting inserted?
Your references clause needs to reference the parent table. Not the child table
ALTER TABLE employee_history
ADD CONSTRAINT employee_history_fk
FOREIGN KEY (employee_id)
REFERENCES employee(employee_id); -- employee not employee_history
The SQL you posted is trying to create a self-referential foreign key where employee_history is both the parent and the child. That doesn't make sense in this case.

Resources