Oracle - Text Classification (adding a secondary column) - oracle

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;

Related

Inserting values into newly created table from a pre-existing table using a cursor and for loop - Snowflake SQL (classic web interface)

I'm trying to insert values into a new table in the classic Snowflake SQL web interface using data from a table that was already created, a cursor, and a for loop. My goal is to insert new information and information from the original table into the new table, but when I try and run my code, there is an error where I am referring to the column of my original table. (See code below)
-- Creation and inserting values into table invoice_original
create temporary table invoice_original (id integer, price number(12,2));
insert into invoice_original (id, price) values
(1, 11.11),
(2, 22.22);
-- Creates final empty table invoice_final
create temporary table invoice_final (
study_number varchar,
price varchar,
price_type varchar);
execute immediate $$
declare
c1 cursor for select price from invoice_original;
begin
for record in c1 do
insert into invoice_final(study_number, price, price_type)
values('1', record.price, 'Dollars');
end for;
end;
$$;
My end goal is to have the resulting table invoice_final with 3 columns - study_number, price, and price_type where the price value comes from the invoice_original table. The error I'm currently getting is:
Uncaught exception of type 'STATEMENT_ERROR' on line 6 at position 8 : SQL compilation error: error line 2 at position 20 invalid identifier 'RECORD.PRICE'.
Does anyone know why the record.price is not capturing the price value from the invoice_original table?
there are a number of type of dynamic SQL that do not handle the cursor name, and thus give this error if you push it into a single name temp value it will work:
for record in c1 do
let temp_price number := record.price;
insert into invoice_final(study_number, price, price_type)
values('1', temp_price, 'Dollars');
end for;
this sql has not been run, and could be the wrong format, but it is the base issue.
Also this really looks like an INSERT would work, but I also assume this is the nature of simplify the question down.
See the following for details on working with variables:
https://docs.snowflake.com/en/developer-guide/snowflake-scripting/variables.html#working-with-variables
The revised code below functions as desired:
-- Creation and inserting values into table invoice_original
create
or replace temporary table invoice_original (id integer, price number(12, 2));
insert into
invoice_original (id, price)
values
(1, 11.11),
(2, 22.22);
-- Creates final empty table invoice_final
create
or replace temporary table invoice_final (
study_number varchar,
price number(12, 2),
price_type varchar
);
execute immediate $$
declare
new_price number(12,2);
c1 cursor for select price from invoice_original;
begin
for record in c1 do
new_price := record.price;
insert into invoice_final(study_number, price, price_type) values('1',:new_price, 'Dollars');
end for;
end;
$$;
Note that I changed the target table definition for price to NUMBER (12,2) instead of VARCHAR, and assigned the record.price to a local variable that was passed to the insert statement as :new_price.
That all said ... I would strongly recommend against this approach for loading tables for performance reasons. You can replace all of this with an INSERT .. AS ... SELECT.
Always opt for set based processing over cursor / loop / row based processing with Snowflake.
https://docs.snowflake.com/en/sql-reference/sql/insert.html

execute SQL query stored in a table

I have a table having one of the columns that stores SQL query returning ids or it stores comma separated ids.
create table to store query or ids(separated by ,)
create table test1
(
name varchar(20) primary key,
stmt_or_value varchar(500),
type varchar(50)
);
insert into test1 (name, stmt_or_value, type)
values ('first', 'select id from data where id = 1;','SQL_QUERY')
insert into test1 (name, stmt_or_value, type)
values ('second', '1,2,3,4','VALUE')
data table is as follows
create table data
(
id number,
subject varchar(500)
);
insert into data (id, subject) values (1, 'test subject1');
insert into data (id, subject) values (2, 'test subject2');
insert into data (id, subject) values (3, 'test subject2');
I am not able to formulate query that will return values after either executing stored sql or parsing stored ids based on the value of name.
select id, subject
from data
where id in( EXECUTE IMMEDIATE stmt_or_value
where type='SQL_QUERY'
and name = 'first') or
( parse and return ids
from stmt_or_value
where type='VALUE'
and name = 'second')
Could you please help me in this.
Parsing comma separated value is done, I basically need help in below first part of the query:
( EXECUTE IMMEDIATE stmt_or_value
where type='SQL_QUERY'
and name = 'first')
This seems a very peculiar requirement, and one which will be difficult to solve in a robust fashion. STMT_OR_VALUE is the embodiment of the One Column Two Usages anti-pattern. Furthermore, resolving STMT_OR_VALUE requires flow control logic and the use of dynamic SQL. Consequently it cannot be a pure SQL solution: you need to use PL/SQL to assemble and execute the dynamic query.
Here is a proof of concept for a solution. I have opted for a function which you can call from SQL. It depends on one assumption: every query string you insert into TEST1.STMT_OR_VALUE has a projection of a single numeric column and every value string is a CSV of numeric data only. With this proviso it is simple to construct a function which either executes a dynamic query or tokenizes the string into a series of numbers; both of which are bulk collected into a nested table:
create or replace function get_ids (p_name in test1.name%type)
return sys.odcinumberlist
is
l_rec test1%rowtype;
return_value sys.odcinumberlist;
begin
select * into l_rec
from test1
where name = p_name;
if l_rec.type = 'SQL_QUERY' then
-- execute a query
execute immediate l_rec.stmt_or_value
bulk collect into return_value;
else
-- tokenize a string
select xmltab.tkn
bulk collect into return_value
from ( select l_rec.stmt_or_value from dual) t
, xmltable( 'for $text in ora:tokenize($in, ",") return $text'
passing stmt_or_value as "in"
columns tkn number path '.'
) xmltab;
end if;
return return_value;
end;
/
Note there is more than one way of executing a dynamic SQL statement and a multiplicity of ways to tokenize a CSV into a series of numbers. My decisions are arbitrary: feel free to substitute your preferred methods here.
This function can be invoked with a table() call:
select *
from data
where id in ( select * from table(get_ids('first'))) -- execute query
or id in ( select * from table(get_ids('second'))) -- get string of values
/
The big benefit of this approach is it encapsulates the logic around the evaluation of STMT_OR_VALUE and hides use of Dynamic SQL. Consequently it is easy to employ it in any SQL statement whilst retaining readability, or to add further mechanisms for generating a set of IDs.
However, this solution is brittle. It will only work if the values in the test1 table obey the rules. That is, not only must they be convertible to a stream of single numbers but the SQL statements must be valid and executable by EXECUTE IMMEDIATE. For instance, the trailing semi-colon in the question's sample data is invalid and would cause EXECUTE IMMEDIATE to hurl. Dynamic SQL is hard not least because it converts compilation errors into runtime errors.
Following is the set up data used for this example:
create table test1
(
test_id number primary key,
stmt_or_value varchar(500),
test_type varchar(50)
);
insert into test1 (test_id, stmt_or_value, test_type)
values (1, 'select id from data where id = 1','SQL_QUERY');
insert into test1 (test_id, stmt_or_value, test_type)
values (2, '1,2,3,4','VALUE');
insert into test1 (test_id, stmt_or_value, test_type)
values (3, 'select id from data where id = 5','SQL_QUERY');
insert into test1 (test_id, stmt_or_value, test_type)
values (4, '3,4,5,6','VALUE');
select * from test1;
TEST_ID STMT_OR_VALUE TEST_TYPE
1 select id from data where id = 1 SQL_QUERY
2 1,2,3,4 VALUE
3 select id from data where id = 5 SQL_QUERY
4 3,4,5,6 VALUE
create table data
(
id number,
subject varchar(500)
);
insert into data (id, subject) values (1, 'test subject1');
insert into data (id, subject) values (2, 'test subject2');
insert into data (id, subject) values (3, 'test subject3');
insert into data (id, subject) values (4, 'test subject4');
insert into data (id, subject) values (5, 'test subject5');
select * from data;
ID SUBJECT
1 test subject1
2 test subject2
3 test subject3
4 test subject4
5 test subject5
Below is the solution:
declare
sql_stmt clob; --to store the dynamic sql
type o_rec_typ is record(id data.id%type, subject data.subject%type);
type o_tab_typ is table of o_rec_typ;
o_tab o_tab_typ; --to store the output records
begin
--The below SELECT query generates the required dynamic SQL
with stmts as (
select (listagg(stmt_or_value, ' union all ') within group(order by stmt_or_value))||' union all ' s
from test1 t
where test_type = 'SQL_QUERY')
select
q'{select id, subject
from data
where id in (}'||
nullif(s,' union all ')||q'{
select distinct to_number(regexp_substr(s, '[^,]+', 1, l)) id
from (
select level l,
s
from (select listagg(stmt_or_value,',') within group(order by stmt_or_value) s
from test1
where test_type = 'VALUE') inp
connect by level <= length (regexp_replace(s, '[^,]+')) + 1))}' stmt into sql_stmt
from stmts; -- Create the dynamic SQL and store it into the clob variable
--execute the statement, fetch and display the output
execute immediate sql_stmt bulk collect into o_tab;
for i in o_tab.first..o_tab.last
loop
dbms_output.put_line('id: '||o_tab(i).id||' subject: '||o_tab(i).subject);
end loop;
end;
Output:
id: 1 subject: test subject1
id: 2 subject: test subject2
id: 3 subject: test subject3
id: 4 subject: test subject4
id: 5 subject: test subject5
Learnings:
Avoid using key words for table and column names.
Design application tables effectively to serve current and reasonable future requirements.
The above SQL will work. Still it is wise to consider reviewing the table design because, the complexity of the code will keep increasing with changes in requirements in future.
Learned how to convert comma separated values into records. "https://asktom.oracle.com/pls/apex/f?p=100:11:::NO::P11_QUESTION_ID:9538583800346706523"
declare
my_sql varchar2(1000);
v_num number;
v_num1 number;
begin
select stmt_or_value into my_sql from test1 where ttype='SQL_QUERY';
execute immediate my_sql into v_num;
select id into v_num1 from data where id=v_num;
dbms_output.put_line(v_num1);
end;
Answer for part 1.Please check.

how to make distinct type with condition in oracle

create or replace TYPE PDV AS OBJECT
( percentage NUMBER(4,2),
MEMBER FUNCTION get_percentage RETURN NUMBER
) INSTANTIABLE NOT FINAL;
create or replace TYPE BODY PDV AS
MEMBER FUNCTION get_percentage RETURN NUMBER AS
BEGIN
return SELF.percentage;
END get_percentage;
END;
I have table Product (productID, name, description, percentage)
When I insert this in the database, it should be saved in the table Product:
insert into Product VALUES (1, 'Table', 'Brown table for six people.Made of oak', PDV(20.00));
When I insert this into the database, an error should occur:
insert into Product VALUES (1, 'Table', 'Brown table for six people.Made of oak', PDV(130.20));
I want to make distinct type with condition - percentage must be between 0 and 100. Where to put that condition?
percentage must be between 0 and 100. Where to put that condition?
Nowhere, I'd say. PERCENTAGE's data type, a numeric having precision 4 and scale 2 will take care about it.
As you didn't provide whole code you use, here's an example.
SQL> create or replace type pdv as object
2 (productid number,
3 name varchar2(30),
4 description varchar2(100),
5 percentage number(4, 2),
6 member function get_percentage return number
7 ) instantiable not final;
8 /
Type created.
SQL> create or replace type body pdv as
2 member function get_percentage return number as
3 begin
4 return self.percentage;
5 end get_percentage;
6 end;
7 /
Type body created.
SQL> create table product (prod pdv);
Table created.
SQL> insert into product values (pdv(1, 'Table', 'Made of oak', 20));
1 row created.
SQL> insert into product values (pdv(1, 'Table', 'Made of oak', 130));
insert into product values (pdv(1, 'Table', 'Made of oak', 130))
*
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column
SQL> insert into product values (pdv(1, 'Table', 'Made of oak', 55.567));
1 row created.
SQL>
[EDIT, written after reading OP's comment]
I'm not sure I understood what you mean. If it means that you want to create an inline CHECK constraint, well, that won't work:
SQL> create or replace type pdv_typ as object
2 (
3 producid number,
4 name varchar2 (30),
5 description varchar2 (100),
6 percentage number (4, 2) constraint ch_perc check (percentage between 0 and 100),
7 member function get_percentage
8 return number
9 );
10 /
create or replace type pdv_typ as object
*
ERROR at line 1:
ORA-06545: PL/SQL: compilation error - compilation aborted
ORA-06550: line 6, column 29:
PLS-00103: Encountered the symbol "CONSTRAINT" when expecting one of the
following:
:= ) , not null default external character
ORA-06550: line 0, column 0:
PLS-00565: PDV_TYP must be completed as a potential REF target (object type)
SQL>
What you could do is to create a table whose column data type is of a previously created type, such as this:
SQL> create or replace type pdv_typ as object
2 (
3 producid number,
4 name varchar2 (30),
5 description varchar2 (100),
6 percentage number (4, 2),
7 member function get_percentage
8 return number
9 );
10 /
Type created.
SQL> create or replace type body pdv_typ
2 as
3 member function get_percentage
4 return number
5 as
6 begin
7 return self.percentage;
8 end get_percentage;
9 end;
10 /
Type body created.
SQL> create table pdv_tab
2 (
3 id number primary key,
4 pdv pdv_typ constraint ch_perc check (pdv.percentage between 0 and 100)
5 );
Table created.
SQL>
SQL> insert into pdv_tab values (1, pdv_typ (1, 'Table', 'Made of oak', 20));
1 row created.
SQL> insert into pdv_tab values (2, pdv_typ (2, 'Chair', 'Made of steel', 120));
insert into pdv_tab values (2, pdv_typ (2, 'Chair', 'Made of steel', 120))
*
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column
SQL> insert into pdv_tab values (3, pdv_typ (3, 'Window', 'Made of glass', -5));
insert into pdv_tab values (3, pdv_typ (3, 'Window', 'Made of glass', -5))
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH_PERC) violated
SQL>
Personally, I really, really don't like object side of Oracle. For me, it is a relational DBMS. Object support came as if they wanted to say hey, look, we can do that too!. I can't remember whether I ever used that functionality, except for educational purposes. Drawbacks? Plenty. Benefits? None. Once again, from my point of view.
So, what are you, really, doing? This is not a real-life problem, is it? That suggests your comment, saying that it has to be done that way. Says who? If it is a client, tell him to mind his own business. If it is a professor, then do what he says, regardless.
The straightforward way to do this would be a CHECK constraint on the table. That could be as simple as:
create table Product (
productID number primary key
, name varchar2(30) not null
, description varchar2(128) not null
, percentage number check (percentage between 0 and 100)
);
Demo in SQL Fiddle.

Exception Oracle Instead of Update Trigger

I got one question with this Instead of Update Trigger:
CREATE OR REPLACE TRIGGER view_player_update
INSTEAD OF INSERT ON view_player
FOR EACH ROW
DECLARE
anzTeams NUMBER;
teamIdentifier NUMBER;
BEGIN
SELECT count(*) INTO anzTeams FROM team WHERE team=:NEW.team;
IF anzTeams = 0
THEN
INSERT INTO team(team) VALUES (:NEW.team);
SELECT teamid INTO teamIdentifier FROM team WHERE team=:NEW.team;
ELSE
SELECT teamid INTO teamIdentifier FROM team WHERE team=:NEW.team;
END IF;
UPDATE player SET player=:NEW.player, position=:NEW.position,teamid=teamIdentifier WHERE playerid=:OLD.playerid;
END;
One case is wrong. By an Update of an Team
UPDATE view_player SET team='Real Madrid' WHERE playerid=1
i got this Exception:
ORA-01779: Kann keine Spalte, die einer Basistabelle zugeordnet wird, verändern
The Database cannot change the entry of an basistable?!
This is my code:
CREATE TABLE team(
teamid integer PRIMARY KEY,
team VARCHAR2(100)
);
CREATE TABLE player(
playerid integer PRIMARY KEY,
player VARCHAR2(100),
position VARCHAR2(100),
teamid integer REFERENCES team(teamid)
);
INSERT ALL
INTO team (teamid, team) VALUES (1, 'FC Bayern Muenchen')
INTO team (teamid, team) VALUES (2, 'Manchester United')
SELECT * FROM DUAL;
INSERT ALL
INTO player (playerid, player, position, teamid) VALUES (1, 'Manuel Neuer', 'goalkeeper', 1)
INTO player (playerid, player, position, teamid) VALUES (2, 'Dante', 'defense', 1)
INTO player (playerid, player, position, teamid) VALUES (3, 'Cesc Fabregas', 'midfield', 2)
INTO player (playerid, player, position, teamid) VALUES (4, 'Lionel Messi', 'striker', 2)
INTO player (playerid, player, position, teamid) VALUES (5, 'Arjen Robben', 'midfield', 1)
SELECT * FROM DUAL;
CREATE VIEW view_player AS
SELECT p.playerid,p.player,p.position, t.team FROM player p
INNER JOIN team t
ON p.teamid = t.teamid;
I got a Sequence and Trigger for the Auto Increment of both Tables.
Thank you for you help!
Think about this: when you run the update statement, what do you intend should happen? Should it:
change the name of the team to which playerid 1 is joined to be 'Real Madrid', or
change the teamid for playerid 1 to be that for Real Madrid?
The database cannot know what you want, and it is unlikely on its own to do either of those even if the intention was clear.
If you want to do the former then you should instead update the player tables.
If you want to do the latter then update the team table.
I think that this approach you're taking of using instead-of triggers on a view is a very bad practice, and you should stick to the conventional methods for maintaining the data.

Automating pl\sql functions

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)

Resources