Jiangping WangDistributed Database Applications
Outline
Cursors and data retrieval
Procedures
Functions
Parameters
Sequences
Jiangping WangDistributed Database Applications
Cursors and Data Retrieval
PL/SQL integrates with the Oracle databaseSystem 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 cursorExplicit cursorCursor variable
Jiangping WangDistributed Database Applications
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;
Jiangping WangDistributed Database Applications
Cursorcreate 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;/
Jiangping WangDistributed Database Applications
Cursor Attributes
Page 468%FOUND
Status of fetch operationTrue if fetch succeeded
%NOTFOUNDOpposite of %FOUND
%ROWCOUNTNumber of records fetched
%ISOPENTrue if the cursor is open
cursor_name%attribute_name
Jiangping WangDistributed Database Applications
Referencing Variables in Cursor
Identifier precedence in a cursorQualifying variable with proc nameUsing standard naming conventions
create or replace PROCEDURE adjustIS 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;
Jiangping WangDistributed Database Applications
Implicit CursorUse 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;
Jiangping WangDistributed Database Applications
Implicit Cursor
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;/
Implicit SQL cursor attributes SQL%FOUNDSQL%NOTFOUNDSQL%ROWCOUNTSQL%ISOPEN
Error handlingWith exception
Jiangping WangDistributed Database Applications
Explicit CursorExplicitly defined in declaration sectionComplete 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%ROWTYPEIS SELECT * FROM employee WHERE department_id = 10;
Jiangping WangDistributed Database Applications
Explicit Cursor
OpenFetchCloseExplicit cursor attributes
cursor%FOUNDcursor%NOTFOUNDcursor%ROWCOUNTcursor%ISOPEN
Jiangping WangDistributed Database Applications
Explicit CursorDECLARE 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;/
Jiangping WangDistributed Database Applications
Explicit CursorDECLARE 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 WangDistributed Database Applications
Explicit CursorDECLARE 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;/
Jiangping WangDistributed Database Applications
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;/
Jiangping WangDistributed Database Applications
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;/
Jiangping WangDistributed Database Applications
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;
Jiangping WangDistributed Database Applications
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;
Jiangping WangDistributed Database Applications
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;
/
Jiangping WangDistributed Database Applications
Modular Code
PL/SQL offers the following structures that modularize your code in different ways
ProcedureFunctionTriggerPackage
Jiangping WangDistributed Database Applications
Procedure
Procedure is a module that performs one or more actionsCan be a standalone call, executable statement
Jiangping WangDistributed Database Applications
ProcedureCREATE OR REPLACEPROCEDURE get_happy (ename_in IN VARCHAR2)
Header
IS
hiredate DATE; Declarations
BEGIN
hiredate:= SYSDATE – 2; INSERT INTO employee (emp_name, hiredate)
VALUES (ename_in, hiredate);
Code Body
EXCEPTION * optional *
WHEN DUP_VAL_IN_INDEX THEN DBMS_OUTPUT.PUT_LINE (‘Cannot insert.’);
Exception block* optional *
END get_happy;
Jiangping WangDistributed Database Applications
Procedureprocedure 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;
Jiangping WangDistributed Database Applications
Procedureprocedure 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;
Jiangping WangDistributed Database Applications
Procedure
Calling a procedureProcedure is called as an executable PL/SQL statementCalled in a blockMust end with (;)
beginapply_discount( new_company_id, 0.15 );display_store_summary;display_store_summary();
end;
Jiangping WangDistributed Database Applications
Function
Function is a module that returns a valueFunction can exist only as part of an executable statementFunction has a datatype
Jiangping WangDistributed Database Applications
FunctionCREATE OR REPLACEFUNCTION soft_pillow (type_in IN VARCHAR2)
RETURN BOOLEAN
Header
IS
CURSOR pillow_cur (type_in pillow.pillow_type%TYPE) ISSELECT softnessFROM pillowWHERE pillow_type = type-in;
Pillow_rec pillow_cur%ROWTYPE;
Declarations
BEGIN
OPEN pillow_cur(type_in);FETCH pillow_cur INTO Pillow_rec;CLOSE pillow_cur;RETURN Pillow_rec.softness;
Code Body
EXCEPTION * optional *
Exception block* optional *
END soft_pillow;
Jiangping WangDistributed Database Applications
Function
Defining function
create or replace function favorite_nickname( name_in in varchar2) return varchar2isbeginEnd;
Calling function
declarenickname varchar2(100) := favorite_nickname(‘Nic’);
Jiangping WangDistributed Database Applications
Functioncreate or replace function get_department( ssn_in in employee.ssn%type) return department.dept_name%typeis 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;/
Jiangping WangDistributed Database Applications
Parameter
Be used to pass information back and forthParameter declaration must be unconstrained
DECLARE company_name varchar2(60);
PROCEDURE display_company( company_name IN varchar2) IS …
Jiangping WangDistributed Database Applications
Parameter ModeIN mode: Read-only
Is the default modeValue cannot be changedCan have default valuePassed by reference
OUT mode: Write-onlyHas no value until the endNo default valueActual parameter must be a variablePassed by value
IN OUT mode: Read-writeCannot have default valueMust be a variablePassed by value
Jiangping WangDistributed Database Applications
Parametercreate 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;/
Jiangping Wang
Parameter
Distributed Database Applications
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')ISBEGIN 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;/
Jiangping WangDistributed Database Applications
Oracle SequencesIndependent object in the database
Not a data typeNot tied to a table or a columnCan be used anywhere a value is expected
Generate a numeric value that can be assigned to any column in any tableThe table attribute to which you assigned a value based on a sequence can be edited and modifiedCan be created and deleted anytime
Jiangping WangDistributed Database Applications
Oracle SequencesCREATE 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;
Jiangping WangDistributed Database Applications
Oracle SequencesINSERT 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);
Jiangping WangDistributed Database Applications
Oracle SequencesOnce a sequence value is used (through NEXTVAL), it cannot be used againIf SQL statement rolls back, the sequence value does not roll backA 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 generatedA sequence has one purpose: assign unique numbers to stuff
Do not expect a sequence to return gap free values
Jiangping WangDistributed Database Applications
HomeworkCreate 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