Distributed Database Applications COSC 5050 Week Three

advertisement
Distributed Database
Applications
COSC 5050
Week Three
Outline
Cursors and data retrieval
Procedures
Functions
Parameters
Sequences
Distributed Database Applications
Jiangping Wang
Cursors and Data Retrieval
PL/SQL integrates with the Oracle database
System Global Area (SGA)
Private working area for SQL statement
Cursor
To query data from the database and make
that data available within PL/SQL programs
Implicit cursor
Explicit cursor
Cursor variable
Distributed Database Applications
Jiangping Wang
Cursor
Cursor is a pointer into a virtual table in
the database
CURSOR employee_cur IS
SELECT fname, lname FROM employee;
OPEN employee_cur;
FETCH employee_cur INTO employee_rec;
CLOSE employee_cur;
Distributed Database Applications
Jiangping Wang
Cursor Fetch Operation
Distributed Database Applications
Jiangping Wang
Cursor
create or replace procedure cursor_employee
is
CURSOR employee_cur IS
SELECT fname, lname
FROM employee
WHERE ssn = '600000001';
employee_rec employee_cur%rowtype;
begin
OPEN employee_cur;
FETCH employee_cur INTO employee_rec;
dbms_output.put_line(
employee_rec.fname || ' ' ||employee_rec.lname);
CLOSE employee_cur;
end;
/
Distributed Database Applications
Jiangping Wang
Cursor Attributes
Page 468
cursor_name%attribute_name
%FOUND
Status of fetch operation
True if fetch succeeded
%NOTFOUND
Opposite of %FOUND
%ROWCOUNT
Number of records fetched
%ISOPEN
True if the cursor is open
Distributed Database Applications
Jiangping Wang
Referencing Variables in Cursor
Identifier precedence in a cursor
Qualifying variable with proc name
Using standard naming conventions
create or replace PROCEDURE adjust
IS
l_code NUMBER := 1000;
CURSOR double_code_cur
IS
SELECT code + l_code as adjusted
FROM employee
WHERE dept_num = 2;
employee_rec double_code_cur%rowtype;
begin
OPEN double_code_cur;
FETCH double_code_cur INTO employee_rec;
dbms_output.put_line(employee_rec.adjusted);
CLOSE double_code_cur;
END;
Distributed Database Applications
Jiangping Wang
Implicit Cursor
Use SELECT INTO
DECLARE
l_department department.dept_name%TYPE;
BEGIN
SELECT dept_name INTO l_department
FROM department
WHERE dept_num = 1;
DBMS_OUTPUT.PUT_LINE(l_department);
END;
DECLARE
l_department department%ROWTYPE;
BEGIN
SELECT * INTO l_department
FROM department
WHERE dept_num = 1;
DBMS_OUTPUT.PUT_LINE(l_department.dept_name);
END;
Distributed Database Applications
Jiangping Wang
Implicit Cursor
Error handling
With exception
Implicit SQL cursor attributes
SQL%FOUND
SQL%NOTFOUND
SQL%ROWCOUNT
SQL%ISOPEN
DECLARE
l_department department%ROWTYPE;
BEGIN
SELECT * INTO l_department
FROM department
WHERE dept_num = 3;
DBMS_OUTPUT.PUT_LINE(l_department.dept_name);
EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.PUT_LINE('No data!');
WHEN TOO_MANY_ROWS
THEN
DBMS_OUTPUT.PUT_LINE('Too many rows');
END;
/
Distributed Database Applications
Jiangping Wang
Explicit Cursor
Explicitly defined in declaration section
Complete control over open, fetch, close
CURSOR company_cur IS
SELECT company_id FROM company;
CURSOR name_cur (company_id_in IN NUMBER)
IS
SELECT name FROM company
WHERE company_id = company_id_in;
CURSOR emp_cur RETURN employee%ROWTYPE
IS
SELECT * FROM employee
WHERE department_id = 10;
Distributed Database Applications
Jiangping Wang
Explicit Cursor
Open
Fetch
Close
Explicit cursor attributes
cursor%FOUND
cursor%NOTFOUND
cursor%ROWCOUNT
cursor%ISOPEN
Distributed Database Applications
Jiangping Wang
Explicit Cursor
DECLARE
CURSOR c1 IS
SELECT fname, lname, code, code*1.1 new_code
FROM employee;
rec c1%ROWTYPE;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO rec;
EXIT WHEN c1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(
rec.fname || ' ' || rec.lname || ' ' ||
rec.code || ' ' || rec.new_code);
END LOOP;
CLOSE c1;
END;
/
Distributed Database Applications
Jiangping Wang
Explicit Cursor
DECLARE
l_dept_id NUMBER := 1;
CURSOR name_cur (dept_id_in IN NUMBER)
IS
SELECT dept_name, lname
FROM department inner join employee
on department.dept_mgr_ssn = employee.ssn
WHERE department.dept_num = dept_id_in;
name_rec name_cur%ROWTYPE;
BEGIN
OPEN name_cur(l_dept_id);
LOOP
FETCH name_cur INTO name_rec;
EXIT WHEN name_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(
name_rec.dept_name || ' ' || name_rec.lname);
END LOOP;
CLOSE name_cur;
END;
/
Jiangping Wang
Distributed Database Applications
Explicit Cursor
DECLARE
CURSOR emp_cur RETURN employee%rowtype
IS
SELECT * FROM employee WHERE dept_num = 15;
emp_rec emp_cur%ROWTYPE;
BEGIN
OPEN emp_cur;
LOOP
FETCH emp_cur INTO emp_rec;
EXIT WHEN emp_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(emp_cur%rowcount || ': ' ||
emp_rec.fname || ' ' || emp_rec.lname);
END LOOP;
CLOSE emp_cur;
END;
/
Distributed Database Applications
Jiangping Wang
Cursor Variable
Cursor variable points to or references
an underlying cursor
DECLARE
TYPE employee_curtype IS REF CURSOR
RETURN employee%ROWTYPE;
employee_curvar employee_curtype;
employee_rec employee%ROWTYPE;
BEGIN
OPEN employee_curvar FOR
SELECT * FROM employee;
FETCH employee_curvar INTO employee_rec;
CLOSE employee_curvar;
dbms_output.put_line(employee_rec.fname);
END;
/
Distributed Database Applications
Jiangping Wang
Cursor Loop
Cursor with simple loop
DECLARE
CURSOR name_cur IS
SELECT lname, fname
FROM employee WHERE ssn like '8%';
name_rec name_cur%ROWTYPE;
BEGIN
OPEN name_cur;
LOOP
FETCH name_cur INTO name_rec;
EXIT WHEN name_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(
name_rec.fname || ' ' || name_rec.lname);
END LOOP;
CLOSE name_cur;
END;
/
Distributed Database Applications
Jiangping Wang
Cursor Loop
Cursor with simple loop
DECLARE
CURSOR occupancy_cur IS
SELECT pet_id, room_number
FROM occupancy
WHERE occupied_dt = TRUNC(SYSDATE);
occupancy_rec occupancy_cur%ROWTYPE;
BEGIN
OPEN occupancy_cur;
LOOP
FETCH occupancy_cur INTO occupancy_rec;
EXIT WHEN occupancy_cur%NOTFOUND;
update_bill
(occupancy_rec.pet_id, occupancy_rec.room_number);
END LOOP;
CLOSE occupancy_cur;
END;
Distributed Database Applications
Jiangping Wang
Cursor FOR Loop
Cursor For loop
DECLARE
CURSOR occupancy_cur IS
SELECT pet_id, room_number
FROM occupancy
WHERE occupied_dt = TRUNC(SYSDATE);
BEGIN
FOR occupancy_rec IN occupancy_cur
LOOP
update_bill
(occupancy_rec.pet_id, occupancy_rec.room_number);
END LOOP;
END;
Distributed Database Applications
Jiangping Wang
Cursor FOR Loop
Cursor FOR loop
DECLARE
CURSOR name_cur IS
SELECT lname, fname
FROM employee WHERE ssn like '8%';
BEGIN
FOR name_rec IN name_cur
LOOP
DBMS_OUTPUT.PUT_LINE(
name_rec.fname || ' ' || name_rec.lname);
END LOOP;
END;
/
Distributed Database Applications
Jiangping Wang
Modular Code
PL/SQL offers the following structures
that modularize your code in different
ways
Procedure
Function
Trigger
Package
Distributed Database Applications
Jiangping Wang
Procedure
Procedure is a module that performs
one or more actions
Can be a standalone call, executable
statement
Distributed Database Applications
Jiangping Wang
Procedure
CREATE OR REPLACE
PROCEDURE get_happy (ename_in IN VARCHAR2)
 Header
IS
 Declarations
hiredate DATE;
BEGIN
hiredate:= SYSDATE – 2;
INSERT INTO employee (emp_name, hiredate)
VALUES (ename_in, hiredate);
EXCEPTION
 Code Body
* optional *
WHEN DUP_VAL_IN_INDEX THEN
DBMS_OUTPUT.PUT_LINE (‘Cannot insert.’);
 Exception block
* optional *
END get_happy;
Distributed Database Applications
Jiangping Wang
Procedure
Distributed Database Applications
Jiangping Wang
Procedure
procedure Add_employee
(ssn
in
varchar2
, fname
in
varchar2
, lname
in
varchar2
, dept_num
in
number
, code
in
number
, sup_ssn
in
varchar2)
is
begin
insert into employee values
(ssn, fname, lname, dept_num, code, sup_ssn);
end;
Distributed Database Applications
Jiangping Wang
Procedure
procedure delete_employee (tgt_ssn in varchar2)
is
cursor dept_mgr_cur (tst_ssn varchar2)
is
select dept_mgr_ssn
from department
where dept_mgr_ssn = tst_ssn;
dept_mgr_cur_ssn varchar2(9);
begin
open dept_mgr_cur(tgt_ssn);
fetch dept_mgr_cur into dept_mgr_cur_ssn;
if (dept_mgr_cur%found) then
update department set dept_mgr_ssn = NULL
where dept_mgr_ssn = tgt_ssn;
end if;
delete from employee where ssn = tgt_ssn;
close dept_mgr_cur;
end;
Distributed Database Applications
Jiangping Wang
Procedure
Calling a procedure
Procedure is called as an executable
PL/SQL statement
Called in a block
Must end with (;)
begin
apply_discount( new_company_id, 0.15 );
display_store_summary;
display_store_summary();
end;
Distributed Database Applications
Jiangping Wang
Function
Function is a module that returns a
value
Function can exist only as part of an
executable statement
Function has a datatype
Distributed Database Applications
Jiangping Wang
Function
CREATE OR REPLACE
FUNCTION soft_pillow (type_in IN VARCHAR2)
RETURN BOOLEAN
 Header
IS
CURSOR pillow_cur (type_in pillow.pillow_type%TYPE) IS
SELECT softness
FROM pillow
WHERE pillow_type = type-in;
Pillow_rec pillow_cur%ROWTYPE;
 Declarations
BEGIN
 Code Body
OPEN pillow_cur(type_in);
FETCH pillow_cur INTO Pillow_rec;
CLOSE pillow_cur;
RETURN Pillow_rec.softness;
EXCEPTION
* optional *
 Exception block
* optional *
END soft_pillow;
Distributed Database Applications
Jiangping Wang
Function
Distributed Database Applications
Jiangping Wang
Function
Defining function
create or replace function favorite_nickname(
name_in in varchar2) return varchar2
is
begin
End;
Calling function
declare
nickname varchar2(100) :=
favorite_nickname(‘Nic’);
Distributed Database Applications
Jiangping Wang
Function
create or replace function get_department(
ssn_in in employee.ssn%type)
return department.dept_name%type
is
l_dept_name department.dept_name%type;
begin
select dept_name into l_dept_name
from department inner join employee
on employee.dept_num = department.dept_num
where ssn = ssn_in;
dbms_output.put_line('department name: ' || l_dept_name);
return l_dept_name;
exception
when no_data_found then
dbms_output.put_line(
'no such employee or not in any department!');
return null;
end;
/
Distributed Database Applications
Jiangping Wang
Parameter
Be used to pass information back and
forth
Parameter declaration must be
unconstrained
DECLARE
company_name varchar2(60);
PROCEDURE display_company(
company_name IN varchar2)
IS …
Distributed Database Applications
Jiangping Wang
Parameter Mode
IN mode: Read-only
Is the default mode
Value cannot be changed
Can have default value
Passed by reference
OUT mode: Write-only
Has no value until the end
No default value
Actual parameter must be a variable
Passed by value
IN OUT mode: Read-write
Cannot have default value
Must be a variable
Passed by value
Distributed Database Applications
Jiangping Wang
Parameter
create or replace procedure delete_employee (
tgt_ssn_in in varchar2, removed_name_out out varchar2)
is
cursor dept_mgr_cur (tst_ssn varchar2)
is
select dept_mgr_ssn from department
where dept_mgr_ssn = tst_ssn;
dept_mgr_cur_ssn varchar2(9);
begin
open dept_mgr_cur(tgt_ssn_in);
fetch dept_mgr_cur into dept_mgr_cur_ssn;
if (dept_mgr_cur%found) then
update department set dept_mgr_ssn = NULL
where dept_mgr_ssn = tgt_ssn_in;
end if;
select lname into removed_name_out from employee
where ssn = tgt_ssn_in;
delete from employee where ssn = tgt_ssn_in;
close dept_mgr_cur;
end;
/
Distributed Database Applications
Jiangping Wang
Parameter
create or replace PROCEDURE combine_and_format_names
(first_name_inout IN OUT VARCHAR2,
last_name_inout IN OUT VARCHAR2,
full_name_out OUT VARCHAR2,
name_format_in IN VARCHAR2 := 'LAST, FIRST')
IS
BEGIN
first_name_inout := UPPER (first_name_inout);
last_name_inout := UPPER (last_name_inout);
IF name_format_in = 'LAST, FIRST'
THEN
full_name_out := last_name_inout || ', ' || first_name_inout;
ELSIF name_format_in = 'FIRST LAST'
THEN
full_name_out := first_name_inout || ' ' || last_name_inout;
END IF;
END;
/
Distributed Database Applications
Jiangping Wang
Oracle Sequences
Independent object in the database
Not a data type
Not tied to a table or a column
Can be used anywhere a value is expected
Generate a numeric value that can be
assigned to any column in any table
The table attribute to which you assigned a
value based on a sequence can be edited and
modified
Can be created and deleted anytime
Distributed Database Applications
Jiangping Wang
Oracle Sequences
CREATE SEQUENCE NAME [START WITH N] [INCREMENT
BY N] [CACHE | NOCACHE]
CREATE SEQUENCE CUS_CODE_SEQ START WITH 20010
NOCACHE;
CREATE SEQUENCE INV_NUMBER_SEQ START WITH 4010
NOCACHE;
SELECT * FROM USER_SEQUENCES;
DROP SEQUENCE CUS_CODE_SEQ;
DROP SEQUENCE INV_NUMBER_SEQ;
Distributed Database Applications
Jiangping Wang
Oracle Sequences
INSERT INTO CUSTOMER VALUES
(CUS_CODE_SEQ.NEXTVAL, ‘CONNERY’, ‘SEAN’, NULL,
‘615’, ‘898-2007’, 0.00);
INSERT INTO INVOICE VALUES
(INV_NUMBER_SEQ.NEXTVAL, 20010, SYSDATE);
INSERT INTO LINE VALUES
(INV_NUMBER_SEQ.CURRVAL, 1, ‘13-Q2/P2’, 1,
14.99);
INSERT INTO LINE VALUES
(INV_NUMBER_SEQ.CURRVAL, 2, ‘23109-HB’, 1,
9.95);
Distributed Database Applications
Jiangping Wang
Oracle Sequences
Once a sequence value is used (through
NEXTVAL), it cannot be used again
If SQL statement rolls back, the sequence
value does not roll back
A sequence is not associated with a table
A sequence can be used to generate unique
values for more than one tables
Dropping a sequence does not delete the
values generated
A sequence has one purpose: assign unique
numbers to stuff
Do not expect a sequence to return gap free
values
Distributed Database Applications
Jiangping Wang
Homework
Create a function that returns the next
available customer ID.
Create a stored procedure that accepts
customer data as input arguments, adds a
new customer record to the customer table.
Create a stored procedure that accepts a
numeric amount as an input argument that
will be used as a filter threshold and prints
a listing of customer information.
Lab activities
Distributed Database Applications
Jiangping Wang
Download