Please send questions to
st10@humboldt.edu .
--
-- 315lab12-projected.sql
--
-- last modified: 11-10-10 (during lab)
-- uncomment if needed -- should already have these tables in your
-- database, though
--
-- @ set-up-ex-tbls
-- SET UP for WEEK 12 LAB EXERCISE:
-- * ssh to nrs-labs
-- * mkdir 315lab12
-- * chmod 700 315lab12
-- * cd 315lab12
-- * nano lab12.sql
-- * ...and start up today's lab script with:
-- * comments containing your name, Week 12 lab, today's date
-- * also spool on and spool off commands:
-- spool lab12-results.txt
-- spool off
-- REMEMBER: put the queries for today's lab exercise
-- IN BETWEEN the spool and spool off commands!
spool lab12-results.txt
--***********************************
-- SQL*LOADER
--***********************************
-- SQL*Loader is a program that comes with the Oracle DBMS
-- to import data from files into database tables;
-- three SIMPLE examples, look at Google/Oracle doc for more!
-- basically: you set up a .ctl (control) file for SQL*Loader,
-- that says WHERE the data is and HOW to handle it
-- and WHERE to put it,
-- and then run SQL*Loader program with that control file
-- and (possibly) data files
-- consider: the empltemp example (the 4 empltemp files)
-- also consider: the painter example: using a sequence and SQL*Loader
-- in conjunction;
-----
-- QUICK sqlldr additional tidbits:
-- * using sequences and sqlldr together
-- * host and sqlldr
-----
-- want to use sequences AND sqlldr? It can be done!
-- make a new copy of the painter table:
drop table painter cascade constraints;
create table painter
(ptr_num char(3),
ptr_lname varchar2(30) not null,
ptr_fname varchar2(15),
primary key (ptr_num)
);
drop table painting cascade constraints;
create table painting
(ptg_title varchar2(30),
ptr_num char(3),
primary key (ptg_title),
foreign key (ptr_num) references painter
);
-- here's the painter sequence, in case you have deleted it or something:
drop sequence painter_seq;
create sequence painter_seq
increment by 2
start with 100;
-- and here are the initial rows:
insert into painter
values
(painter_seq.nextval, 'Van Gogh', 'Vincent');
insert into painter
values
(painter_seq.nextval, 'Monet', 'Claude');
insert into painter
values
(painter_seq.nextval, 'Da Vinci', 'Leonardo');
select *
from painter;
-- see painter.ctl and painter.dat to now see how you can now use sqlldr and
-- sequences together;
-- note that the host SQL*Plus command opens up a new OS shell, and puts you
-- in it; (when you exit the shell, you are back in your SQL*Plus session)
-- host with an OS command after it just executes that one OS command in the
-- new shell, but you then you come right back to your SQL*Plus session;
-- why mention this now?
-- ...because you type sqlldr at the OS prompt, NOT within SQL*Plus;
-- ...but you can have the sqlldr command in a script IF you precede it with
-- host:
-- when run, you WILL need to enter your Oracle username and password
-- when prompted
host sqlldr control=painter.ctl log=painter.log
select *
from painter;
--***********************************************************---
-- VIEW examples
--***********************************************************---
---------
-- A view is a *derived* table --- data is not stored, just
-- how to GENERATE the desired information whenever the view
-- is used. (Can give someone a specific "picture", or view,
-- of certain data --- BUT no update hassles!)
--------
-- create a view short_empl that JUST includes the employee's
-- name, their job_title, and their manager's employee number
-- (as for tables, it is fairly common, note, to precede these
-- with a "drop view" statement when they are in scripts that
-- might be re-run...)
drop view short_empl;
create view short_empl as
select empl_num, empl_last_name, job_title, mgr
from empl;
-- once a view is created, you can use it just like a
-- table in queries --- BUT remember, it is not REALLY a
-- table, it is "built" whenever it is referred to...
-- let's look at view short_empl:
select *
from short_empl;
-- I can now use this like ANY table in queries, note!
select empl_last_name, cust_lname
from short_empl, customer
where short_empl.empl_num = customer.empl_rep;
-- ...and can even use it to build another view...!
drop view cust_rep_display;
create view cust_rep_display as
select empl_last_name, cust_lname
from short_empl se, customer c
where se.empl_num = c.empl_rep;
select *
from cust_rep_display;
-- if you change the underlying tables, the view simply
-- reflects those changes next time it is generated:
insert into customer
values
('456789', 'Fourthly', 'Fourth', '7499', '4444 Fourth Street',
'Four Corners', 'CA', '94444', 444.44);
select *
from cust_rep_display;
--********
-- IMPORTANT SECURITY CONSIDERATION:
-- remember the grant and revoke commands? e.g.,
--
--grant select
--on painter
--to abc999, cde888, fgh777;
--
--revoke select
--on painter
--from abc999, cde888, fgh777;
--
-- Oracle won't let you protect PART of a table from access; grant
-- isn't that "fine-tuned";
-- BUT can you see that, if a user should only be able to access SOME
-- columns of a table, you COULD use a view to accomplish this:
-- 1. create a view consisting of just what it is OK for that user to see;
-- 2. grant select access to THAT user to that view, NOT the whole table
-- the view is "built" from;
--
-- See how, carefully used, this could enhance database security?
--********
-- LAB EX #1
-- drop and create a view empl_salaries that includes JUST
-- employee last names and salaries
-- THEN write a query projecting all of the "contents" of
-- that view (really computing them right then)
-- THEN write a query that projects JUST the highest
-- salary using ONLY that view
-- you can also give the columns in the view different names
-- than the columns/expressions being projected to create
-- that view
-- we'll do that in short_empl2:
drop view short_empl2;
create view short_empl2(name, "job category", manager) as
select empl_last_name, job_title, mgr
from empl;
-- see what column names appear when you look at short_empl2:
select *
from short_empl2;
-- the queries using views can be as complex as you'd like, note
-- (but you should use the column names you set up for the view)
--
-- (note the need for double quotes for the column name containing
-- a blank...! Don't use double quotes for view column names, thus,
-- unless you REALLY NEED them --- they unnecessarily complicate
-- subsequent queries!!!
-- (besides, once you have created a view, you can set up column
-- commands for that view's columns to make their headings,
-- formats, etc. as sophisticated as you'd like...)
select "job category", name
from short_empl2
order by "job category";
-- (what if you use the original table's column names, instead?)
-- THIS WILL FAIL, complaining about the invalid column name;
select "job category", empl_last_name
from short_empl2
order by "job category";
-- you can also give the columns names using column aliases in the
-- sub-select
drop view short_empl3;
create view short_empl3 as
drop view short_empl3;
create view short_empl3 as
select empl_last_name last_name, job_title position
from empl;
select position, last_name
from short_empl3
order by last_name;
-- DO CLICKER QUESTION 1 NOW;
-- another view example --- with functions,
-- you HAVE to give the column another name...
-- let's say you want a view that gives the average salary
-- per job category: let's call it salary_avgs
-- this WON'T work --- it'll complain that you need a column
-- alias for avg(salary)
drop view salary_avgs;
create view salary_avgs as
select job_title, avg(salary)
from empl
group by job_title;
-- this WILL work...
create view salary_avgs(job, salary_avg) as
select job_title, avg(salary)
from empl
group by job_title;
-- (this would work, too...:
--
--create view salary_avgs as
--select job_title, avg(salary) salary_avg
--from empl
--group by job_title;
select *
from salary_avgs;
--*****
-- now, it USED to be an error to use an "order by" clause in
-- view CREATION --- after all, it certainly doesn't make a
-- lot of sense to include it. You can always order the view
-- however you want when you display it.
-- how about this semester? is it a
-- "SQL command not properly ended" error or not?!
-- THIS IS STILL CONSIDERED POOR STYLE, HOWEVER.
drop view empl_roster;
create view empl_roster as
select empl_last_name, dept_name, dept_loc
from empl, dept
where empl.dept_num = dept.dept_num
order by dept_name;
select *
from empl_roster;
select *
from empl_roster
order by dept_loc;
-- NOT having the order-by clause is
-- better STYLE, though:
drop view empl_roster;
create view empl_roster as
select empl_last_name, dept_name, dept_loc
from empl, dept
where empl.dept_num = dept.dept_num;
-- makes more sense, anyway --- you can always display the
-- view in any order you like!
-- by dept_name...
select dept_name, empl_last_name, dept_loc
from empl_roster
order by dept_name;
-- by dept_loc...
select dept_loc, empl_last_name, dept_name
from empl_roster
order by dept_loc;
-- by empl_last_name!
select *
from empl_roster
order by empl_last_name;
-- LAB EXERCISE #2
-- drop and create a view earliest_hires that will contain 2 columns:
-- * a job title
-- * the earliest (minimum) hiredate for someone with that job title
-- THEN write a query that projects all of the "contents" of that view
-- THEN write a query that project JUST the latest (maximum) hiredate
-- of the hiredates from the earliest_hiredate view (the latest
-- of the earliests...!) (use ONLY the earliest_hiredate view)
--****************************
-- SQL*PLUS REPORTS
--****************************
-----
-- moving on to simple ASCII reports
-----
--*****
-- note: / on a line by itself means to re-run the previous
-- SQL command (not SQL*PLus command, note!)
-- so, this'll redo previous query:
/
--******************************************************---
-- first thing: it is good form to make sure that no previous
-- breaks, columns, computes are going to mess up your coming
-- report --- so clear 'em in your report script, first:
-----
clear breaks
clear columns
clear computes
-- compliments of S. Griffin: yes, this works, too!!!
clear breaks columns computes
--***********************************---
-- feedback: that little line saying how many rows were selected
-- by a query
-----
-- want to know its current value? Here's how:
show feedback
-- here's how to set the feedback to a different number:
set feedback 3
show feedback
-- this'll note that 3 rows were selected.
select *
from painter;
-- this will not note that one row was:
select *
from painter
where ptr_lname = 'Monet';
-- this will simply turn feedback OFF
set feedback off
-- when you are ready to have results written to a file, spool!
-- (commented out for lab purposes...)
-- spool report_output.txt
--***************************************************---
-- pagesize: how many lines in a "page"
-----
show pagesize
set pagesize 30
-- you can set pagesize to 0 to mean, NEVER want page breaks (when
-- you want to generate a flat file of data for another program,
-- for example
--*********************************************************---
-- linesize: how many characters are in a line
-----
show linesize
set linesize 50
--**********************************************************---
-- newpage: the number of blank lines to put before the top title
-- of a page (if any)
-----
-- (appears that each SQL select result starts on a new "page", pagesize-
-- and newpage-wise)
show newpage
set newpage 5
-----
-- can set newpage to 0 as well --- nice for creating a flat file
-- of input
-----
--*****
-- (oddly enough, the number of lines in a page is
-- pagesize + newpage...)
-- INSERT CLICKER QUESTION 2 HERE
--------
-- more on SQL*Plus/ASCII reports in Week 13 lab!
--------
-- COURSE STYLE STANDARD:
-- because this script DOES mess with some default SQL*Plus
-- settings, put 'em "back" before your script ends,
-- to avoid confusing/annoying a user who does something else
-- after running your script;
set feedback 6
set pagesize 14
set linesize 80
set newpage 1
spool off
-- end of 315lab12-projected.sql