Tuesday, November 22, 2016

50 Sample Project with Oracle Application Express

OracleFlix Online Media Rentals

If you find it difficult to understand, please go through links in below mentioned google sheet step by step and come back to this page:


CUSTOMERS

MOVIES

MEDIA


RENTAL HISTORY
ACTORS

STAR_BILLINGS
ERD


Script Content


All the Activities, step 1 through 7, are performed and recorded in this script. This script is uploaded and executed in Oracle Application Express

--Drop view if exist
DROP VIEW title_unavail;
--Drop all tables if they exist
DROP TABLE rental_history PURGE;
DROP TABLE customers PURGE;
DROP TABLE media PURGE;
DROP TABLE star_billings PURGE;
DROP TABLE movies PURGE;
DROP TABLE actors PURGE;
--drop the sequences
DROP SEQUENCE customer_id_seq;
DROP SEQUENCE title_id_seq;
DROP SEQUENCE media_id_seq;
DROP SEQUENCE actor_id_seq;
-- drop the synonym
DROP SYNONYM  tu;



--now create tables
--1. Create tables using the attached ERD. AND 2. Creating and Managing Constraints

CREATE TABLE  actors
   ( actor_id NUMBER(10,0) CONSTRAINT atr_atr_id_pk PRIMARY KEY ,
                stage_name VARCHAR2(40) CONSTRAINT atr_ste_nae_nn NOT NULL ,
                first_name VARCHAR2(25) CONSTRAINT atr_fit_nae_nn NOT NULL ,
                last_name VARCHAR2(25) CONSTRAINT atr_lat_nae_nn NOT NULL ,
                birth_date DATE CONSTRAINT atr_bih_dae_nn NOT NULL
   );
CREATE TABLE  movies
   ( title_id NUMBER(10,0) CONSTRAINT mie_tte_id_pk PRIMARY KEY ,
                title VARCHAR2(60) CONSTRAINT mie_tte_nn NOT NULL ,
                description VARCHAR2(400) CONSTRAINT mie_dsn_nn NOT NULL ,
                --rating VARCHAR2(4) CONSTRAINT atr_rig_chk CHECK (UPPER(rating) IN ('G', 'PG', 'R', 'PG13')),
                rating VARCHAR2(4) CONSTRAINT mie_rig_chk CHECK ( rating  IN ('G', 'PG', 'R', 'PG13')),
                category VARCHAR2(20) CONSTRAINT mie_cey_chk CHECK ( category  IN ('DRAMA', 'COMEDY', 'ACTION', 'CHILD', 'SCIFI', 'DOCUMENTARY')),
                --category VARCHAR2(20) CONSTRAINT atr_cey_chk CHECK ( UPPER(category)  IN ('DRAMA', 'COMEDY', 'ACTION', 'CHILD', 'SCIFI', 'DOCUMENTARY')),             
                release_date DATE CONSTRAINT mie_rle_dae_nn NOT NULL
   ); 
  
   CREATE TABLE  star_billings
   ( actor_id NUMBER(10,0) CONSTRAINT str_big_atr_id_fk REFERENCES actors(actor_id) ,
                title_id NUMBER(10,0) CONSTRAINT str_big_tte_id_fk REFERENCES movies(title_id) ,
                comments VARCHAR2(40),
                CONSTRAINT str_big_atr_id_tte_id_pk PRIMARY KEY (actor_id, title_id)
   );


 CREATE TABLE  media
   ( media_id NUMBER(10,0) CONSTRAINT mda_mda_id_pk PRIMARY KEY ,
                format VARCHAR2(3) CONSTRAINT mda_fmt_nn NOT NULL ,
                title_id NUMBER(10,0) CONSTRAINT mda_tte_id_nn NOT NULL  ,
                CONSTRAINT mda_tte_id_fk FOREIGN KEY(title_id)  REFERENCES movies(title_id)
   );

 CREATE TABLE  customers
   ( customer_id NUMBER(10,0) CONSTRAINT ctr_ctr_id_pk PRIMARY KEY ,
                last_name VARCHAR2(25) CONSTRAINT ctr_lat_nae_nn NOT NULL ,
                first_name VARCHAR2(25) CONSTRAINT ctr_fit_nae_nn NOT NULL ,
                home_phone VARCHAR2(12) CONSTRAINT ctr_hoe_phe_nn NOT NULL ,
                address VARCHAR2(100) CONSTRAINT ctr_ads_nn NOT NULL ,
                city VARCHAR2(30) CONSTRAINT ctr_cyy_nn NOT NULL ,
                state VARCHAR2(2) CONSTRAINT ctr_ste_nn NOT NULL ,
                email VARCHAR2(25),
                cell_phone VARCHAR2(12)
   );

 CREATE TABLE  rental_history
   ( media_id NUMBER(10,0) CONSTRAINT ral_hty_mda_id_fk REFERENCES media(media_id) ,
                rental_date DATE DEFAULT SYSDATE ,
                customer_id NUMBER(10,0)  CONSTRAINT ral_hty_ctr_id_nn NOT NULL ,
                return_date DATE ,
                CONSTRAINT ral_hty_ctr_id_fk FOREIGN KEY(customer_id)  REFERENCES customers(customer_id),
                CONSTRAINT ral_hty_mda_id_ral_dae_pk PRIMARY KEY (media_id, rental_date)
   ); 

--3. Create a view called TITLE_UNAVAIL
CREATE OR REPLACE VIEW title_unavail ("movie title", "media id") AS
SELECT movies.title,  media.media_id
FROM
rental_history  INNER JOIN  media ON rental_history.media_id = media.media_id INNER JOIN movies ON media.title_id   = movies.title_id
WHERE rental_history.return_date IS NULL
WITH READ ONLY; 

--4. Create the following sequences to be used for primary key values
CREATE SEQUENCE customer_id_seq
START WITH 101;
CREATE SEQUENCE title_id_seq;
CREATE SEQUENCE media_id_seq
START WITH 92;
CREATE SEQUENCE actor_id_seq
START WITH 1001;





--5. Add the data to the tables. Be sure to use the sequences for the PKs

INSERT INTO actors(actor_id, stage_name, first_name, last_name, birth_date)
VALUES(actor_id_seq.NEXTVAL, 'Brad Pitt', 'William', 'Pitt', TO_DATE('18-DEC-1963','DD-MON-YYYY'));
INSERT INTO actors(actor_id, stage_name, first_name, last_name, birth_date)
VALUES(actor_id_seq.NEXTVAL, 'Amitabh Bachchan', 'Amit', 'Srivastav', TO_DATE('11-10-1942','DD-MM-YYYY'));
INSERT INTO actors(actor_id, stage_name, first_name, last_name, birth_date)
VALUES(actor_id_seq.NEXTVAL, 'Aamir Khan', 'Aamir', 'Hussain Khan', TO_DATE('14 March 1965','DD Month YYYY'));
INSERT INTO actors(actor_id, stage_name, first_name, last_name, birth_date)
VALUES(actor_id_seq.NEXTVAL, 'Akshay Kumar', 'Rajiv', 'Bhatia', TO_DATE('09/09/1967','DD/MM/YYYY'));


INSERT INTO movies(title_id, title , description ,  rating , category , release_date )
VALUES(title_id_seq.NEXTVAL, 'Fight Club', 'An insomniac office worker, looking for a way to change his life, crosses paths with a devil-may-care soap maker, forming an underground fight club that evolves into something much, much more.', 'R', 'DRAMA',  TO_DATE('15 October 1999','DD Month YYYY'));
INSERT INTO movies(title_id, title , description ,  rating , category , release_date )
VALUES(title_id_seq.NEXTVAL, 'World War Z', 'Former United Nations employee Gerry Lane traverses the world in a race against time to stop the Zombie pandemic that is toppling armies and governments, and threatening to destroy humanity itself.', 'PG13', 'ACTION',
  TO_DATE('21 June 2013','DD Month YYYY'));
INSERT INTO movies(title_id, title , description ,  rating , category , release_date )
VALUES(title_id_seq.NEXTVAL, 'The Curious Case of Benjamin Button', 'Tells the story of Benjamin Button, a man who starts aging backwards with bizarre consequences.', 'PG13', 'DRAMA',
  TO_DATE('25 December 2008','DD Month YYYY'));
INSERT INTO movies(title_id, title , description ,  rating , category , release_date )
VALUES(title_id_seq.NEXTVAL, 'The Great Gatsby', 'A writer and wall street trader, Nick, finds himself drawn to the past and lifestyle of his millionaire neighbor, Jay Gatsby.', 'PG13', 'DRAMA',
  TO_DATE('10 May 2013','DD Month YYYY'));
INSERT INTO movies(title_id, title , description ,  rating , category , release_date )
VALUES(title_id_seq.NEXTVAL, '3 Idiots', 'Two friends are searching for their long lost companion. They revisit their college days and recall the memories of their friend who inspired them to think differently, even as the rest of the world called them "idiots".', 'PG13', 'DRAMA',
  TO_DATE('25 December 2009','DD Month YYYY')); 
INSERT INTO movies(title_id, title , description ,  rating , category , release_date )
VALUES(title_id_seq.NEXTVAL, 'Baby', 'An elite counter-intelligence unit learns of a plot, masterminded by a maniacal madman. With the clock ticking, it''s up to them to track the terrorists'' international tentacles and prevent them from striking at the heart of India.', NULL, 'ACTION',
  TO_DATE('23 January 2015','DD Month YYYY'));
 
 
INSERT INTO star_billings(actor_id, title_id , comments)
VALUES(1001,1, 'soap salesman named Tyler Durden'); 
INSERT INTO star_billings(actor_id, title_id , comments)
VALUES(1001,2, 'a former United Nations investigator'); 
INSERT INTO star_billings(actor_id, title_id , comments)
VALUES(1001,3, NULL);
INSERT INTO star_billings(actor_id, title_id , comments)
VALUES(1002,4, 'a Jewish friend and mentor of Gatsby''s'); 
INSERT INTO star_billings(actor_id, title_id , comments)
VALUES(1003,5, 'Phunsukh Wangdu'); 
INSERT INTO star_billings(actor_id, title_id , comments)
VALUES(1004,6, 'as Ajay Singh Rajput');

INSERT INTO media(media_id, format , title_id)
VALUES(media_id_seq.NEXTVAL,'DVD',1);
INSERT INTO media(media_id, format , title_id)
VALUES(media_id_seq.NEXTVAL,'VHS',1);
INSERT INTO media(media_id, format , title_id)
VALUES(media_id_seq.NEXTVAL,'DVD',2);
INSERT INTO media(media_id, format , title_id)
VALUES(media_id_seq.NEXTVAL,'VHS',2); 
INSERT INTO media(media_id, format , title_id)
VALUES(media_id_seq.NEXTVAL,'DVD',3);
INSERT INTO media(media_id, format , title_id)
VALUES(media_id_seq.NEXTVAL,'VHS',3);
INSERT INTO media(media_id, format , title_id)
VALUES(media_id_seq.NEXTVAL,'DVD',4);
INSERT INTO media(media_id, format , title_id)
VALUES(media_id_seq.NEXTVAL,'VHS',4);
INSERT INTO media(media_id, format , title_id)
VALUES(media_id_seq.NEXTVAL,'DVD',5);
INSERT INTO media(media_id, format , title_id)
VALUES(media_id_seq.NEXTVAL,'VHS',5);
INSERT INTO media(media_id, format , title_id)
VALUES(media_id_seq.NEXTVAL,'DVD',6);
INSERT INTO media(media_id, format , title_id)
VALUES(media_id_seq.NEXTVAL,'VHS',6);

INSERT INTO customers(customer_id, last_name, first_name,  home_phone, address, city, state, email,  cell_phone)
VALUES(customer_id_seq.NEXTVAL,'Palombo', 'Lisa', '716-270-2669', '123 Main St', 'Buffalo', 'NY', 'palombo@ecc.edu', '716-555-1212');
INSERT INTO customers(customer_id, last_name, first_name,  home_phone, address, city, state, email,  cell_phone)
VALUES(customer_id_seq.NEXTVAL,'Bee', 'Cole', '407-555-8234', '123 Main St', 'Orlando', 'FL', 'cbee@edu.edu', NULL);
INSERT INTO customers(customer_id, last_name, first_name,  home_phone, address, city, state, email,  cell_phone)
VALUES(customer_id_seq.NEXTVAL,'Twee', 'Zoe', '709-867-5309', '1009 Oliver Avenue', 'Boston', 'MA', NULL, NULL);
INSERT INTO customers(customer_id, last_name, first_name,  home_phone, address, city, state)
VALUES(customer_id_seq.NEXTVAL,'Rampal', 'Amarjeet', '408-809-1212', '1212 Down Trail', 'Buffalo', 'NY');
INSERT INTO customers(customer_id, last_name, first_name,  home_phone, address, city, state)
VALUES(customer_id_seq.NEXTVAL,'Tulli', 'Manoj', '404-200-3011', '3011 Great Rd', 'Atlanta', 'GA');
INSERT INTO customers(customer_id, last_name, first_name,  home_phone, address, city, state)
VALUES(customer_id_seq.NEXTVAL,'Hare Krishna', 'Goswami', '415-503-4444', '405 Church St.', 'Lawrenceville', 'GA');



INSERT INTO rental_history(media_id, rental_date, customer_id,  return_date)
VALUES(94, TO_DATE('09/09/1967','DD/MM/YYYY'), 106, TO_DATE('16/09/1967','DD/MM/YYYY') );
INSERT INTO rental_history(media_id, rental_date, customer_id,  return_date)
VALUES(94, TO_DATE('20/06/1968','DD/MM/YYYY'), 104, NULL );
INSERT INTO rental_history(media_id, rental_date, customer_id,  return_date)
VALUES(92, TO_DATE('19-SEP-2010','DD-MON-YYYY'), 101, TO_DATE('20-SEP-2010','DD-MON-YYYY') );
INSERT INTO rental_history(media_id, rental_date, customer_id,  return_date)
VALUES(92, TO_DATE('25-SEP-2010','DD-MON-YYYY'), 101, NULL );



--6. Create an index on the last_name column of the Customers table.
CREATE INDEX ctr_lat_nae_idx
 on customers(last_name);

--7. Create a synonym called TU for the TITLE_UNAVAIL view.
CREATE  SYNONYM tu
FOR title_unavail;


Now each step of script output verification:



  

Number
Elapsed
Statement
Feedback
Rows
1
0
DROP VIEW title_unavail
ORA-00942: table or view does not exist

2
0.01
DROP TABLE rental_history PURGE
ORA-00942: table or view does not exist

3
0
DROP TABLE customers PURGE
ORA-00942: table or view does not exist

4
0.01
DROP TABLE media PURGE
ORA-00942: table or view does not exist

5
0
DROP TABLE star_billings PURGE
ORA-00942: table or view does not exist

6
0.01
DROP TABLE movies PURGE
ORA-00942: table or view does not exist

7
0
DROP TABLE actors PURGE
ORA-00942: table or view does not exist

8
0.01
DROP SEQUENCE customer_id_seq
ORA-02289: sequence does not exist

9
0
DROP SEQUENCE title_id_seq
ORA-02289: sequence does not exist

10
0
DROP SEQUENCE media_id_seq
ORA-02289: sequence does not exist

11
0.01
DROP SEQUENCE actor_id_seq
ORA-02289: sequence does not exist

12
0
DROP SYNONYM  tu
ORA-01434: private synonym to be dropped does not exist

13
0.02
CREATE TABLE  actors    ( actor_id NUMBER(10,0) CONSTRAINT a
Table created.
0
14
0.02
CREATE TABLE  movies    ( title_id NUMBER(10,0) CONSTRAINT m
Table created.
0
15
0.01
CREATE TABLE  star_billings    ( actor_id NUMBER(10,0) CO
Table created.
0
16
0.02
CREATE TABLE  media    ( media_id NUMBER(10,0) CONSTRAINT m
Table created.
0
17
0.02
CREATE TABLE  customers    ( customer_id NUMBER(10,0) CONST
Table created.
0
18
0.01
CREATE TABLE  rental_history    ( media_id NUMBER(10,0) CON
Table created.
0
19
0.01
CREATE OR REPLACE VIEW title_unavail ("movie title", "media
View created.
0
20
0.01
CREATE SEQUENCE customer_id_seq START WITH 101
Sequence created.
0
21
0
CREATE SEQUENCE title_id_seq
Sequence created.
0
22
0.01
CREATE SEQUENCE media_id_seq START WITH 92
Sequence created.
0
23
0
CREATE SEQUENCE actor_id_seq START WITH 1001
Sequence created.
0
24
0.01
INSERT INTO actors(actor_id, stage_name, first_name, last_na
1 row(s) inserted.
1
25
0
INSERT INTO actors(actor_id, stage_name, first_name, last_na
1 row(s) inserted.
1
26
0
INSERT INTO actors(actor_id, stage_name, first_name, last_na
1 row(s) inserted.
1
27
0.01
INSERT INTO actors(actor_id, stage_name, first_name, last_na
1 row(s) inserted.
1
28
0
INSERT INTO movies(title_id, title , description ,  rating ,
1 row(s) inserted.
1
29
0.01
INSERT INTO movies(title_id, title , description ,  rating ,
1 row(s) inserted.
1
30
0
INSERT INTO movies(title_id, title , description ,  rating ,
1 row(s) inserted.
1
31
0
INSERT INTO movies(title_id, title , description ,  rating ,
1 row(s) inserted.
1
32
0
INSERT INTO movies(title_id, title , description ,  rating ,
1 row(s) inserted.
1
33
0
INSERT INTO movies(title_id, title , description ,  rating ,
1 row(s) inserted.
1
34
0
INSERT INTO star_billings(actor_id, title_id , comments) VAL
1 row(s) inserted.
1
35
0.01
INSERT INTO star_billings(actor_id, title_id , comments) VAL
1 row(s) inserted.
1
36
0
INSERT INTO star_billings(actor_id, title_id , comments) VAL
1 row(s) inserted.
1
37
0
INSERT INTO star_billings(actor_id, title_id , comments) VAL
1 row(s) inserted.
1
38
0
INSERT INTO star_billings(actor_id, title_id , comments) VAL
1 row(s) inserted.
1
39
0.01
INSERT INTO star_billings(actor_id, title_id , comments) VAL
1 row(s) inserted.
1
40
0
INSERT INTO media(media_id, format , title_id) VALUES(media_
1 row(s) inserted.
1
41
0
INSERT INTO media(media_id, format , title_id) VALUES(media_
1 row(s) inserted.
1
42
0.01
INSERT INTO media(media_id, format , title_id) VALUES(media_
1 row(s) inserted.
1
43
0
INSERT INTO media(media_id, format , title_id) VALUES(media_
1 row(s) inserted.
1
44
0
INSERT INTO media(media_id, format , title_id) VALUES(media_
1 row(s) inserted.
1
45
0
INSERT INTO media(media_id, format , title_id) VALUES(media_
1 row(s) inserted.
1
46
0.01
INSERT INTO media(media_id, format , title_id) VALUES(media_
1 row(s) inserted.
1
47
0
INSERT INTO media(media_id, format , title_id) VALUES(media_
1 row(s) inserted.
1
48
0
INSERT INTO media(media_id, format , title_id) VALUES(media_
1 row(s) inserted.
1
49
0
INSERT INTO media(media_id, format , title_id) VALUES(media_
1 row(s) inserted.
1
50
0.01
INSERT INTO media(media_id, format , title_id) VALUES(media_
1 row(s) inserted.
1
51
0
INSERT INTO media(media_id, format , title_id) VALUES(media_
1 row(s) inserted.
1
52
0
INSERT INTO customers(customer_id, last_name, first_name,  h
1 row(s) inserted.
1
53
0.01
INSERT INTO customers(customer_id, last_name, first_name,  h
1 row(s) inserted.
1
54
0
INSERT INTO customers(customer_id, last_name, first_name,  h
1 row(s) inserted.
1
55
0
INSERT INTO customers(customer_id, last_name, first_name,  h
1 row(s) inserted.
1
56
0
INSERT INTO customers(customer_id, last_name, first_name,  h
1 row(s) inserted.
1
57
0.01
INSERT INTO customers(customer_id, last_name, first_name,  h
1 row(s) inserted.
1
58
0
INSERT INTO rental_history(media_id, rental_date, customer_i
1 row(s) inserted.
1
59
0
INSERT INTO rental_history(media_id, rental_date, customer_i
1 row(s) inserted.
1
60
0.01
INSERT INTO rental_history(media_id, rental_date, customer_i
1 row(s) inserted.
1
61
0
INSERT INTO rental_history(media_id, rental_date, customer_i
1 row(s) inserted.
1
62
0.01
CREATE INDEX ctr_lat_nae_idx  on customers(last_name)
Index created.
0
63
0
CREATE  SYNONYM tu FOR title_unavail
Synonym created.
0


01 Working with DDL Statements - Output

DESC rental_history;

DESCRIBE customers;

DESCRIBE media;

DESCRIBE star_billings;


DESC movies;

DESC actors;




02_ Creating and Managing Constraints- Output

SELECT chld.table_name "Subject", chldcols.column_name "Subject Column Name", chld.constraint_name "constraint_name in Subject",  chld.constraint_type  "constraint_type in Subject", chld.search_condition  "search_condition in Subject", prnt.table_name "Parent of FK",  prntcols.column_name "Parent's Column Name", prnt.constraint_name "Parent PK"
FROM user_constraints chld LEFT OUTER JOIN user_constraints prnt ON  chld.r_constraint_name = prnt.constraint_name
LEFT OUTER JOIN user_cons_columns chldcols ON chld.constraint_name = chldcols.constraint_name
LEFT OUTER JOIN user_cons_columns prntcols ON prnt.constraint_name = prntcols.constraint_name
WHERE chld.table_name = UPPER('table_name');
ACTORS:

MOVIES:

STAR_BILLINGS:

MEDIA:

CUSTOMERS:

RENTAL_HISTORY:

03_ Creating and Managing Views-Output

(After 5. Add the data to the tables.)

SELECT * FROM title_unavail;



04_ Working with Sequences (Indexes and Synonyms)-Output

Output of  SELECT * FROM user_sequences WHERE sequence_name = UPPER('squence_name');

·         Use a sequence to generate PKs for CUSTOMER_ID in CUSTOMERS table Begin at 101 and increment by 1
CREATE SEQUENCE customer_id_seq
START WITH 101;

·         Use a sequence to generate PKs for TITLE_ID in MOVIES table Begin at 1 and increment by 1
CREATE SEQUENCE title_id_seq;


·         Use a sequence to generate PKs for MEDIA_ID in MEDIA table Begin at 92 and increment by 1
CREATE SEQUENCE media_id_seq
START WITH 92;


·         Use a sequence to generate PKs for ACTOR_ID in ACTOR table Begin at 1001 and increment by 1
CREATE SEQUENCE actor_id_seq
START WITH 1001;





5. Add the data to the tables. Be sure to use the sequences for the PKs.



SELECT * FROM actors;




SELECT * FROM movies;










SELECT * FROM star_billings;

SELECT * FROM media;



SELECT * FROM customers;




SELECT * FROM rental_history;



6. Create an index on the last_name column of the Customers table. 


SELECT ucm.index_name, ucm.column_name, ucm.column_position, uix.uniqueness
FROM user_indexes uix INNER JOIN user_ind_columns ucm ON uix.index_name = ucm.index_name
WHERE ucm.table_name = 'CUSTOMERS' AND ucm.column_name = 'LAST_NAME' ;




7. Create a synonym called TU for the TITLE_UNAVAIL view.


Note: I didn’t have privileges to create public synonym:
ORA-01031: insufficient privileges
So I created private
SELECT * FROM tu;


SELECT * FROM user_synonyms WHERE table_NAME = UPPER('title_unavail');


Sunday, November 20, 2016

49 Ensuring Quality Query Results– Advanced Technique


1. Create additional tables used in this section by executing the following statements:

CREATE TABLE emp AS SELECT * FROM employees;
CREATE TABLE dept AS SELECT * FROM departments;
CREATE TABLE emp
AS ( SELECT * FROM employees);

CREATE TABLE dept
AS ( SELECT * FROM departments);

DESCRIBE table_name;






SELECT chld.table_name "Subject", chldcols.column_name "Subject Column Name", chld.constraint_name "constraint_name in Subject",  chld.constraint_type  "constraint_type in Subject",  prnt.table_name "Parent of FK",  prntcols.column_name "Parent's Column Name", prnt.constraint_name "Parent PK"
FROM user_constraints chld LEFT OUTER JOIN user_constraints prnt ON  chld.r_constraint_name = prnt.constraint_name
LEFT OUTER JOIN user_cons_columns chldcols ON chld.constraint_name = chldcols.constraint_name
LEFT OUTER JOIN user_cons_columns prntcols ON prnt.constraint_name = prntcols.constraint_name
WHERE chld.table_name = UPPER('table_name');




So, only not null constraints travel through with copy.

SELECT * FROM table_name;
Data is copied well though.
2.  Produce a report that lists the constraint name, type, column name, and column position of all the constraints on the JOB_HISTORY table, apart from the not null constraints.
I have to show rows related to all constraints including CHECK constraints, except the one which are NOT NULL constraints.
Difference between NOT NULL constraint and check constraint is going to be tricky here. I could very well create a CHECK constraint with search condition e.g. "EMPLOYEE_ID" IS NOT NULL to achieve my business goal. But, problem says specifically, exclude not null constraint, but include check/pk/fk constraint.
 Given that search_condition of user_constraints is a long in oracle as of today.  Some errors I got under obvious implementations (e.g. using WITH clause, instead of  my_temp_table  use subquery, trying to convert long to desired formats for comparisons etc.) :
ORA-00932: inconsistent datatypes: expected - got LONG
ORA-00932: inconsistent datatypes: expected CHAR got LONG
ORA-00997: illegal use of LONG datatype
Etc. Finally: Execute all 3 SQL statements

CREATE TABLE my_temp_table AS
(SELECT cons.constraint_name, cons.constraint_type,
cols.column_name, cols.position,
TO_LOB(cons.search_condition)  search_condition
FROM  user_constraints cons
INNER JOIN user_cons_columns cols
ON cons.constraint_name = cols.constraint_name
WHERE cons.table_name = 'JOB_HISTORY' );

SELECT * FROM my_temp_table
WHERE NOT (
constraint_type = 'C'
AND  column_name in
(SELECT column_name FROM user_tab_columns
 WHERE table_name = UPPER('job_history')
 AND nullable = 'N')
AND DBMS_LOB.COMPARE(search_condition,
 CONCAT('"', CONCAT(column_name, '" IS NOT NULL'))) = 0);

All other constraints except JHIST_EMPLOYEE_NN, JHIST_START_DATE_NN, JHIST_END_DATE_NN and JHIST_JOB_NN which are the NOT NULL constraints are returned by above statement:

If I want to display only NULL constraints here, I will remove NOT in above SELECT statement.
If I want to display all constraints including NOT NULL then I will remove WHERE clause.
Please note, a constraint which uses two columns, is coming twice here, since problem also mentioned to display position
DROP TABLE my_temp_table PURGE;

Edit:  There is another way to target this Problem 2 which doesn’t need creating and dropping a temp table:
a)      Create a function which gives search_condition as varchar2(4000):
CREATE OR REPLACE FUNCTION getsearchcondition( p_constraint_name in varchar2)
return varchar2 as l_cursor integer default dbms_sql.open_cursor;
l_n number;
l_long_val varchar2(4000);
l_long_len number;
l_buflen number := 4000;
l_curpos number := 0;
begin
dbms_sql.parse( l_cursor, 'SELECT search_condition FROM user_constraints WHERE constraint_name = :x', dbms_sql.native );
dbms_sql.bind_variable( l_cursor, ':x', p_constraint_name );
dbms_sql.define_column_long(l_cursor, 1);
l_n := dbms_sql.execute(l_cursor);
if (dbms_sql.fetch_rows(l_cursor)>0)
then
dbms_sql.column_value_long(l_cursor, 1, l_buflen, l_curpos ,l_long_val, l_long_len );
end if;
dbms_sql.close_cursor(l_cursor);
return l_long_val;
end getsearchcondition;





b)
WITH
subquery1 AS
(SELECT cons.constraint_name, cons.constraint_type,
cols.column_name, cols.position,
getsearchcondition(cons.constraint_name)  search_condition
FROM  user_constraints cons
INNER JOIN user_cons_columns cols
ON cons.constraint_name = cols.constraint_name
WHERE cons.table_name = 'JOB_HISTORY' ),
subquery2 AS
(
SELECT column_name FROM user_tab_columns
 WHERE table_name = UPPER('job_history')
 AND nullable = 'N'
)
SELECT * FROM (SELECT * FROM subquery1 )
WHERE NOT (
constraint_type = 'C'
AND  column_name in
(SELECT * FROM subquery2)
AND search_condition = CONCAT('"', CONCAT(column_name, '" IS NOT NULL')) );

This second method [includes two steps a) and b) mentioned above] seems to be cleaner approach with same valid results.

3.  Create a primary key constraint on the emp table’s employee_id column
ALTER TABLE emp
ADD  CONSTRAINT emp_employee_id_pk PRIMARY KEY (employee_id);
SELECT constraint_name, constraint_type, table_name, status, index_name  FROM user_constraints  WHERE table_name = UPPER('emp') AND constraint_type = 'P';

4.  Create a primary key on the dept table’s department_id column
ALTER TABLE dept
ADD  CONSTRAINT dept_department_id_pk PRIMARY KEY (department_id);
SELECT constraint_name, constraint_type, table_name, status, index_name  FROM user_constraints  WHERE table_name = UPPER('dept') AND constraint_type = 'P';

5.  Add a foreign constraint between DEPT and EMP so that only valid departments can be entered in the EMP table. Make sure you can delete any row from the DEPT table, and that referenced rows in the EMP table are deleted.
ALTER TABLE  emp ADD CONSTRAINT emp_dept_department_id_fk FOREIGN KEY (department_id)
REFERENCES  dept (department_id) ON DELETE CASCADE;

SELECT chld.table_name "Subject", chldcols.column_name "Subject Column Name", chld.constraint_name "constraint_name in Subject",  chld.constraint_type  "constraint_type in Subject",  chld.delete_rule  "delete_rule in Subject", prnt.table_name "Parent Table",  prntcols.column_name "Parent table Column Name", prnt.constraint_name "Parent PK"
FROM user_constraints chld LEFT OUTER JOIN user_constraints prnt ON  chld.r_constraint_name = prnt.constraint_name
LEFT OUTER JOIN user_cons_columns chldcols ON chld.constraint_name = chldcols.constraint_name
LEFT OUTER JOIN user_cons_columns prntcols ON prnt.constraint_name = prntcols.constraint_name
WHERE chld.table_name = UPPER('emp') AND chld.constraint_type = 'R' AND chldcols.column_name = UPPER('department_id') ;


Verification:
SELECT * FROM dept WHERE department_id = 20;

SELECT * FROM emp WHERE department_id = 20;



If same action done on original departments table:


But in dept where ON DELETE CASCADE is used:
DELETE FROM dept WHERE department_id = 20;



6.  Test the foreign key constraint you just created:
Count the number of rows in the EMP table.
SELECT COUNT(*) FROM emp;

Remove department 10 from the dept table.
DELETE FROM dept WHERE department_id = 10;

Now count emps again. There should be fewer employees.

7.  Produce a report that returns the last name, salary, department number, and average salary of all the departments where salary is greater than the average salary.

Produce a report that returns the last name, salary, department number, and average salary of all the departments where salary is greater than the average salary.

I target first the phrase "average salary of all the departments":
·         I assume that I have to consider employees having no department; I assume department_id as -1 where, there is no department_id mentioned.
·         Also, AVG skips null salaries; it's very unfair and will like to include nulls as zero.
SELECT NVL(department_id, -1) dpt_idAVG(NVL(salary,0)) avg_sal FROM employees
GROUP BY NVL(department_id, -1);

Now I target "where salary is greater than the average salary"
It seems to me, I have to print the employees in a department, if the salary is greater than average of their department.

WITH avg_sal_by_dept AS
(SELECT NVL(department_id, -1) dpt_id,  AVG(NVL(salary,0)) avg_sal FROM employees
GROUP BY NVL(department_id, -1))

SELECT emp.last_name "last name", TO_CHAR(ROUND(emp.salary,2),'$999999.99') "salary",  CASE WHEN avgqry.dpt_id = -1 THEN NULL ELSE avgqry.dpt_id END  "department number", TO_CHAR(ROUND(avgqry.avg_sal,2),'$999999.99')  "average salary"
FROM employees emp INNER JOIN (SELECT * FROM avg_sal_by_dept) avgqry ON NVL(emp.department_id, -1) = avgqry.dpt_id
WHERE emp.salary > avgqry.avg_sal;



8.  Create a view named V2 that returns the highest salary, lowest salary, average salary and department name.
This problem is same as Creating Views > Problem 6

Included null salaries in avg/max calculations.
Included a department name even if there is no employee for this.
Excluded the employee with null department_id.

CREATE OR REPLACE VIEW v2 ("highest salary", "lowest salary", "average salary", "Department Name") AS
SELECT 
TO_CHAR(ROUND(MAX(NVL(emp.salary,0)),2),'$999999.99'),
TO_CHAR(ROUND(MIN(NVL(emp.salary,0)),2),'$999999.99'),
TO_CHAR(ROUND(AVG(NVL(emp.salary,0)),2),'$999999.99'),  dpt.department_name
FROM departments dpt LEFT OUTER JOIN employees emp ON dpt.department_id = emp.department_id
GROUP BY (dpt.department_id, dpt.department_name);

SELECT * FROM v2;

.

9.  Create a view named Dept_Managers_view that returns a listing of department names long with the manager initial and surname for that department. Test the view by returning all the rows from it. Make sure no rows can be updated through the view. Try to run an UPDATE statement against the view.

Ideally manager of an employee should have been in the same department as the employee. And I should have been using Hierarchical Queries to get the top most employees in a department to be termed as super manager.
SELECT emp.employee_id employeeid, mgr.employee_id managerid
FROM employees emp LEFT OUTER JOIN employees mgr ON emp.manager_id = mgr.employee_id
WHERE emp.department_id != mgr.department_id;
Suggests, this is not true.
Let’s assume definition of managers as given in Correlated Subqueries > Problem 3
"employees who have at least one person reporting to them"
So this problem has just one more addition on the top of Correlated Subqueries > Problem 3, join with departments for department name.
Let’s do it with join instead of subquery (Correlated Subqueries > Problem 3)
manager initial means first character of firt name + first character of last name. First name is nullable
CREATE OR REPLACE VIEW dept_managers_view  AS
SELECT DISTINCT SUBSTR(NVL(mgr.first_name, '_'),1, 1) || SUBSTR(mgr.last_name,1, 1) initials,   mgr.last_name surname, dpt.department_name
FROM
employees mgr INNER JOIN employees emp ON mgr.employee_id = emp.manager_id
LEFT OUTER JOIN departments dpt ON mgr.department_id = dpt.department_id;
I used left outer join here to include managers with null department also.
SELECT * FROM Dept_Managers_view ;

As per "DML Operations and Views”, since view has DISTINCT keyword, DML operations can't be done on it.

UPDATE dept_managers_view 
SET surname = 'Kumar' WHERE department_name = ‘Sales';

ORA-01732: data manipulation operation not legal on this view



10.  Create a sequence named ct_seq using all the default values.
CREATE SEQUENCE ct_seq ;

SELECT * FROM user_sequences WHERE sequence_name = UPPER('ct_seq');


11.  Examine the following insert statement and fix the errors.
INSERT INTO emp
(employee_id, first_name, last_name, email, phone_number, hire_date,
job_id, salary, commission_pct, manager_id, department_id)
VALUES
(ct_seq.nextvalue, "Kaare", 'Hansen', 'KHANSEN', '44965 832123',
sysdate, 'SA_REP', $6500, null, 100, 20);

INSERT INTO dept (department_id, department_name, manager_id, location_id)
VALUES (20, 'Marketing', 201, 1800);
INSERT INTO emp
(employee_id, first_name, last_name, email, phone_number, hire_date,
job_id, salary, commission_pct, manager_id, department_id)
VALUES
(ct_seq.NEXTVAL, 'Kaare', 'Hansen', 'KHANSEN', '44965 832123',
sysdate, 'SA_REP', 6500, null, 100, 20);

ORA-00911: invalid character
ORA-00984: column not allowed here
ORA-00984: column not allowed here
ORA-02291: integrity constraint (HKUMAR.EMP_DEPT_DEPARTMENT_ID_FK) violated - parent key not found

12.  Write the SQL statement to list all the user tables which contains the name PRIV.
DESCRIBE  user_tables;
SELECT * FROM user_tables WHERE table_NAME like '%PRIV%';
SELECT * FROM user_tables WHERE  REGEXP_LIKE(table_NAME, '(PRIV)');
SELECT * FROM all_tables WHERE REGEXP_LIKE(table_name, '(PRIV)');
first attempt:
ORA-07455: estimated execution time (86 secs), exceeds limit (60 secs)
Second attempt:


13.  Give select access to public on the EMP table, and verify the grant by running this query.
SELECT *
FROM user_tab_privs
WHERE table_name = 'EMP';

GRANT SELECT ON emp to PUBLIC;

14.  Replace the ?? in the following query using regular expressions to return only the numbers from the following string: 'Oracle Academy9547d6905%&^ db apex'.
SELECT REGEXP_REPLACE('Oracle Academy9547d6905%&^ db apex',??,'') regexpreplace
FROM DUAL;

SELECT REGEXP_REPLACE('Oracle Academy9547d6905%&^ db apex','[^[:digit:]]','') regexpreplace
FROM DUAL;
95476905
SELECT REGEXP_REPLACE('Oracle Academy9547d6905%&^ db apex','[^0-9]','') regexpreplace
FROM DUAL;
95476905

15.  Amend the previous query using regular expressions to return the number of digits from the following string: 'Oracle Academy9547d6905%&^ db’
SELECT LENGTH(REGEXP_REPLACE('Oracle Academy9547d6905%&^ db apex','??','')) regexpreplace
FROM DUAL;
SELECT LENGTH(REGEXP_REPLACE('Oracle Academy9547d6905%&^ db apex','[^[:digit:]]','')) regexpreplace
FROM DUAL;
8
16.  Amend the query again to return only the non-numeric characters.
SELECT REGEXP_REPLACE('Oracle Academy9547d6905%&^ db apex','??','') regexpreplace
FROM DUAL;
SELECT REGEXP_REPLACE('Oracle Academy9547d6905%&^ db apex','[[:digit:]]','') regexpreplace
FROM DUAL;
Oracle Academyd%&^ db apex
SELECT REGEXP_REPLACE('Oracle Academy9547d6905%&^ db apex','[0-9]','') regexpreplace
FROM DUAL;
Oracle Academyd%&^ db apex
17.  Using Oracle proprietary joins, construct a statement that returns all the employee_ids joined to all the department_names.
Seems to be this problem wants Cartesian Product: listing all the possible matches
SELECT em.employee_id, dp.department_name
FROM employees em, departments dp;

18.  Still using Oracle Joins, correct the previous statement so that it returns only the name of the department that the employee actually works in.
Seems to be problem wants oracle proprietary equi join equivalent to INNER JOIN
SELECT em.employee_id, dp.department_name
FROM employees em, departments dp
WHERE em.department_id = dp.department_id;

19.  Still using Oracle Joins, construct a query that lists the employees last name, the department name, the salary, and the country name of all employees.
After reading next problem, seems to be problem just wants to stick to equi join equivalent to INNER JOIN for employees and departments, seems to be part of normal problems flow. But for other table combinations I will follow common sense:
For departments location_id is nullable
For locations country_id is nullable
So left outer join in both cases

SELECT em.last_name "last name", dp.department_name "department name",em.salary, con.country_name "country name"
FROM employees em, departments dp, locations loc, countries con
WHERE em.department_id = dp.department_id
AND
dp.location_id = loc.location_id(+)
AND
loc.country_id = con.country_id(+)





20.  Still using Oracle join syntax, alter the previous query so that it also includes the employee record of the employee with no department_id, ‘Grant’.
So just need to do long awaited left outer join for employees, departments combination too ( department_id is nullable in employees table, so this make sense too)
SELECT em.last_name "last name", dp.department_name "department name",em.salary, con.country_name "country name"
FROM employees em, departments dp, locations loc, countries con
WHERE em.department_id = dp.department_id(+)
AND
dp.location_id = loc.location_id(+)
AND


loc.country_id = con.country_id(+);