Automating pl\sql functions - oracle

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)

Related

How to use CONSTRAINT CHECK in SQLDEVELOPER on a specific DATE?

I'm trying to set a CONSTRAINT on column Nr_AnoLetivo which is a DATE, which only can be NOT NULL AND greater than the year 2000.
I've been trying this:
CREATE TABLE Classe(
Cd_Classe NUMBER(8),
Nr_AnoLetivo NUMBER(4) CONSTRAINT CLASSE_NR_ANOLETIVO_NN NOT NULL,
Cd_Escola NUMBER(5),
Cd_Grau NUMBER(2),
Nr_Serie NUMBER(2) CONSTRAINT CLASSE_NR_SERIE_NN NOT NULL,
Sg_Turma VARCHAR2(2) CONSTRAINT CLASSE_SG_TURMA_NN NOT NULL,
Cd_Periodo NUMBER(2),
CONSTRAINT CLASSE_CD_CLASSE_PK PRIMARY KEY (CD_CLASSE),
CONSTRAINT CLASSE_NR_ANOLETIVO_CK CHECK (NR_ANOLETIVO IN DATE ('2000/01/01')),
CONSTRAINT ESCOLA_CD_ESCOLA_FK FOREIGN KEY (CD_ESCOLA) REFERENCES Escola (CD_ESCOLA),
CONSTRAINT GRAU_CD_GRAU_FK FOREIGN KEY (CD_GRAU) REFERENCES Grau (CD_GRAU),
CONSTRAINT PERIODO_CD_PERIODO_FK FOREIGN KEY (CD_PERIODO) REFERENCES Periodo (CD_PERIODO)
);
And the Error message is:
00000 - "missing expression"
Something tells me this error is generated by the DATE row and I don't get it why.
Can anyone tell why is this happening?
You got it wrong.
If you declared NR_ANOLETIVO column as NUMBER(4), it seems that you expect year only in that column (such as 1957, 1998, 2010, etc.), not the whole date (such as 16.09.2018 (dd.mm.yyyy)).
Therefore, setting a constraint to check some date value is wrong - you should check that value you put into that column is larger than 2000. Something like this (your code, simplified):
SQL> create table classe
2 (cd_classe number(8) constraint pk_cla primary key,
3 --
4 nr_anoletivo number(4) constraint ch_nra_2k check (nr_anoletivo > 2000)
5 not null,
6 --
7 cd_grau number(2));
Table created.
SQL> insert into classe (cd_classe, nr_anoletivo, cd_grau) values (1, 1990, 23);
insert into classe (cd_classe, nr_anoletivo, cd_grau) values (1, 1990, 23)
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH_NRA_2K) violated
SQL> insert into classe (cd_classe, nr_anoletivo, cd_grau) values (2, 2018, 33);
1 row created.
SQL>
If you really meant to check the full date, then you should modify datatype column (to DATE), as well as the constraint:
SQL> create table classe
2 (cd_classe number(8) constraint pk_cla primary key,
3 --
4 nr_anoletivo date constraint ch_nra_2k check (nr_anoletivo > date '2000-01-01')
5 not null,
6 --
7 cd_grau number(2));
Table created.
SQL> insert into classe (cd_classe, nr_anoletivo, cd_grau) values (1, date '1990-12-25', 23);
insert into classe (cd_classe, nr_anoletivo, cd_grau) values (1, date '1990-12-25', 23)
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH_NRA_2K) violated
SQL> insert into classe (cd_classe, nr_anoletivo, cd_grau) values (2, date '2018-09-16', 33);
1 row created.
SQL>

Oracle - Text Classification (adding a secondary column)

I'm following the demo on training on classification from Oracle.
I've attached the script.
In what way can this be used to create multiple sets of rules based on a secondary column? The column wouldn't be an extra predictor, but really a way to completely isolate the rules.
That column might have its own list of data, and I'd hate to create separate sets of tables to handle the scenario.
So for example, if I added a doc_type field to ml_docs (and to the categories). When its 1 I might want to use one set of rules and if its a 2, a different set of rules. I want them to be completely isolated. What implications would that have on the script? Does Oracle support this?
create table ml_docs (
doc_id number primary key,
doc_text clob);
insert into ml_docs values
(1, 'MacTavishes is a fast-food chain specializing in burgers, fries and -
shakes. Burgers are clearly their most important line.');
insert into ml_docs values
(2, 'Burger Prince are an up-market chain of burger shops, who sell burgers -
and fries in competition with the likes of MacTavishes.');
insert into ml_docs values
(3, 'Shakes 2 Go are a new venture in the low-cost restaurant arena,
specializing in semi-liquid frozen fruit-flavored vegetable oil products.');
insert into ml_docs values
(4, 'TCP/IP network engineers generally need to know about routers,
firewalls, hosts, patch cables networking etc');
insert into ml_docs values
(5, 'Firewalls are used to protect a network from attack by remote hosts,
generally across TCP/IP');
create table ml_category_descriptions (
cd_category number,
cd_description varchar2(80));
create table ml_doc_categories (
dc_category number,
dc_doc_id number,
primary key (dc_category, dc_doc_id))
organization index;
-- descriptons for categories
insert into ml_category_descriptions values (1, 'fast food');
insert into ml_category_descriptions values (2, 'computer networking');
insert into ml_doc_categories values (1, 1);
insert into ml_doc_categories values (1, 2);
insert into ml_doc_categories values (1, 3);
insert into ml_doc_categories values (2, 4);
insert into ml_doc_categories values (2, 5);
exec ctx_ddl.create_preference('bid_lex', 'basic_lexer');
exec ctx_ddl.set_attribute ('bid_lex', 'index_themes', 'no');
exec ctx_ddl.set_attribute ('bid_lex', 'index_text', 'yes');
create index ml_docsindex on ml_docs(doc_text) indextype is ctxsys.context
parameters ('lexer bid_lex');
create table ml_rules(
rule_cat_id number,
rule_text varchar2(4000),
rule_confidence number
);
begin
ctx_cls.train(
index_name => 'ml_docsindex',
docid => 'doc_id',
cattab => 'ml_doc_categories',
catdocid => 'dc_doc_id',
catid => 'dc_category',
restab => 'ml_rules',
rescatid => 'rule_cat_id',
resquery => 'rule_text',
resconfid => 'rule_confidence'
);
end;
create index rules_idx on ml_rules (rule_text) indextype is ctxsys.ctxrule;
set serveroutput on;
declare
incoming_doc clob;
begin
incoming_doc
:= 'I have spent my entire life managing restaurants selling burgers';
for c in
( select distinct cd_description from ml_rules, ml_category_descriptions
where cd_category = rule_cat_id
and matches (rule_text, incoming_doc) > 0) loop
dbms_output.put_line('CATEGORY: '||c.cd_description);
end loop;
end;

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?).

Oracle Inserting a row in a table only if a match found in some other table

I have 3 tables in my database namely employees,students and Images
create table employees(id number primary key,name varchar2(100), address varchar2(100));
create table students(id number primary key,name varchar2(100),address varchar2(100));
create table Images (image_id number primary key,employee_id number,student_id number,image_name varchar2(100));
Insert into employees values (1,'asdfasd','asdfasdf');
Insert into employees values (2,'asdfasd','asdfasdf');
Insert into employees values (3,'asdfasd','asdfasdf');
Insert into employees values (4,'asdfasd','asdfasdf');
Insert into employees values (5,'asdfasd','asdfasdf');
Insert into students values (1,'asdfasd','asdfasdf');
Insert into students values (2,'asdfasd','asdfasdf');
Insert into students values (3,'asdfasd','asdfasdf');
Insert into students values (4,'asdfasd','asdfasdf');
Insert into students values (5,'asdfasd','asdfasdf');
Insert into students values (49,'asdfasd','asdfasdf');
Insert into Images(image_id,employee_id,image_name) values (1,5,'adsfasdfasdf');
Insert into Images(image_id,student_id,image_name) values (2,49,'asfasdfasdf');
Now, when Inserting a row into the Images table I should check whether the employee_id / Student_id is existed in the employees table/student table, If a match found then only I have to Insert else it should not.
I thought of adding two foreign keys on the images table as follows:
alter table images add constraint fk_employeeid foreign key(employee_id)
references employees(id);
alter table images add constraint fk_studentsid foreign key(student_id)
references students(id);
But, If I do so. It will not allow me to insert null values. How can I modify my design so that whenever I insert a row in images table either it should be an employee_id or an student_id.
If I created any confusion, here is the link for the sql fiddle,http://www.sqlfiddle.com/#!4/92d24/1/0
I thought of adding two foreign keys on the images table.
But, If I do so. It will not allow me to insert null values.
You are wrong when you say the foreign key constraint won't allow NULL values. It will definitely allow the NULL values.
Test case
Let's add the foreign key constraint on the IMAGES table for the employee_id and student_id.
ALTER TABLE images ADD CONSTRAINT fk_emp FOREIGN KEY(employee_id) REFERENCES employees(ID);
ALTER TABLE images ADD CONSTRAINT fk_stu FOREIGN KEY(student_id) REFERENCES students(ID);
Let's check the INSERT with NULL values:
SQL> INSERT INTO Images(image_id,employee_id,image_name) VALUES (1,5,'adsfasdfasdf');
1 row created.
SQL> INSERT INTO Images(image_id,student_id,image_name) VALUES (2,49,'asfasdfasdf');
1 row created.
SQL> INSERT INTO Images(image_id,employee_id,image_name) VALUES (3,null,'adsfasdfasdf');
1 row created.
SQL> INSERT INTO Images(image_id,student_id,image_name) VALUES (4,null,'asfasdfasdf');
1 row created.
SQL>
SQL> COMMIT;
Commit complete.
SQL>
SQL> SELECT * FROM images;
IMAGE_ID EMPLOYEE_ID STUDENT_ID IMAGE_NAME
---------- ----------- ---------- ---------------
1 5 adsfasdfasdf
2 49 asfasdfasdf
3 adsfasdfasdf
4 asfasdfasdf
SQL>
Let's check the foreign key constraint validation:
SQL> INSERT INTO Images(image_id,employee_id,image_name) VALUES (1,10,'adsfasdfasdf');
INSERT INTO Images(image_id,employee_id,image_name) VALUES (1,10,'adsfasdfasdf')
*
ERROR at line 1:
ORA-00001: unique constraint (LALIT.SYS_C0010739) violated
SQL> INSERT INTO Images(image_id,student_id,image_name) VALUES (2,20,'asfasdfasdf');
INSERT INTO Images(image_id,student_id,image_name) VALUES (2,20,'asfasdfasdf')
*
ERROR at line 1:
ORA-00001: unique constraint (LALIT.SYS_C0010739) violated
SQL>
So, everything works as per the design.
Add constraints to images like you did. Add one more constraint:
alter table images add constraint chk_nulls
check (
(employee_id is not null and student_id is null)
or (employee_id is null and student_id is not null)
);
This way you cannot insert both nulls nor both not nulls for employee_id and student_id. And foreign keys are also checked.
Test:
insert into images values (1, 1, null, 'not important'); -- OK
insert into images values (2, null, null, 'not important'); -- error
insert into images values (3, 1, 1, 'not important'); -- error
insert into images values (4, null, 1, 'not important'); -- OK
I would keep the foreign keys, that is the correct approach.
But instead of inserting NULL's, you should define an "unknown record" in your EMPLOYEES and STUDENTS tables (maybe with an id=-1, name='UNKNOWN'), and insert -1 into your IMAGES table.
I recommend you to change the primary key in table images, and have as PK three columns (image_id, employee_id and student_id).
Edit 1: Based on comment
I think you planned in a wrong way the problem. If the images are for both, employees and students, you should have two tables, images_employees and images_students, with respectively foreign keys employee_id and student_id and of course an id for the image.
But is there any sense to have a row like this?
id: 1 student_id: null image_name: 'something'
I don't think so... please explain more about the purpose of images table.

How can I modify a unique constraint to allow for a one off exception

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.

Resources