Matthew P. Johnson, OCL2, CISDD CUNY, January 20051 OCL2 Oracle 10g: SQL & PL/SQL Session #8 Matthew P. Johnson CISDD, CUNY Fall, 2004.

Slides:



Advertisements
Similar presentations
PL/SQL.
Advertisements

AN INTRODUCTION TO PL/SQL Mehdi Azarmi 1. Introduction PL/SQL is Oracle's procedural language extension to SQL, the non-procedural relational database.
PL/SQL. Introduction to PL/SQL PL/SQL is the procedure extension to Oracle SQL. It is used to access an Oracle database from various environments (e.g.
SQL*PLUS, PLSQL and SQLLDR Ali Obaidi. SQL Advantages High level – Builds on relational algebra and calculus – Powerful operations – Enables automatic.
Stored Procedure Language Stored Procedure Overview Stored Procedure is a function in a shared library accessible to the database server can also write.
Chapter 4B: More Advanced PL/SQL Programming
Using Oracle PL/SQL PL/SQL stands for Procedural Language/SQL. PL/SQL extends SQL by adding constructs found in procedural languages, resulting in a structural.
M.P. Johnson, DBMS, Stern/NYU, Sp20041 C : Database Management Systems Lecture #19 Matthew P. Johnson Stern School of Business, NYU Spring, 2004.
M.P. Johnson, DBMS, Stern/NYU, Spring C : Database Management Systems Lecture #21 M.P. Johnson Stern School of Business, NYU Spring, 2008.
PL/SQL Agenda: Basic PL/SQL block structure
Matthew P. Johnson, OCL1, CISDD CUNY, F20041 OCL1 Oracle 10g: SQL & PL/SQL Session #7 Matthew P. Johnson CISDD, CUNY Fall, 2004.
M.P. Johnson, DBMS, Stern/NYU, Spring C : Database Management Systems Lecture #19 M.P. Johnson Stern School of Business, NYU Spring, 2005.
Matthew P. Johnson, OCL4, CISDD CUNY, Sept OCL4 Oracle 10g: SQL & PL/SQL Session #6 Matthew P. Johnson CISDD, CUNY June, 2005.
Cursors in Pl/SQL Database 1. Practice. Sample Database The schema of the sample database is the following: Drinkers (name, occupation, birthday, salary)
PL/SQL Bulk Collections in Oracle 9i and 10g Kent Crotty Burleson Consulting October 13, 2006.
Introduction to PL/SQL. Procedural Language extension for SQL Oracle Proprietary 3GL Capabilities Integration of SQL Portable within Oracle data bases.
Distributed Database Applications COSC 5050 Week Three.
PL / SQL P rocedural L anguage / S tructured Q uery L anguage Chapter 7 in Lab Reference.
Cursor and Exception Handling By Nidhi Bhatnagar.
Lecture 4 PL/SQL language. PL/SQL – procedural SQL Allows combining procedural and SQL code PL/SQL code is compiled, including SQL commands PL/SQL code.
ASP.NET Programming with C# and SQL Server First Edition Chapter 3 Using Functions, Methods, and Control Structures.
Stored procedures1 Stored procedures and functions Procedures and functions stored in the database.
Overview · What is PL/SQL · Advantages of PL/SQL · Basic Structure of a PL/SQL Block · Procedure · Function · Anonymous Block · Types of Block · Declaring.
Distributed Database Applications COSC 5050 Week One.
1 Theory, Practice & Methodology of Relational Database Design and Programming Copyright © Ellis Cohen Cursors These slides are licensed under.
PL/SQL A BRIEF OVERVIEW DAVID WILSON. PL/SQL User’s Guide and Reference PL/SQL User’s Guide and Reference.
1. 1. Which type of argument passes a value from a procedure to the calling program? A. VARCHAR2 B. BOOLEAN C. OUT D. IN 2.
Advanced SQL: Cursors & Stored Procedures
Matthew P. Johnson, OCL3, CISDD CUNY, June OCL3 Oracle 10g: SQL & PL/SQL Session #8 Matthew P. Johnson CISDD, CUNY June, 2004.
CpSc 462/662: Database Management Systems (DBMS) (TEXNH Approach) Stored Procedure James Wang.
CS178 Database Management PL/SQL session 8 References: ORACLE 9i PROGRAMMING A Primer Rajshekhar Sunderraman.
CSIT 313 DB PROGRAMMING EXCEPTION HANDLING. In PL/SQL, an error condition is called an exception. An exception can be either –internally defined (by the.
Oracle PL/SQL. PL/SQL Originally modeled after ADA Originally modeled after ADA Created for Dept. of DefenseCreated for Dept. of Defense Allows expanded.
Trapping Oracle Server Exceptions. 2 home back first prev next last What Will I Learn? Describe and provide an example of an error defined by the Oracle.
PL/SQL Block Structure DECLARE - Optional Variables, cursors, user-defined exceptions BEGIN - Mandatory SQL Statements PL/SQL Statements EXCEPTIONS - Optional.
Distributed Database Applications COSC 5050 Week Five.
Trigger Oracle PL/SQL. Triggers Associated with a particular table Associated with a particular table Automatically executed when a particular event occurs.
Chapter 15 Introduction to PL/SQL. Chapter Objectives  Explain the benefits of using PL/SQL blocks versus several SQL statements  Identify the sections.
Database Technology Jing Shen.
School of Computing and Management Sciences © Sheffield Hallam University SQL is non-procedural –designed to be relatively approachable to non- programmers.
Oracle 8i Exception Handling. General Syntax DECLARE --- BEGIN --- EXCEPTION WHEN exception_name1 THEN -Error handling statements WHEN exception_name2.
1 PL\SQL Dev Templates. 2 TEMPLATE DEFINITION Whenever you create a new program unit, its initial contents are based upon a template which contains pre-defined.
Using SQL in PL/SQL ITEC 224 Database Programming.
ITEC 224 Database Programming PL/SQL Lab Cursors.
CREATING STORED PROCEDURES AND FUNCTIONS. Objectives After completing this lecture, you should be able to do the following: Differentiate between anonymous.
Chapter 5 : Integrity And Security  Domain Constraints  Referential Integrity  Security  Triggers  Authorization  Authorization in SQL  Views 
implicit and an explicit cursor
Using SQL in PL/SQL Oracle Database PL/SQL 10g Programming Chapter 4.
Chapter 18: Exception Handling1 Chapter Eighteen Exception Handling Objective: – Define exceptions – List types of exception handlers – Trap errors – Exception.
©Silberschatz, Korth and Sudarshan5.1Database System Concepts - 6 th Edition Procedural Constructs in SQL Chapter 5.
Handling Exceptions. Objectives What is exception Types of exceptions How to handle exceptions Trapping pre defined oracle errors.
A procedure is a module performing one or more actions; it does not need to return any values. The syntax for creating a procedure is as follows: CREATE.
PL/SQL programming Procedures and Cursors Lecture 1 [Part 2]
PRACTICE OVERVIEW PL/SQL Part Your stored procedure, GET_BUDGET, has a logic problem and must be modified. The script that contains the procedure.
Advanced SQL: Cursors & Stored Procedures Instructor: Mohamed Eltabakh 1.
Kingdom of Saudi Arabia Ministry of Higher Education Al-Imam Muhammad Ibn Saud Islamic University College of Computer and Information Sciences Overview.
Matthew P. Johnson, OCL3, CISDD CUNY, June OCL3 Oracle 10g: SQL & PL/SQL Session #7 Matthew P. Johnson CISDD, CUNY June, 2005.
CS422 Principles of Database Systems Oracle PL/SQL Chengyu Sun California State University, Los Angeles.
Oracle 数据库应用 -- PL/SQL 进阶 (3) & Oracle DBA 2016/5/ /5/10.
1 Copyright © 2004, Oracle. All rights reserved. PL/SQL Programming Concepts: Review.
ITEC 224 Database Programming
C : Database Management Systems Lecture #20
Difference between Oracle PL/SQL and MySQL
SQL Stored Triggers Presented by: Dr. Samir Tartir
Handling Exceptions.
SQL PL/SQL Presented by: Dr. Samir Tartir
Triggers.
Stored Procedure Language
Database Programming Using Oracle 11g
Database Programming Using Oracle 11g
Presentation transcript:

Matthew P. Johnson, OCL2, CISDD CUNY, January OCL2 Oracle 10g: SQL & PL/SQL Session #8 Matthew P. Johnson CISDD, CUNY Fall, 2004

Matthew P. Johnson, OCL2, CISDD CUNY, January Agenda More PL/SQL: CASE statements Exception-handling Packages Execution rights DDL in PL/SQL with dynamic PL/SQL Triggers

Matthew P. Johnson, OCL2, CISDD CUNY, January 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

Matthew P. Johnson, OCL2, CISDD CUNY, January 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;

Matthew P. Johnson, OCL2, CISDD CUNY, January 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;

Matthew P. Johnson, OCL2, CISDD CUNY, January 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'); …

Matthew P. Johnson, OCL2, CISDD CUNY, January 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;

Matthew P. Johnson, OCL2, CISDD CUNY, January Searched case e.g. Q: Can this be implemented as a simple case? CASE WHEN salary >= AND salary <=20000 THEN give_bonus(employee_id, 1500); WHEN salary > AND salary <= THEN give_bonus(employee_id, 1000); WHEN salary > THEN give_bonus(employee_id, 500); ELSE give_bonus(employee_id, 0); END CASE; CASE WHEN salary >= AND salary <=20000 THEN give_bonus(employee_id, 1500); WHEN salary > AND salary <= THEN give_bonus(employee_id, 1000); WHEN salary > THEN give_bonus(employee_id, 500); ELSE give_bonus(employee_id, 0); END CASE;

Matthew P. Johnson, OCL2, CISDD CUNY, January Searched case e.g. CASE TRUE WHEN salary >= AND salary <=20000 THEN give_bonus(employee_id, 1500); WHEN salary > AND salary <= give_bonus(employee_id, 1000); WHEN salary > give_bonus(employee_id, 500); ELSE give_bonus(employee_id, 0); END CASE; CASE TRUE WHEN salary >= AND salary <=20000 THEN give_bonus(employee_id, 1500); WHEN salary > AND salary <= give_bonus(employee_id, 1000); WHEN salary > give_bonus(employee_id, 500); ELSE give_bonus(employee_id, 0); END CASE;

Matthew P. Johnson, OCL2, CISDD CUNY, January Case expressions Above were case statements  One statement/set of statements executed, depending on value of test expression Also have case expressions  Evaluates to some expression, depending on value of test expression Case expressions, too, come in both varieties

Matthew P. Johnson, OCL2, CISDD CUNY, January Simple case expression Simple_Case_Expression := CASE expression WHEN result1 THEN result_expression1 WHEN result2 THEN result_expression2... ELSE result_expression_else END; Simple_Case_Expression := CASE expression WHEN result1 THEN result_expression1 WHEN result2 THEN result_expression2... ELSE result_expression_else END; Searched_Case_Expression := CASE WHEN expression1 THEN result_expression1 WHEN expression2 THEN result_expression2... ELSE result_expression_else END; Searched_Case_Expression := CASE WHEN expression1 THEN result_expression1 WHEN expression2 THEN result_expression2... ELSE result_expression_else END;

Matthew P. Johnson, OCL2, CISDD CUNY, January 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;

Matthew P. Johnson, OCL2, CISDD CUNY, January 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;

Matthew P. Johnson, OCL2, CISDD CUNY, January 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;

Matthew P. Johnson, OCL2, CISDD CUNY, January Another loop e.g. CREATE OR REPLACE PROCEDURE pay_out_balance ( account_id_in IN accounts.id%TYPE) -- the type of the var is the same as the field type! IS --IS or AS can be used in place of DECLARE l_balance_remaining NUMBER; BEGIN LOOP l_balance_remaining := account_balance (account_id_in); IF l_balance_remaining < 1000 THEN EXIT; -- exit from the LOOP ELSE apply_balance (account_id_in, l_balance_remaining); END IF; END LOOP; END pay_out_balance; CREATE OR REPLACE PROCEDURE pay_out_balance ( account_id_in IN accounts.id%TYPE) -- the type of the var is the same as the field type! IS --IS or AS can be used in place of DECLARE l_balance_remaining NUMBER; BEGIN LOOP l_balance_remaining := account_balance (account_id_in); IF l_balance_remaining < 1000 THEN EXIT; -- exit from the LOOP ELSE apply_balance (account_id_in, l_balance_remaining); END IF; END LOOP; END pay_out_balance;

Matthew P. Johnson, OCL2, CISDD CUNY, January 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;

Matthew P. Johnson, OCL2, CISDD CUNY, January Function e.g. FUNCTION company_name (company_id_in IN company.company_id%TYPE) RETURN VARCHAR2 IS cname company.company_id%TYPE; BEGIN SELECT name INTO cname FROM company WHERE company_id = company_id_in; RETURN cname; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN NULL; END; FUNCTION company_name (company_id_in IN company.company_id%TYPE) RETURN VARCHAR2 IS cname company.company_id%TYPE; BEGIN SELECT name INTO cname FROM company WHERE company_id = company_id_in; RETURN cname; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN NULL; END;

Matthew P. Johnson, OCL2, CISDD CUNY, January Longer exception e.g. CREATE OR REPLACE PROCEDURE check_account ( account_id_in IN accounts.id%TYPE) IS l_balance_remaining NUMBER; l_balance_below_minimum EXCEPTION; l_account_name accounts.name%TYPE; BEGIN SELECT name INTO l_account_name FROM accounts WHERE id = account_id_in; l_balance_remaining := account_balance (account_id_in); DBMS_OUTPUT.put_line ('Balance for ' || l_account_name || ' = ' || l_balance_remaining); CREATE OR REPLACE PROCEDURE check_account ( account_id_in IN accounts.id%TYPE) IS l_balance_remaining NUMBER; l_balance_below_minimum EXCEPTION; l_account_name accounts.name%TYPE; BEGIN SELECT name INTO l_account_name FROM accounts WHERE id = account_id_in; l_balance_remaining := account_balance (account_id_in); DBMS_OUTPUT.put_line ('Balance for ' || l_account_name || ' = ' || l_balance_remaining);

Matthew P. Johnson, OCL2, CISDD CUNY, January Longer exception e.g. IF l_balance_remaining < 1000 THEN RAISE l_balance_below_minimum; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN -- No account found for this ID log_error (...); WHEN l_balance_below_minimum THEN log_error (...); RAISE; END; IF l_balance_remaining < 1000 THEN RAISE l_balance_below_minimum; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN -- No account found for this ID log_error (...); WHEN l_balance_below_minimum THEN log_error (...); RAISE; END;

Matthew P. Johnson, OCL2, CISDD CUNY, January 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;

Matthew P. Johnson, OCL2, CISDD CUNY, January 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;

Matthew P. Johnson, OCL2, CISDD CUNY, January More on scope Can name blocks and loops with labels > BEGIN INSERT INTO catalog VALUES (...); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN NULL; END insert_but_ignore_dups; > BEGIN INSERT INTO catalog VALUES (...); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN NULL; END insert_but_ignore_dups;

Matthew P. Johnson, OCL2, CISDD CUNY, January Scope and nested, labeled loops > DECLARE counter INTEGER := 0; BEGIN... DECLARE counter INTEGER := 1; BEGIN IF counter = outerblock.counter THEN... END IF; END; > DECLARE counter INTEGER := 0; BEGIN... DECLARE counter INTEGER := 1; BEGIN IF counter = outerblock.counter THEN... END IF; END;

Matthew P. Johnson, OCL2, CISDD CUNY, January Scope and nested, labeled loops BEGIN > LOOP EXIT outer_loop; END LOOP; some_statement ; END LOOP; END; BEGIN > LOOP EXIT outer_loop; END LOOP; some_statement ; END LOOP; END;

Matthew P. Johnson, OCL2, CISDD CUNY, January 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

Matthew P. Johnson, OCL2, CISDD CUNY, January Package e.g. Create or replace PACKAGE rg_select as list_name VARCHAR2(60); PROCEDURE init_list (item_name_in IN VARCHAR2, fill_action_in IN VARCHAR2 := 'IMMEDIATE'); PROCEDURE delete_list; PROCEDURE clear_list; END rg_select; Create or replace PACKAGE rg_select as list_name VARCHAR2(60); PROCEDURE init_list (item_name_in IN VARCHAR2, fill_action_in IN VARCHAR2 := 'IMMEDIATE'); PROCEDURE delete_list; PROCEDURE clear_list; END rg_select;

Matthew P. Johnson, OCL2, CISDD CUNY, January Package body Package body is defined separately, containing actual ftn/proc implementations  Do not preface ftns and procs with “create or replace” Create or replace PACKAGE body rg_select as PROCEDURE init_list (item_name_in IN VARCHAR2, fill_action_in IN VARCHAR2 := 'IMMEDIATE') as … End; … END rg_select; Create or replace PACKAGE body rg_select as PROCEDURE init_list (item_name_in IN VARCHAR2, fill_action_in IN VARCHAR2 := 'IMMEDIATE') as … End; … END rg_select;

Matthew P. Johnson, OCL2, CISDD CUNY, January 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:  FOR my-rec IN my-cursor LOOP … END LOOP; FOR my-rec IN my-cursor LOOP … END LOOP;

Matthew P. Johnson, OCL2, CISDD CUNY, January Record-based DML CREATE OR REPLACE PROCEDURE set_book_info ( book_in IN books%ROWTYPE) IS BEGIN INSERT INTO books VALUES book_in; EXCEPTION WHEN DUP_VAL_ON_INDEX THEN UPDATE books SET ROW = book_in WHERE isbn = book_in.isbn; END; CREATE OR REPLACE PROCEDURE set_book_info ( book_in IN books%ROWTYPE) IS BEGIN INSERT INTO books VALUES book_in; EXCEPTION WHEN DUP_VAL_ON_INDEX THEN UPDATE books SET ROW = book_in WHERE isbn = book_in.isbn; END;

Matthew P. Johnson, OCL2, CISDD CUNY, January Programs and rights By default, only the creator of a program may run it (apart from the admin) If others should run, must GRANT them permission: Permissions can be revoked: Can also grant to particular roles or everyone: Wider/narrower grant ops are independent… SQL> GRANT EXECUTE ON wordcount TO george; SQL> REVOKE EXECUTE FROM wordcount TO george; SQL> GRANT EXECUTE ON wordcount TO everyone;

Matthew P. Johnson, OCL2, CISDD CUNY, January PL/SQL v. SQL There are some things SQL can’t do (e.g., factorial), but some problems can be solved in both DECLARE CURSOR checked_out_cur IS SELECT pet_id, name, checkout_date FROM occupancy WHERE checkout_date IS NOT NULL; BEGIN FOR checked_out_rec IN checked_out_cur LOOP INSERT INTO occupancy_history (pet_id, name, checkout_date) VALUES (checked_out_rec.pet_id, checked_out_rec.name, checked_out_rec.checkout_date); DELETE FROM occupancy WHERE pet_id = checked_out_rec.pet_id; END LOOP; END; DECLARE CURSOR checked_out_cur IS SELECT pet_id, name, checkout_date FROM occupancy WHERE checkout_date IS NOT NULL; BEGIN FOR checked_out_rec IN checked_out_cur LOOP INSERT INTO occupancy_history (pet_id, name, checkout_date) VALUES (checked_out_rec.pet_id, checked_out_rec.name, checked_out_rec.checkout_date); DELETE FROM occupancy WHERE pet_id = checked_out_rec.pet_id; END LOOP; END;

Matthew P. Johnson, OCL2, CISDD CUNY, January PL/SQL v. SQL The same thing can be done w/o a cursor: BEGIN INSERT INTO occupancy_history (pet_id, NAME, checkout_date) SELECT pet_id, NAME, checkout_date FROM occupancy WHERE checkout_date IS NOT NULL; DELETE FROM occupancy WHERE checkout_date IS NOT NULL; END; BEGIN INSERT INTO occupancy_history (pet_id, NAME, checkout_date) SELECT pet_id, NAME, checkout_date FROM occupancy WHERE checkout_date IS NOT NULL; DELETE FROM occupancy WHERE checkout_date IS NOT NULL; END;

Matthew P. Johnson, OCL2, CISDD CUNY, January 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 ;

Matthew P. Johnson, OCL2, CISDD CUNY, January 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; /

Matthew P. Johnson, OCL2, CISDD CUNY, January 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; /

Matthew P. Johnson, OCL2, CISDD CUNY, January More on PL/SQL O’Reilly’s Oracle PL/SQL Programming:   This lecture somewhat follows 3 rd edition of this book PL/SQL Reference & Tutorial:  Introduction to PL/SQL:  Oracle FAQ's Script and Code Exchange: 