Thursday, November 3, 2016

35 Modifying a Table

13-3: Modifying a Table

Before beginning the practice exercises, execute a DESCRIBE for each of the following tables:
o_employees, o_departments and o_jobs. These tables will be used in the exercises. If
they do not exist in your account, create them as follows:

1.  Create the three o_tables – jobs, employees, and departments – using the syntax:
CREATE TABLE o_jobs AS (SELECT * FROM jobs);
CREATE TABLE o_employees AS (SELECT * FROM employees);
CREATE TABLE o_departments AS (SELECT * FROM departments);

2.  Add the Human Resources job to the jobs table:
INSERT INTO o_jobs (job_id, job_title, min_salary, max_salary)
VALUES('HR_MAN', 'Human Resources Manager', 4500, 5500);

3.  Add the three new employees to the employees table:
INSERT INTO o_employees (employee_id, first_name, last_name, email,
hire_date, job_id)
VALUES(210, 'Ramon', 'Sanchez', 'RSANCHEZ', SYSDATE, 'HR_MAN');
INSERT INTO o_employees (employee_id, first_name, last_name, email,
hire_date, job_id)
VALUES(211, 'Ramon2', 'Sanchez2', 'RSANCHEZ2', SYSDATE, 'HR_MAN');

INSERT INTO o_employees (employee_id, first_name, last_name, email,
hire_date, job_id)
VALUES(212, 'Ramon3', 'Sanchez3', 'RSANCHEZ3', SYSDATE, 'HR_MAN');
4.  Add Human Resources to the departments table:
DESCRIBE o_departments;
INSERT INTO o_departments(department_id, department_name)
VALUES (210,'Human Resources');


You will need to know which columns do not allow null values.

1.  Why is it important to be able to modify a table?
There is nothing permanent in this world except change and I do make mistakes, that is why databases are also dynamic in nature and so are the tables could be modified.

2.  CREATE a table called Artists.

a.  Add the following to the table:
·         artist ID
·         first name
·         last name
·         band name
·         email
·         hourly rate
·         song ID from d_songs table
CREATE TABLE  artists
(artist_id NUMBER(5,0),
first_name VARCHAR2(25) CONSTRAINT ait_first_name_nn NOT NULL ENABLE,
last_name VARCHAR2(30) CONSTRAINT ait_last_name_nn NOT NULL ENABLE,
band_name VARCHAR2(30),
email VARCHAR2(75) CONSTRAINT ait_email_nn NOT NULL ENABLE,
hr_rate NUMBER(8,2) CONSTRAINT ait_hr_rate_nn NOT NULL ENABLE,
song_id NUMBER(5,0) CONSTRAINT ait_song_id_nn NOT NULL ENABLE,
CONSTRAINT ait_id_pk PRIMARY KEY (artist_id)
);
b.  INSERT one artist from the d_songs table.
DESCRIBE artists;
It suggests that,
I must have artist_id, which I could take as 1 since I am inserting one row only, please note there is no sequence present here.
First name and last name I must need, I could get it from artist in d_songs by string manipulation.
band name I may skip but I can temporarily take it same as artist full name.
song id I can take from d_songs very well.
email and hourly rate, d_songs will give no clue about, so, I will have to have two constraints:

ALTER TABLE artists
DROP CONSTRAINT ait_email_nn;
ALTER TABLE artists
DROP CONSTRAINT ait_hr_rate_nn;
DESCRIBE artists;

Now insert first select from d_songs to artists:
INSERT INTO artists (artist_id, first_name, last_name, band_name, email, hr_rate, song_id)
SELECT 1 AS artist_id,
CASE
WHEN artist IS NULL THEN 'first name unknown'
WHEN INSTR(artist,' ') = 0 THEN artist
ELSE SUBSTR(artist,1,INSTR(artist,' ') -1)
END
AS first_name,
CASE
WHEN artist IS NULL THEN 'last name unknown'
WHEN INSTR(artist,' ') = 0 THEN artist
ELSE SUBSTR(artist,INSTR(artist,' '),LENGTH(artist))
END
AS last_name,
artist as band_name,
NULL as email,
NULL as hr_rate,
id as song_id

FROM d_songs
WHERE  ROWNUM =1 ;

SELECT * FROM artists;

c.  INSERT one artist of your own choosing; leave song_id blank.
Now leaving song_id blank would require dropping another constraint or I will get error ORA-01400: cannot insert NULL into ("HKUMAR"."ARTISTS"."SONG_ID"):
ALTER TABLE artists
DROP CONSTRAINT ait_song_id_nn;
INSERT INTO artists (artist_id, first_name, last_name, band_name, email, hr_rate, song_id)
VALUES(2,'David','Gray','david''s band','some.email@somedomain.com','999999.99',NULL);
SELECT * FROM artists;

d. Give an example how each of the following may be used on the table that you have created:
1) ALTER TABLE
ALTER TABLE artists
ADD (specialty VARCHAR2(100), college VARCHAR2(100));

ALTER TABLE artists
MODIFY (specialty VARCHAR2(99), college VARCHAR2(98));

ALTER TABLE artists
DROP COLUMN specialty;

ALTER TABLE artists
RENAME COLUMN college to university;

ALTER TABLE artists
  RENAME TO artists_new_name;

ALTER TABLE artists_new_name
MODIFY (university VARCHAR2(98) DEFAULT 'Great College');

ALTER TABLE artists_new_name
SET UNUSED (university);
SELECT column_name FROM user_tab_columns WHERE LOWER(table_name) = 'artists_new_name';

ALTER TABLE artists_new_name
DROP UNUSED COLUMNS;


3) RENAME TABLE
RENAME artists_new_name TO artists_new2;

4) TRUNCATE
TRUNCATE TABLE artists_new2;
SELECT * FROM artists_new2;

5) COMMENT ON TABLE

Here I found a bug in oracle:


COMMENT ON TABLE artists_new2 IS 'The exercises are reordered to use same table, next I will drop this table';

Output: (See the message which is a bug) Application Express 5.0.3.00.03

SELECT table_name, comments
FROM user_tab_comments WHERE LOWER(table_name) = 'artists_new2';
Output:


COMMENT ON TABLE artists_new2 IS 'xxxx';
Output:


SELECT table_name, comments
FROM user_tab_comments WHERE LOWER(table_name) = 'artists_new2';



COMMENT ON COLUMN artists_new2.artist_id is 'this should be primary key I guess';

SELECT table_name, column_name,comments
FROM  user_col_comments WHERE  LOWER(table_name) = 'artists_new2' AND LOWER(column_name) = 'artist_id';


2) DROP TABLE
DROP TABLE artists_new2;

3.  In your o_employees table, enter a new column called “Termination.” The datatype for the new column should be VARCHAR2. Set the DEFAULT for this column as SYSDATE to appear as character data in the format: February 20th, 2003.

ALTER TABLE o_employees
ADD ("Termination" VARCHAR2(100)  DEFAULT  TO_CHAR(SYSDATE,'Month ddth, YYYY') );
INSERT INTO o_employees (employee_id, first_name, last_name, email, hire_date, job_id)
VALUES(213, 'Ramon213', 'Sanchez213', 'RSANCHEZ213', SYSDATE, 'HR_MAN');
SELECT "Termination" FROM o_employees WHERE employee_id = 213;

If I wanted it to be 2nd instead of  02nd:
ALTER TABLE o_employees
MODIFY ("Termination" VARCHAR2(100)  DEFAULT  TO_CHAR(SYSDATE,'fmMonth ddth, YYYY') );
INSERT INTO o_employees (employee_id, first_name, last_name, email, hire_date, job_id)
VALUES(214, 'Ramon214', 'Sanchez214', 'RSANCHEZ214', SYSDATE, 'HR_MAN');
SELECT "Termination" FROM o_employees WHERE employee_id = 214;


4.  Create a new column in the o_employees table called start_date. Use the TIMESTAMP WITH LOCAL TIME ZONE as the datatype.
ALTER TABLE o_employees
ADD (start_date TIMESTAMP WITH LOCAL TIME ZONE);
default fractional_seconds_precision is 6 here
5.  Truncate the o_jobs table. Then do a SELECT * statement. Are the columns still there? Is the data still there?
DESCRIBE o_jobs;
SELECT * FROM  o_jobs;
TRUNCATE TABLE o_jobs;
DESCRIBE o_jobs;
SELECT * FROM  o_jobs;
Columns are still there, data is gone.

6.  What is the distinction between TRUNCATE, DELETE, and DROP for tables?
The DROP TABLE statement removes the definition of oracle table along with data and indexes. Recovery of a dropped table along with even indexes may be done but it's not guaranteed using FLASHBACK:
DROP TABLE mytable;
It is possible to query what  may be restored by command:
SELECT original_name, operation, droptime
FROM user_recyclebin;
FLASHBACK TABLE mytable TO BEFORE DROP;
But if PURGE is used along with DROP TABLE, there is no recyclebin in b/w for sure:
DROP TABLE mytable PURGE;
TRUNCATE TABLE removes all rows and release storage space without possibility of rollback. It will be faster than DELETE. It won't remove columns from table.
TRUNCATE TABLE sometable;
DELETE SQL statement will remove the rows but won't clean storage space. We may use COMMIT or ROLLBACK here and DELETE triggers may also be used unlike TRUNCATE TABLE.
SELECT * FROM o_employees

WHERE employee_id = 100;

1 rows returned in 0.01 seconds

DELETE FROM o_employees
WHERE employee_id = 100;
1 row(s) deleted.

SELECT * FROM o_employees

WHERE employee_id = 100;

no data found

SELECT versions_operation, versions_starttime,  versions_endtime, employee_id, first_name, last_name, email, phone_number,hire_date,job_id,salary,commission_pct,manager_id, department_id,bonus,"Termination",start_date
FROM o_employees
VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE
WHERE employee_id = 100;
Output:

7.  List the changes that can and cannot be made to a column.
-1. Newly created column is always put at last. But select can be written to return in desired manner, so no issues.
0. Adding new column to table will always give null to pre-existing row's new field, even if, default value is assigned to new column.

1. I can increase precision of a number column.
2. In can increase length of character column.
3. I can decrease precision of number column if: it contains only nulls till now or there is no row in table. Otherwise I will get ORA-00940: invalid ALTER command
4. varchar2 can be decreased to length down to the largest value present currently in all rows.
5. Datatype can be changed altogether if all values in this column are nulls.
6. char can become varchar2 if column contain nulls or the size given is not less than any existing field for that column.
6. varchar2  can become char if column contain nulls or the size given is not less than any existing field for that column.
7. Change in default value is effective to new inserts only not the already present rows.
8. A column containing values can be dropped if this is not referenced as foreign key in further tables. Also, data values in it not recovered after column drop.
9. I can drop only one column at a time. Also, at least one column must remain, I cannot drop last column.
10. Since dropping column may take time, it does modify each row before deleting, I can use SET UNUSED command as a replacement for practical purposes and DROP UNUSED later on.
11. I can rename a column if I want.
8.  Add the following comment to the o_jobs table:
"New job description added"
View the data dictionary to view your comments.
COMMENT ON TABLE o_jobs IS 'New job description added';


SELECT table_name, comments
FROM user_tab_comments WHERE LOWER(table_name) = 'o_jobs';
9.  Rename the o_jobs table to o_job_description.
ALTER TABLE o_jobs
RENAME TO o_job_description;

RENAME o_job_description TO o_job_description2
10.  F_staffs table exercises:
a.  Create a copy of the f_staffs table called copy_f_staffs and use this copy table for the remaining labs in this lesson.
CREATE TABLE copy_f_staffs
AS ( SELECT * FROM f_staffs);
DESCRIBE f_staffs;
DESCRIBE copy_f_staffs;
SELECT * FROM f_staffs;
SELECT * FROM copy_f_staffs;

b.  Describe the new table to make sure it exists.
DESC copy_f_staffs;
c.  Drop the table.
DROP TABLE copy_f_staffs;
d.  Try to select from the table.
SELECT * FROM copy_f_staffs;

ORA-00942: table or view does not exist
e.  Investigate your recyclebin to see where the table went.
DESCRIBE user_recyclebin ;
Please note droptime is varchar2 here.
SELECT * FROM
   (SELECT * FROM user_recyclebin ORDER BY droptime DESC)
   WHERE ROWNUM <= 100;
SELECT object_name,droptime FROM user_recyclebin  WHERE LOWER(original_name) = 'copy_f_staffs';

SELECT object_name FROM user_recyclebin  WHERE LOWER(original_name) = 'copy_f_staffs' AND droptime = '2016-11-02:20:14:25';



f.  Try to select from the dropped table by using the value stored in the OBJECT_NAME column. You will need to copy and paste the name as it is exactly, and enclose the new name in “ “ (double quotes). So if the dropped name returned to you is BIN$Q+x1nJdcUnngQESYELVIdQ==$0, you need to write a query that refers to “BIN$Q+x1nJdcUnngQESYELVIdQ==$0”.
SELECT * FROM "BIN$QF30ctmEV7jgU81jFJDpGA==$0";
g.  Undrop the table.
FLASHBACK TABLE copy_f_staffs TO BEFORE DROP;
h.  Describe the table.
DESCRIBE copy_f_staffs;


11.  Still working with the copy_f_staffs table, perform an update on the table.

a.   Issue a select statement to see all rows and all columns from the copy_f_staffs table;
SELECT * FROM copy_f_staffs;
b.   Change the salary for Sue Doe to 12 and commit the change.
UPDATE copy_f_staffs
SET salary = 12
WHERE first_name = 'Sue' AND last_name = 'Doe';
c.   Issue a select statement to see all rows and all columns from the copy_f_staffs table;
SELECT * FROM copy_f_staffs;

d.   For Sue Doe, update the salary to 2 and commit the change.
UPDATE copy_f_staffs
SET salary = 2
WHERE first_name = 'Sue' AND last_name = 'Doe';
e.   Issue a select statement to see all rows and all columns from the copy_f_staffs table;
SELECT * FROM copy_f_staffs;

f.   Now, issue a FLASHBACK QUERY statement against the copy_f_staffs table, so you can see all the changes made.
SELECT versions_operation, versions_starttime,  versions_endtime, id, first_name, last_name, birthdate, salary,overtime_rate,training,staff_type,manager_id, manager_budget,manager_target
FROM copy_f_staffs
VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE
WHERE id = 12;

g.   Investigate the result of f), and find the original salary and update the copy_f_staffs table salary column for Sue Doe back to her original salary.

UPDATE copy_f_staffs
SET salary = (SELECT salary
FROM copy_f_staffs
VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE
WHERE first_name = 'Sue' AND last_name = 'Doe' AND versions_operation IS NULL AND versions_starttime IS NULL)
WHERE first_name = 'Sue' AND last_name = 'Doe';

Now,

SELECT * FROM copy_f_staffs;
SELECT versions_operation, versions_starttime,  versions_endtime, id, first_name, last_name, birthdate, salary,overtime_rate,training,staff_type,manager_id, manager_budget,manager_target
FROM copy_f_staffs
VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE


WHERE id = 12;


Wednesday, November 2, 2016

34 Using Data Types

  • ·         Allows time to be stored as an interval of years and months- INTERVAL YEAR[(x)] TO MONTH (x is optional  default is 2)
  • ·         When a column is selected in a SQL statement the time is automatically converted to the user’s timezone- TIMESTAMP [(fractional_seconds_precision)] WITH LOCAL TIME ZONE (data stored in the database is normalized to the database time zone, and the time zone offset is not stored as part of the column data. When users retrieve the data, Oracle returns it in the users' local session time zone)
  • ·         Binary large object data up to 4 gigabytes-BLOB
  • ·         Stores a time zone value as a displacement from Universal Coordinated Time or UCT- TIMESTAMP [(fractional_seconds_precision)] WITH TIME ZONE (includes a time zone offset or time zone region name in its value)
  • ·         Allows time to be stored as an interval of days to hours, minutes, and seconds- INTERVAL DAY[(x)] TO SECOND[(y)] default for x is 2 and for y is 6
  • ·         Character data up to 4 gigabytes-CLOB
  • ·         Allows the time to be stored as a date with fractional seconds- TIMESTAMP [(fractional_seconds_precision)] (It stores year, month, day, hour, minute, and second values. It also stores fractional seconds, which are not stored by the DATE datatype.)


1.  Create each of the three time-zone tables.

a.  TIMESTAMP WITH LOCAL TIME ZONE

SELECT DBTIMEZONE FROM DUAL;

SELECT SESSIONTIMEZONE FROM DUAL;


Now let’s create a table and insert a row:







CREATE TABLE time_ex3 (first_column TIMESTAMP WITH TIME ZONE,
second_column TIMESTAMP WITH LOCAL TIME ZONE);



INSERT INTO time_ex3
(first_column,
 second_column)
VALUES
(TO_TIMESTAMP_TZ('2016-11-0116:02:08.236+05:30','YYYY-MM-DDHH24:MI:SS.FFTZH:TZM'),
TO_TIMESTAMP_TZ('2016-11-0116:02:08.236+05:30','YYYY-MM-DDHH24:MI:SS.FFTZH:TZM'));
While storing first_column is stored as is, but second_column is normalized to server time.




b.  INTERVAL YEAR TO MONTH
CREATE TABLE time_ex4
(loan_duration1 INTERVAL YEAR(3) TO MONTH,
loan_duration2  INTERVAL YEAR(2) TO MONTH);
INSERT INTO time_ex4 (loan_duration1, loan_duration2 )
VALUES( INTERVAL '120' MONTH(3), INTERVAL '3-6' YEAR TO MONTH);
c.  INTERVAL DAY TO SECOND
CREATE TABLE time_ex5
(day_duration1 INTERVAL DAY(3) TO SECOND,
day_duration2  INTERVAL DAY(3) TO SECOND);
INSERT INTO time_ex5 (day_duration1, day_duration2 )
VALUES( INTERVAL '25' DAY(2), INTERVAL '4 10:30:10' DAY TO SECOND);
2.   Execute a SELECT * from each table to verify your input.

a.  TIMESTAMP WITH LOCAL TIME ZONE
Since for apex me the user’s timezone in PST ( -07.00):


SELECT * FROM time_ex3;



Now let’s execute below mentioned two statements together as a script:

ALTER SESSION SET TIME_ZONE = '-05:00';
SELECT * FROM time_ex3;



It proves that for second_column: When user retrieves the data, Oracle returns it in the users' local session time zone

b.  INTERVAL YEAR TO MONTH
SELECT TO_CHAR( SYSDATE + loan_duration1 , 'DD-Month-YYYY') AS "120 months from Now", TO_CHAR( SYSDATE + loan_duration2 , 'DD-Month-YYYY') AS "3 years 6 months from Now"
FROM time_ex4;



c.  INTERVAL DAY TO SECOND

SELECT
TO_CHAR( SYSDATE , 'DD-Month-YYYY hh:mi:ss') AS now,
 TO_CHAR( SYSDATE + day_duration1 , 'DD-Month-YYYY hh:mi:ss') AS "25 days from Now",
 TO_CHAR( SYSDATE + day_duration2 , 'DD-Month-YYYY hh:mi:ss') AS "4day10hr30min10sec from now "
FROM time_ex5;


3.  Give 3 examples of organizations and personal situations where it is important to know to which time zone a date-time value refers.
·         My team fills timesheet every Friday end of the day.  For team members in U.S. end of day time in UTC is different than team in India.
·          When client says lets schedule weekly meeting for Wednesday 8 AM, it means he is saying every Wednesday 08:00 AM in his time zone. This time is different for offshore team. Outlook must take care of this thing. And it does.

·         When there is a cricket match in India, news channel display timings in IST. To watch the match live I have to convert it to my local time zone and switch on my TV at that time.

Tuesday, November 1, 2016

33 Creating Tables


  • ·         Created and maintained by the Oracle Server and contains information about the database- Data dictionary
  • ·         A collection of objects that are the logical structures that directly refer to the data in the database- Schema
  • ·         Specifies a preset value if a value is omitted in the INSERT statement- DEFAULT
  • ·         Stores data; basic unit of storage composed of rows and columns- TABLE
  • ·         Command use to make a new table- CREATE TABLE


1.  Complete the GRADUATE CANDIDATE table instance chart. Credits is a foreign-key column referencing the requirements table.


Column Name

student_id

last_name

first_name

credits

graduation_date

Key Type

Primary key


foreign key

Nulls/Unique

NO/YES
NO/NO
NO/NO
NO/NO
YES/NO
FK Column




credits

Datatype

NUMBER

VARCHAR2

VARCHAR2

NUMBER

DATE

Length

6
75
75
6


For credits and student_id it could have been precision and scale rather mentioned here. I assume that when 6 is written for student_id it means NUMBER(6,0) and for credits NUMBER(5, 2)
2.  Write the syntax to create the grad_candidates table.

CREATE TABLE  graduate_candidates
   ( student_id NUMBER(6,0),
    last_name VARCHAR2(75) CONSTRAINT gcs_last_name_nn NOT NULL ENABLE,
 first_name VARCHAR2(75) CONSTRAINT gcs_first_name_nn NOT NULL ENABLE,
 credits NUMBER(5,2) CONSTRAINT gcs_credits_nn NOT NULL ENABLE,
graduation_date DATE,
 CONSTRAINT gcs_std_id_pk PRIMARY KEY (student_id),
 CONSTRAINT gcs_req_fk FOREIGN KEY(credits) REFERENCES requirements(credits) ENABLE     
   
  );
Note: Since there is no requirements table already existing for foreign key above stamen will fail. I may create this table if choose not to include this constraint.

3.  Confirm creation of the table using DESCRIBE.
DESCRIBE graduate_candidates;

4.  Create a new table using a subquery. Name the new table your last name -- e.g., smith_table. Using a subquery, copy grad_candidates into smith_table.
Even if the foreign key world have been created in problem 2, it would have been lost here in copy.
CREATE TABLE kumar_table
AS ( SELECT * FROM graduate_candidates);
see if copy worked well:
DESCRIBE kumar_table;
student_id is nullable and not a primary key here in kumar_table.

5.  Insert your personal data into the table created in question 4.
INSERT INTO kumar_table (student_id, last_name, first_name, credits, graduation_date)
Values(10,'kumar','he',999.99,NULL);
SELECT LENGTH(credits) FROM kumar_table WHERE student_id = 10;
6.  Query the data dictionary for each of the following:
• USER_TABLES
• USER_OBJECTS
• USER_CATALOG or USER_CAT
In separate sentences, summarize what each query will return.

--USER_TABLES describes the relational tables owned by the current user. Its columns (except for OWNER) are the same as those in ALL_TABLES.
SELECT * FROM user_tables;
48 rows returned in 0.64 seconds



--USER_CATALOG lists indexes, tables, views, clusters, synonyms, and sequences owned by the current user. Its columns are the same as those in "ALL_CATALOG".
SELECT * FROM user_catalog;
407 rows returned in 0.05 seconds
SELECT DISTINCT(table_type) FROM user_catalog;
3 rows returned in 0.02 seconds        

--USER_OBJECTS describes all objects owned by the current user. Its columns are the same as those in "ALL_OBJECTS".
SELECT * FROM user_objects;
117 rows returned in 0.19 seconds
SELECT DISTINCT(object_type) FROM user_objects;
6 rows returned in 0.17 seconds        


SELECT * FROM user_cat;
ORA-00942: table or view does not exist

32 DEFAULT Values, MERGE, and Multi-Table Inserts



1.  When would you want a DEFAULT value?
-If no value is given while row creation and I want the field to take some predefined value. For example there may be a created on column, and I want that when a row is created, it gets filled up with current time.

2.  Currently, the Global Foods F_PROMOTIONAL_MENUS table START_DATE column does not have SYSDATE set as DEFAULT. Your manager has decided she would like to be able to set the starting date of promotions to the current day for some entries. This will require three steps:
a.  In your schema, Make a copy of the Global Foods F_PROMOTIONAL_MENUS table using the following SQL statement:
CREATE TABLE copy_f_promotional_menus
AS (SELECT * FROM f_promotional_menus)

b.  Alter the current START_DATE column attributes using:
ALTER TABLE copy_f_promotional_menus
MODIFY(start_date DATE DEFAULT SYSDATE)

c.  INSERT the new information and check to verify the results.
INSERT a new row into the copy_f_promotional_menus table for the manager’s new promotion. The promotion code is 120. The name of the promotion is ‘New Customer.’ Enter DEFAULT for the start date and '01-Jun-2005' for the ending date. The giveaway is a 10% discount coupon. What was the correct syntax used?

As a standard rule, we are doing all operations on copy tables rather than screwing original tables.
a. So first I will create a copy table:
CREATE TABLE copy_f_promotional_menus
AS ( SELECT * FROM f_promotional_menus);
DESCRIBE f_promotional_menus;
DESCRIBE copy_f_promotional_menus;
SELECT * FROM f_promotional_menus;
SELECT * FROM copy_f_promotional_menus;
SELECT TO_CHAR(TRUNC(start_date), 'dd-mm-yyyy-hh24:mi:ss'),TO_CHAR(start_date, 'dd-mm-yyyy-hh24:mi:ss')  FROM copy_f_promotional_menus;
SELECT TO_CHAR(TRUNC(sysdate), 'dd-mm-yyyy-hh24:mi:ss') FROM dual;

b. Give default vale to start_date:
ALTER TABLE copy_f_promotional_menus
MODIFY(start_date DATE DEFAULT TRUNC(SYSDATE));

c.1 Out of existing rows, say he wants to set start_date to current date for the rows where start_date is 10-Feb-2004
Set to starting of today:

UPDATE  copy_f_promotional_menus
SET start_date = TRUNC(SYSDATE)
WHERE   TRUNC(start_date) =    TO_DATE('10-Feb-2004','dd-Mon-yyyy');

c.2 For new rows, simply skip giving any value to this field or say DEFAULT:

INSERT INTO copy_f_promotional_menus(code,name,start_date,end_date,give_away)
VALUES('115','Back to School part 2',DEFAULT,NULL,'ballpen and highlighter again');
or
INSERT INTO copy_f_promotional_menus(code,name,end_date,give_away)
VALUES('116','Back to School part 3',NULL,'ballpen and highlighter again2');

INSERT INTO copy_f_promotional_menus(code,name,start_date,end_date,give_away)
VALUES('120','New Customer',DEFAULT,TO_DATE('01-Jun-2005','dd-Mon-yyyy'),' 10% discount coupon');

3.  Allison Plumb, the event planning manager for DJs on Demand, has just given you the following list of CDs she acquired from a company going out of business. She wants a new updated list of CDs in inventory in an hour, but she doesn’t want the original D_CDS table changed. Prepare an updated inventory list just for her.

a.  Assign new cd_numbers to each new CD acquired.
It seems to be, this cd_number assignment is being done manually, I need not create a sequence for this. If the sequence had to be created, this point would have come after point b below, original table don’ have a sequence on this column.
b.  Create a copy of the D_CDS table called manager_copy_d_cds. What was the correct syntax used?
CREATE TABLE manager_copy_d_cds
AS ( SELECT * FROM d_cds);
DESCRIBE d_cds;
DESCRIBE manager_copy_d_cds;
SELECT * FROM d_cds;
SELECT * FROM manager_copy_d_cds;
c.  INSERT into the manager_copy_d_cds table each new CD title using an INSERT statement. Make up one example or use this data:
20, 'Hello World Here I Am', 'Middle Earth Records', '1998'
What was the correct syntax used?
INSERT INTO manager_copy_d_cds(cd_number,title,producer,year)
VALUES(20,'Hello World Here I Am','Middle Earth Records','1998');

INSERT INTO manager_copy_d_cds(cd_number,title,producer,year)
VALUES(97,'Celebrate the Day','R & B Inc.','2003');

INSERT INTO manager_copy_d_cds(cd_number,title,producer,year)
VALUES(99,'Party Music','Old Town Records','2004');

INSERT INTO manager_copy_d_cds(cd_number,title,producer,year)
VALUES(100,'Best of Rock and Roll','Old Town Records','2004');

SELECT * FROM manager_copy_d_cds ;
d.  Use a merge statement to add to the manager_copy_d_cds table, the CDs from the original table. If there is a match, update the title and year. If not, insert the data from the original table. What was the correct syntax used?
To verify merge, first
i) I need to edit some record in manager_copy_d_cds, this should get updated from d_cds to original value.

UPDATE manager_copy_d_cds
SET title = 'hkumar'
WHERE cd_number = 90;

ii) I should delete some record in manager_copy_d_cds which is present in d_cds. This should be recreated after merge.

DELETE FROM manager_copy_d_cds
WHERE cd_number = 91;

SELECT * FROM manager_copy_d_cds ;

MERGE INTO manager_copy_d_cds tgt USING d_cds src
ON (src.cd_number = tgt.cd_number)
WHEN MATCHED THEN UPDATE
SET  tgt.title = src.title, tgt.producer = src.producer, tgt.year = src.year
WHEN NOT MATCHED THEN INSERT
VALUES (src.cd_number, src.title, src.producer, src.year);

If () is missing I will get: ORA-00969: missing ON keyword

SELECT * FROM manager_copy_d_cds ;

4.  Run the following 3 statements to create 3 new tables for use in a Multi-table insert statement. All 3 tables should be empty on creation, hence the WHERE 1=2 condition in the WHERE clause.
CREATE TABLE sal_history (employee_id, hire_date, salary)
AS SELECT employee_id, hire_date, salary
FROM employees
WHERE 1=2;
CREATE TABLE mgr_history (employee_id, manager_id, salary)
AS SELECT employee_id, manager_id, salary
FROM employees
WHERE 1=2;
CREATE TABLE special_sal (employee_id, salary)
AS SELECT employee_id, salary
FROM employees
WHERE 1=2;
Once the tables exist in your account, write a Multi-Table insert statement to first select the employee_id, hire_date, salary, and manager_id of all employees. If the salary is more than 20000 insert the employee_id and salary into the special_sal table. Insert the details of employee_id, hire_date, and salary into the sal_history table. Insert the employee_id, manager_id, and salary into the mgr_history table.
You should get a message back saying 39 rows were inserted. Verify you get this message and verify you have the following number of rows in each table:

Sal_history: 19 rows
Mgr_history: 19 rows
Special_sal: 1

If I use FISRT / ALL no difference, since there is only one ‘WHEN’ I am using. In else there are 2 inserts.
INSERT FIRST
WHEN salary > 20000 THEN
INTO special_sal
VALUES(employee_id, salary)
ELSE
INTO sal_history
VALUES(employee_id, hire_date, salary)
INTO mgr_history
VALUES(employee_id, manager_id, salary)

SELECT employee_id, salary, hire_date, manager_id
FROM employees;
39 row(s) inserted.
SELECT COUNT(*) FROM special_sal;
1
SELECT COUNT(*) FROM sal_history;
19
SELECT COUNT(*) FROM mgr_history;

19