Download presentation
Presentation is loading. Please wait.
Published byCalvin Gallagher Modified over 9 years ago
1
Matthew P. Johnson, OCL3, CISDD CUNY, June 20051 OCL3 Oracle 10g: SQL & PL/SQL Session #8 Matthew P. Johnson CISDD, CUNY June, 2004
2
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 2 Agenda More PL/SQL: CASE statements SELECT … INTO Exception-handling Packages Execution rights DDL in PL/SQL with dynamic PL/SQL Triggers
3
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 3 Case-statements Saw if and if-else statements last time Oracle 8i added support for case stmts Two kinds: Simple cast stmt “searched” case stmt Also: case expressions
4
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 4 Simple case statements General form: ELSE is optional expression and results are scalars numbers, chars, strings, etc.; not tables Literals or vars CASE expression WHEN result1 THEN statements1 WHEN result2 THEN statements2... ELSE statements_else END CASE; CASE expression WHEN result1 THEN statements1 WHEN result2 THEN statements2... ELSE statements_else END CASE;
5
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 5 Simple case e.g. CASE employee_type WHEN 'S' THEN award_salary_bonus(employee_id); WHEN 'H' THEN award_hourly_bonus(employee_id); WHEN 'C' THEN award_commissioned_bonus(employee_id); ELSE RAISE invalid_employee_type; END CASE; CASE employee_type WHEN 'S' THEN award_salary_bonus(employee_id); WHEN 'H' THEN award_hourly_bonus(employee_id); WHEN 'C' THEN award_commissioned_bonus(employee_id); ELSE RAISE invalid_employee_type; END CASE;
6
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 6 Simple case’s ELSE clause This ELSE is optional, but if omitted, you get an implicit else clause: Run example: Can use a NULL statement in the ELSE clause ELSE RAISE CASE_NOT_FOUND; ELSE RAISE CASE_NOT_FOUND; declare x number := 1; begin case x when 2 then dbms_output.put_line('2'); … declare x number := 1; begin case x when 2 then dbms_output.put_line('2'); …
7
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 7 Searched case statement General form: Like C/Java if “switch” “case” and “case” “when” Only the first matching WHEN clause is executed CASE WHEN expression1 THEN statements1 WHEN expression2 THEN statements2... ELSE statements_else END CASE; CASE WHEN expression1 THEN statements1 WHEN expression2 THEN statements2... ELSE statements_else END CASE;
8
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 8 Searched case e.g. Q: Can this be implemented as a simple case? CASE WHEN salary >= 10000 AND salary <=20000 THEN give_bonus(employee_id, 1500); WHEN salary > 20000 AND salary <= 40000 THEN give_bonus(employee_id, 1000); WHEN salary > 40000 THEN give_bonus(employee_id, 500); ELSE give_bonus(employee_id, 0); END CASE; CASE WHEN salary >= 10000 AND salary <=20000 THEN give_bonus(employee_id, 1500); WHEN salary > 20000 AND salary <= 40000 THEN give_bonus(employee_id, 1000); WHEN salary > 40000 THEN give_bonus(employee_id, 500); ELSE give_bonus(employee_id, 0); END CASE;
9
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 9 Searched case e.g. CASE TRUE WHEN salary >= 10000 AND salary <=20000 THEN give_bonus(employee_id, 1500); WHEN salary > 20000 AND salary <= 40000 give_bonus(employee_id, 1000); WHEN salary > 40000 give_bonus(employee_id, 500); ELSE give_bonus(employee_id, 0); END CASE; CASE TRUE WHEN salary >= 10000 AND salary <=20000 THEN give_bonus(employee_id, 1500); WHEN salary > 20000 AND salary <= 40000 give_bonus(employee_id, 1000); WHEN salary > 40000 give_bonus(employee_id, 500); ELSE give_bonus(employee_id, 0); END CASE;
10
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 10 CASE statements in SQL By the way: CASE statements are now supported in Oracle SQL itself SELECT CASE WHEN comm is null THEN 0 ELSE comm END FROM emp; SELECT CASE WHEN comm is null THEN 0 ELSE comm END FROM emp;
11
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 11 Cursors in PL/SQL As expected, PL/SQL has syntax to do the usual things: Declare cursors Open and close Fetch and eventually leave Each can be done manually Also has elegant for/cursor loop Declare, open, close, fetch all automatic: Example: http://pages.stern.nyu.edu/~mjohnson/oracle/plsql/for.sql http://pages.stern.nyu.edu/~mjohnson/oracle/plsql/for.sql FOR my-rec IN my-cursor LOOP … END LOOP; FOR my-rec IN my-cursor LOOP … END LOOP;
12
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 12 Explicit cursors v. for loop cursors 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; 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;
13
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 13 Explicit cursors v. for loop cursors 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; 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;
14
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 14 SELECT … INTO create or replace function getprod(manuf varchar) return varchar as pn varchar(255); begin select prodname into pn from products where mfg = manuf; return pn; end; / create or replace function getprod(manuf varchar) return varchar as pn varchar(255); begin select prodname into pn from products where mfg = manuf; return pn; end; /
15
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 15 SELECT … INTO and exceptions create or replace function getprod(manuf varchar) return varchar as pn varchar(255); begin select prodname into pn from products where mfg = manuf; return pn; Exception When TOO_MANY_ROWS then dbms_output.put_line('got too many'); end; / create or replace function getprod(manuf varchar) return varchar as pn varchar(255); begin select prodname into pn from products where mfg = manuf; return pn; Exception When TOO_MANY_ROWS then dbms_output.put_line('got too many'); end; /
16
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 16 SELECT … INTO and exceptions … Exception When TOO_MANY_ROWS then declare err_num number := sqlcode; err_msg varchar2(255) := sqlerrm; begin dbms_output.put_line('got too many'); dbms_output.put_line(sqlcode); dbms_output.put_line(sqlerrm); end; / … Exception When TOO_MANY_ROWS then declare err_num number := sqlcode; err_msg varchar2(255) := sqlerrm; begin dbms_output.put_line('got too many'); dbms_output.put_line(sqlcode); dbms_output.put_line(sqlerrm); end; /
17
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 17 Exception handlers Each WHEN-THEN names a possible exception, like a case in a switch stmt: EXCEPTION WHEN NO_DATA_FOUND THEN executable_statements1; WHEN DUP_VAL_ON_INDEX THEN executable_statements1;... WHEN OTHERS THEN otherwise_code; END; EXCEPTION WHEN NO_DATA_FOUND THEN executable_statements1; WHEN DUP_VAL_ON_INDEX THEN executable_statements1;... WHEN OTHERS THEN otherwise_code; END;
18
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 18 WHEN OTHERS and NULL Can have generic exception catcher with WHEN OTHERS To swallow all other exception types, use a null statement: EXCEPTION WHEN exception_name1 THEN --do one thing WHEN exception_name2 THEN --do another thing WHEN OTHERS THEN null; END; EXCEPTION WHEN exception_name1 THEN --do one thing WHEN exception_name2 THEN --do another thing WHEN OTHERS THEN null; END;
19
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 19 Raising exceptions You can raise an exception with RAISE: DECLARE exception_name EXCEPTION; BEGIN IF condition THEN RAISE exception_name; END IF; EXCEPTION WHEN exception_name THEN statement; END; DECLARE exception_name EXCEPTION; BEGIN IF condition THEN RAISE exception_name; END IF; EXCEPTION WHEN exception_name THEN statement; END;
20
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 20 Packages Functions and procedures (and vars) can be grouped in packages Like Java packages, C++ namespaces, etc. A pkg has a specification and a body Somewhat like C++ class definitions Specification: declares public functions “public” means: can be run by a user with EXECUTE authority on this pkg Body: defines all functions Vars defined here are visible to the pkg’s programs
21
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 21 Package e.g. Run example: http://pages.stern.nyu.edu/~mjohnson/oracle/ plsql/numsys.sql http://pages.stern.nyu.edu/~mjohnson/oracle/ plsql/numsys.sql
22
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 22 Dynamic PL/SQL Saw “dynamic SQL” in the cases of Pro*C and JDBC Ability to run ad-hoc (non-hard-coded) SQL in programs/scripts Can also do this in PL/SQL The string can be passed in, created from concatenation, etc. EXECUTE IMMEDIATE ;
23
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 23 Dynamic PL/SQL E.g.: write function to return number rows in an arbitrary table CREATE OR REPLACE FUNCTION rowCount ( tabname IN VARCHAR2) return integer as retval integer; begin execute immediate 'select count(*) from ' || tabname into retval; return retval; end; / CREATE OR REPLACE FUNCTION rowCount ( tabname IN VARCHAR2) return integer as retval integer; begin execute immediate 'select count(*) from ' || tabname into retval; return retval; end; /
24
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 24 Dynamic PL/SQL for DDL Ordinarily can’t do DDL in PL/SQL But you can in dynamic PL/SQL Here’s an e.g.: CREATE OR REPLACE procedure dropproc(procname in varchar2) as begin execute immediate 'drop procedure ' || procname; end; / CREATE OR REPLACE procedure dropproc(procname in varchar2) as begin execute immediate 'drop procedure ' || procname; end; /
25
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 25 More on PL/SQL O’Reilly’s Oracle PL/SQL Programming: http://www.unix.org.ua/orelly/oracle/prog2/ http://www.unix.org.ua/orelly/oracle/prog2/ This lecture somewhat follows 3 rd edition of this book PL/SQL Reference & Tutorial: http://www.ilook.fsnet.co.uk/ora_sql/sqlmain2.htm http://www.ilook.fsnet.co.uk/ora_sql/sqlmain2.htm Introduction to PL/SQL: http://www.geocities.com/cliktoprogram/plsql/introduction.html http://www.geocities.com/cliktoprogram/plsql/introduction.html Oracle FAQ's Script and Code Exchange: http://www.orafaq.com/scripts/ http://www.orafaq.com/scripts/
26
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005 26 Live examples Factorial function: http://pages.stern.nyu.edu/~mjohnson/dbms/plsql/ fact.sql http://pages.stern.nyu.edu/~mjohnson/dbms/plsql/ fact.sql Converting between bases: http://pages.stern.nyu.edu/~mjohnson/dbms/plsql/ numsys.sql http://pages.stern.nyu.edu/~mjohnson/dbms/plsql/ numsys.sql Directory of examples: http://pages.stern.nyu.edu/~mjohnson/dbms/plsql/ http://pages.stern.nyu.edu/~mjohnson/dbms/plsql/
Similar presentations
© 2025 SlidePlayer.com Inc.
All rights reserved.