CREATE TABLE SPONSORS (owner_number INT NOT NULL,
requires_anonimity CHAR(3) NOT NULL,
CONSTRAINT chk_requires_anonimity CHECK (requires_anonimity IN ('Yes', 'No')),
FOREIGN KEY (owner_number) REFERENCES OWNER (owner_number),
PRIMARY KEY (owner_number));
CREATE TABLE DONATIONS (receipt_number NCHAR(6) CHECK(receipt_number BETWEEN 111111 AND 999999),
amount_donated NUMBER NOT NULL,
document_reference VARCHAR(50) UNIQUE ,
donations_event_number INT NOT NULL CHECK,
donations_sponsor_number INT NOT NULL,
FOREIGN KEY (donations_sponsor_number) REFERENCES SPONSORS(benefactor_number_sponspor)
);
What I am trying to get out of this command is the following instance,
If Donator BOB decided to give £100 on conditions x and y which will be referenced in the document_reference, he should be able to put in place the same conditions for a future donation, but another individual cannot use his conditions
CREATE UNIQUE INDEX doc_unique_indx
ON DONATIONS ( CASE WHEN donations_sponsor_number = donations_sponsor_number THEN AllOW to use same document_reference ELSE END);
It looks like what you have here is a modelling problem. If document reference must be unique to a particular sponsor then it should be in its own table with a foreign key to sponsor, and the donation table should have a foreign key to the document reference table.
Dave Aldridg is 100% on the mark. This is why normalization is important - your problem is trivial if you have:
SPONSORS (OWNER_NUMBER PK, ...)
DOC_REFS (DOCUMENT_REFERENCE PK,
DONOR_NUMBER FK REFERENCES SPONSORS(OWNER_NUMBER),
...)
DONATIONS (RECEIPT PK,
DOCUMENT_REFERENCE FK REFERENCES DOC_REFS(DOCUMENT_REFERENCE),
...)
If at all possible, fix your model, split the table.
That said... if you had to do this the hard way, do NOT attempt to enforce constraints with triggers (unless only one person is allowed to use the database at a time). The only thing worse than no constraint at all is a false sense of security from a perceived constraint that isn't enforced. If you absolutely must solve this with the table at hand, you can pull off a deferred constraint using a "sanity-checking" FAST REFRESH MV:
CREATE TABLE SPONSORS (owner_number INT NOT NULL,
requires_anonimity CHAR(3) NOT NULL,
CONSTRAINT chk_requires_anonimity CHECK (requires_anonimity IN ('Yes', 'No')),
PRIMARY KEY (owner_number));
CREATE TABLE DONATIONS (receipt_number NCHAR(6) CHECK(receipt_number BETWEEN 111111 AND 999999),
amount_donated NUMBER NOT NULL,
document_reference VARCHAR(50) ,
donations_event_number INT NOT NULL ,
donations_sponsor_number INT NOT NULL,
FOREIGN KEY (donations_sponsor_number) REFERENCES SPONSORS(owner_number));
CREATE MATERIALIZED VIEW LOG ON DONATIONS WITH ROWID (DOCUMENT_REFERENCE, DONATIONS_SPONSOR_NUMBER) INCLUDING NEW VALUES
CREATE MATERIALIZED VIEW DOC_REF_CONSTRAINT
REFRESH FAST ON COMMIT
AS
SELECT DOCUMENT_REFERENCE, MIN(DONATIONS_SPONSOR_NUMBER) MX, MAX(DONATIONS_SPONSOR_NUMBER) MN
FROM DONATIONS
GROUP BY DOCUMENT_REFERENCE
CREATE INDEX DOC_REF_CONSTRAINT_IDX ON DOC_REF_CONSTRAINT(DECODE(MX,MN,0,1/0))
BEGIN
INSERT INTO SPONSORS VALUES (1, 'Yes');
INSERT INTO SPONSORS VALUES (2, 'Yes');
INSERT INTO DONATIONS VALUES ('111111',100,'A',0,1);
INSERT INTO DONATIONS VALUES ('222222',100,'A',0,1);
INSERT INTO DONATIONS VALUES ('333333',100,'C',0,2);
COMMIT;
END;
-- Success!
BEGIN
INSERT INTO SPONSORS VALUES (3, 'Yes');
INSERT INTO SPONSORS VALUES (4, 'Yes');
INSERT INTO DONATIONS VALUES ('444444',100,'A',0,3);
INSERT INTO DONATIONS VALUES ('555555',100,'C',0,3);
INSERT INTO DONATIONS VALUES ('666666',100,'C',0,4);
COMMIT;
END;
--ORA-12008: error in materialized view refresh path
--ORA-01476: divisor is equal to zero
--ORA-06512: at line 7
Note - it's entiirely possible to get more creative than 1/0 - you can put a User Defined Function that throws a comprehensible EXCEPTION instead.
I want to automate the registrations system so that it automatically registers students. Then I want a procedure to automate the grading system. I have included the code that I am written to make most of this assignment work which it does but unsure how to incorporate PL\SQL automated functions for the registrations system, and the grading system. So any help or ideas I would greatly appreciated please.
set Linesize 250
set pagesize 150
drop table student;
drop table faculty;
drop table Course;
drop table Section;
drop table location;
DROP TABLE courseInstructor;
DROP TABLE Registration;
DROP TABLE grade;
create table student(
studentid number(10),
Lastname varchar2(20),
Firstname Varchar2(20),
MI Char(1),
address Varchar2(20),
city Varchar2(20),
state Char(2),
zip Varchar2(10),
HomePhone Varchar2(10),
Workphone Varchar2(10),
DOB Date,
Pin VARCHAR2(10),
Status Char(1));
ALTER TABLE Student
Add Constraint Student_StudentID_pk Primary Key (studentID);
Insert into student values (1,'xxxxxxxx','xxxxxxxxxx','x','xxxxxxxxxxxxxxx','Columbus','oh','44159','xxx-xxx-xxxx','xxx-xxx-xxxx','06-Mar-1957','1211','c');
create table faculty(
FacultyID Number(10),
FirstName Varchar2(20),
Lastname Varchar2(20),
MI Char(1),
workphone Varchar2(10),
CellPhone Varchar2(10),
Rank Varchar2(20),
Experience Varchar2(10),
Status Char(1));
ALTER TABLE Faculty
ADD Constraint Faculty_facultyId_PK PRIMARY KEY (FacultyID);
insert into faculty values (1,'xxx','xxxxxxxxxxxx','xxx-xxx-xxxx','xxx-xxx-xxxx','professor','20','f');
create table Course(
CourseId number(10),
CourseNumber Varchar2(20),
CourseName Varchar(20),
Description Varchar(20),
CreditHours Number(4),
Status Char(1));
ALTER TABLE Course
ADD Constraint Course_CourseID_pk PRIMARY KEY(CourseID);
insert into course values (1,'cit 100','computer concepts','introduction to PCs','3.0','o');
insert into course values (2,'cit 101','Database Program','Database Programming','4.0','o');
insert into course values (3,'Math 101','Algebra I','Algebra I Concepts','5.0','o');
insert into course values (4,'cit 102a','Pc applications','Aplications 1','3.0','o');
insert into course values (5,'cit 102b','pc applications','applications 2','3.0','o');
insert into course values (6,'cit 102c','pc applications','applications 3','3.0','o');
insert into course values (7,'cit 103','computer concepts','introduction systems','3.0','c');
insert into course values (8,'cit 110','Unified language','UML design','3.0','o');
insert into course values (9,'cit 165','cobol','cobol programming','3.0','o');
insert into course values (10,'cit 167','C++ Programming 1','c++ programming','4.0','o');
insert into course values (11,'cit 231','Expert Excel','spreadsheet apps','3.0','o');
insert into course values (12,'cit 233','expert Access','database devel.','3.0','o');
insert into course values (13,'cit 169','Java Programming I','Java Programming I','3.0','o');
insert into course values (14,'cit 263','Visual Basic','Visual Basic Prog','3.0','o');
insert into course values (15,'cit 275','system analysis 2','System Analysis 2','3.0','o');
create table Section(
SectionID Number(10),
CourseId Number(10),
SectionNumber VarChar2(10),
Days Varchar2(10),
StartTime Date,
EndTime Date,
LocationID Number(10),
SeatAvailable Number(3),
Status Char(1));
ALTER TABLE Section
ADD Constraint Section_SectionID_PK PRIMARY KEY(SectionID);
insert into section values (1,1,'18977','r','21-Sep-2011','10-Dec-2011','1','89','o');
create table Location(
LocationId Number(10),
Building Varchar2(20),
Room Varchar2(5),
Capacity Number(5),
Satus Char(1));
ALTER TABLE Location
ADD Constraint Location_LocationID_pk PRIMARY KEY (LocationID);
insert into Location values (1,'Clevleand Hall','cl209','35','o');
insert into Location values (2,'Toledo Circle','tc211','45','o');
insert into Location values (3,'Akron Square','as154','65','o');
insert into Location values (4,'Cincy Hall','ch100','45','o');
insert into Location values (5,'Springfield Dome','SD','35','o');
insert into Location values (6,'Dayton Dorm','dd225','25','o');
insert into Location values (7,'Columbus Hall','CB354','15','o');
insert into Location values (8,'Cleveland Hall','cl204','85','o');
insert into Location values (9,'Toledo Circle','tc103','75','o');
insert into Location values (10,'Akron Square','as201','46','o');
insert into Location values (11,'Cincy Hall','ch301','73','o');
insert into Location values (12,'Dayton Dorm','dd245','57','o');
insert into Location values (13,'Springfield Dome','SD','65','o');
insert into Location values (14,'Cleveland Hall','cl241','10','o');
insert into Location values (15,'Toledo Circle','tc211','27','o');
insert into Location values (16,'Akron Square','as311','28','o');
insert into Location values (17,'Cincy Hall','ch415','73','o');
insert into Location values (18,'Toledo Circle','tc111','67','o');
insert into Location values (19,'Springfield Dome','SD','69','o');
insert into Location values (20,'Dayton Dorm','dd211','45','o');
Alter Table Student
Add Constraint student_Zip_CK Check(Rtrim (Zip,'1234567890-') is null);
Alter Table Student
ADD Constraint Student_Status_CK Check(Status In('c','t'));
Alter Table Student
ADD Constraint Student_MI_CK2 Check(RTRIM(MI,'abcdefghijklmnopqrstuvwxyz')is Null);
Alter Table Student
Modify pin not Null;
Alter table Faculty
Add Constraint Faculty_Status_CK Check(Status In('f','a','i'));
Alter table Faculty
ADD Constraint Faculty_Rank_CK Check(Rank In ('professor','doctor','instructor','assistant','tenure'));
Alter table Faculty
ADD Constraint Faculty_MI_CK2 Check(RTRIM(MI,'abcdefghijklmnopqrstuvwxyz')is Null);
Update Section Set Starttime = To_date('09-21-2011 6:00 PM', 'mm-dd-yyyy hh:mi pm');
Update Section Set Endtime = To_date('12-10-2011 9:50 PM', 'mm-dd-yyyy hh:mi pm');
alter table Section
Add Constraint StartTime_Status_CK Check (starttime < Endtime);
Alter Table Section
Add Constraint Section_StartTime_ck check (StartTime < EndTime);
Alter Table Section
ADD Constraint Section_CourseId_FK FOREIGN KEY (CourseID) References Course(CourseId);
Alter Table Section
ADD Constraint Section_LocationID_FK FOREIGN KEY (LocationID) References Location (LocationId);
Alter Table Section
ADD Constraint Section_Days_CK Check(RTRIM(Days,'mtwrfsu')IS Null);
update section set seatavailable = '99';
Alter Table Section
ADD Constraint Section_SeatsAvailable_CK Check (SeatAvailable < 100);
Alter Table Course
Add Constraint Course_CreditHours_ck check(CreditHours < = 6.0);
update location set capacity = '99';
Alter Table Location
Add Constraint Location_Capacity_CK Check(Capacity < 100);
Create Table Registration (
StudentID Number(10),
SectionID Number(10),
Constraint Registration_pk Primary key (studentId, Sectionid));
Insert into registration values (1, 2);
Insert into Registration values (2, 3);
Insert into registration values (3, 4);
Insert into registration values (4, 5);
Insert into registration values (5, 6);
Insert into registration values (6, 7);
Insert into registration values (7, 8);
Insert into registration values (8, 9);
insert into registration values (9, 10);
insert into registration values (10, 11);
insert into registration values (9, 12);
insert into registration values (8, 13);
insert into registration values (7, 14);
insert into registration values (6, 15);
insert into registration values (5, 17);
insert into registration values (4, 18);
insert into registration values (3, 19);
insert into registration values (2, 20);
insert into registration values (1, 21);
insert into registration values (2, 22);
insert into registration values (3, 23);
insert into registration values (4, 24);
insert into registration values (5, 25);
Insert into registration values (6, 24);
insert into registration values (7, 23);
insert into registration values (8, 22);
insert into registration values (9, 21);
insert into registration values (10, 20);
insert into registration values (9, 19);
insert into registration values (8, 17);
Create Table courseInstructor(
FacultyID Number(10),
SectionID Number(10),
Constraint CourseInstructor_pk Primary key (FacultyId, SectionID));
insert into courseInstructor values (1, 1);
insert into courseInstructor values (2, 2);
insert into courseInstructor values (3, 3);
insert into courseInstructor values (4, 4);
insert into courseInstructor values (5, 5);
insert into courseInstructor values (5, 6);
insert into courseInstructor values (4, 7);
insert into courseInstructor values (3, 8);
insert into courseInstructor values (2, 9);
insert into courseInstructor values (1, 10);
insert into courseInstructor values (5, 11);
insert into courseInstructor values (4, 12);
insert into courseInstructor values (3, 13);
insert into courseInstructor values (2, 14);
insert into courseInstructor values (1, 15);
Create table grade(
StudentID Number(10),
SectionID Number(10),
Grade Varchar2(1),
Constraint grade_pk Primary key (StudentID, SectionID));
CREATE OR REPLACE TRIGGER TR_CreateGrade
AFTER INSERT ON Registration
FOR EACH ROW
BEGIN
INSERT INTO grade (SectionID,StudentID,Grade)
VALUES(:New.SectionID,:New.StudentID,NULL);
END TR_createGrade;
/
CREATE OR REPLACE FORCE VIEW V_reg_student_course AS
SELECT
Registration.StudentID,
student.LastName,
student.FirstName,
course.CourseName,
Registration.SectionID,
course.CreditHours,
section.Days,
TO_CHAR(StartTime, 'MM/DD/YYYY') AS StartDate,
TO_CHAR(StartTime, 'HH:MI PM') AS StartTime,
TO_CHAR(EndTime, 'MM/DD/YYYY') AS EndDate,
TO_CHAR(EndTime, 'HH:MI PM') AS EndTime,
location.Building,
location.Room
FROM registration, student, section, course, location
WHERE registration.StudentID = student.StudentID
AND registration.SectionID = section.SectionID
AND section.LocationID = location.LocationID
AND section.CourseID = course.CourseID;
CREATE OR REPLACE FORCE VIEW V_teacher_to_course AS
SELECT
courseInstructor.FacultyID,
faculty.FirstName,
faculty.LastName,
courseInstructor.SectionID,
section.Days,
TO_CHAR(StartTime, 'MM/DD/YYYY') AS StartDate,
TO_CHAR(StartTime, 'HH:MI PM') AS StartTime,
TO_CHAR(EndTime, 'MM/DD/YYYY') AS EndDate,
TO_CHAR(EndTime, 'HH:MI PM') AS EndTime,
location.Building,
location.Room
FROM courseInstructor, faculty, section, course, location
WHERE courseInstructor.FacultyID = faculty.FacultyID
AND courseInstructor.SectionID = section.SectionID
AND section.LocationID = location.LocationID
AND section.CourseID = course.CourseID;
SELECT * FROM V_reg_student_course;
SELECT * FROM V_teacher_to_course;
I do not know how much detail is required for this exercise but these are the things I see:
You are mixing CHAR and VARCHAR2 types, there is no reason to do this. Make your life easier and stick with VARCHAR2 if the entries are expected to be less than 4000 characters
Many people's names, cities and addresses are much longer than 20 characters. Think big, 250 characters.
Middle Initial is problematic. Not everyone has one and if they do they may want their full middle name spelled out.
Address information should be broken out into a series of separate tables but I grant this may be beyond the scope of your assignment
Not everyone lives in the United States, think about a numeric key to a secondary table for cities and states/provinces.
Many of these fields should be not null such as course number, course name
Now, onto your question about automating functions. I am not sure what you really want. A student registering for a course is initiated outside of the database. Staff would enter the students registration choices based on a form. Or the student would submit them electronically, either way some front-end application would initiate the transaction.
For example, on your front end, someone presses "Submit". Then the old fashioned way is to open a connection to the database, add some parameters, make a procedure call like
Add_student_to_course(student_id_in IN NUMBER, section_id_in IN NUMBER, registration_out OUT sys_refcursor)
Inside the procedure you check to see whether the student exists, course exists, course has seats available.
There are many different ways of dealing with error handling depending on the complexity of the validation process. If it is possible for one registration to violate several business rules then you want to return complex information. (if the course must have a seat available, if the course must have a teacher, if the student is paid up).
So, do your processing as if statements. When everything is fine, in a simple application, the sys_refcursor could look like
select registration_no, error_number from dual;
If everything is fine error_number is 0, if not return an error code. Otherwise the registration code is 0 and the error code refers to a table of errors with a human readable text.
(I am aware that this is a simplistic approach but this is a simplified exercise)