chapter 6 - siuebbordol/index/courses/563/notes/…  · web viewthe exception-handling part...

31
CHAPTER 3 PROCEDURES, FUNCTIONS, TRIGGERS AND PACKAGES ------------------------------------------------------------ ------------------------------------------------ OBJECTIVES In this chapter, we will briefly cover the following topics: Creating procedures Passing parameters and getting values out. Dropping procedures Creating Functions Return statement Dropping Functions Creating package specifiacations Creating package bodies Calling stored packages Cursors in packages Advantages of packages What is a trigger Parts of a trigger Before and After triggers Statement and Row triggers Enabling and Disabling Triggers Dropping Triggers PROCEDURES AND FUNCTIONS A procedure or function is a named PL/SQL block. Procedures and functions are normally stored in the database within package specifications (which is a wrapper for a group of named blocks), although they may also be stored in the database individually. A procedure or function is parsed or compiled at the time it is stored. As a result, they tend to run faster compared to non-procedural SQL scripts, which require extra time for compilation.

Upload: others

Post on 26-Jul-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: CHAPTER 6 - SIUEbbordol/index/courses/563/Notes/…  · Web viewThe exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION

CHAPTER 3

PROCEDURES, FUNCTIONS, TRIGGERS AND PACKAGES ------------------------------------------------------------------------------------------------------------

OBJECTIVES

In this chapter, we will briefly cover the following topics:

Creating procedures Passing parameters and getting values out. Dropping procedures Creating Functions Return statement Dropping Functions Creating package specifiacations Creating package bodies Calling stored packages Cursors in packages Advantages of packages What is a trigger Parts of a trigger Before and After triggers Statement and Row triggers Enabling and Disabling Triggers Dropping Triggers

PROCEDURES AND FUNCTIONS

A procedure or function is a named PL/SQL block. Procedures and functions are normally stored in the database within package specifications (which is a wrapper for a group of named blocks), although they may also be stored in the database individually. A procedure or function is parsed or compiled at the time it is stored. As a result, they tend to run faster compared to non-procedural SQL scripts, which require extra time for compilation.

A procedure or function can be invoked from most Oracle tools like SQL*Plus, or other programming languages like C++ and JAVA.

Benefits of using procedures and functions include:

1. Improved data security and integrity. Control indirect access to objects from non-privileged users. Ensure that related actions are performed together, or not at all, by funnelling

actions for related tables through a single path.

Page 2: CHAPTER 6 - SIUEbbordol/index/courses/563/Notes/…  · Web viewThe exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION

2. Improved performance. Avoid reparsing for multiple users by exploiting shared SQL. Avoid PL/SQL parsing at run time by parsing at compile time. Reduce the number of calls to the database and decrease network traffic by

bundling commands.

3. Improved maintenance. Modify routines online without interfering with other users. Modify one routine to affect multiple applications. Modify one routine to eliminate duplicate testing.

PROCEDURES

Procedures are simply named PL/SQL blocks. They are created and owned by a particular schema. Like the DML functions, right to execute a procedure can be granted / revoked.

Syntax for creating a procedure:

CREATE OR REPLACE PROCEDURE <procedure name> (<parameter1 name> <mode> <data type>, <parameter1 name> <mode> <data type>, …) IS

<Variable declarations>BEGIN

Executable CommandsEXCEPTION

Exception handlersEND.

OR REPLACE - This option re-creates the procedure, maintaining the privileges previously granted.

Parameter list - If a procedure contains more than one parameter, commas should be used to separate them. You cannot specify a constraint on the data type. For example, it is illegal to do the following:

CREATE OR REPLACE PROCEDURE pro_sample(emp_ssn NUMBER(2), …..)

Instead, you should do this:

CREATE OR REPLACE PROCEDURE pro_sample(emp_ssn NUMBER, …..)

Parameters can have three modes:

Mode DescriptionIN This type of parameter is passed to the procedure as a read-only value

Page 3: CHAPTER 6 - SIUEbbordol/index/courses/563/Notes/…  · Web viewThe exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION

that cannot be changed within the procedure.OUT This type of parameter is write-only, and can only appear on the left side

of an assignment statement in the procedure.IN OUT Combination of IN and OUT; the parameter of this mode is passed to the

procedure, and its value can be changed within the procedure.

Variable declarations - Constants, variables, other procedures and local functions are declared in this section. Unlike the parameter list, you must specify the constraint of the data type of a local variable.

Executable commands - The commands to be executed by the procedure are placed here.

Exception handlers - Any error handling statements that should be caught while executing the procedure are placed here.

A procedure has two parts: the specification and the body. The procedure specification begins with the keyword PROCEDURE and ends with the procedure name or a parameter list. Parameter declarations are optional. Procedures that take no parameters are written without parentheses.

The procedure body begins with the keyword IS and ends with the keyword END followed by an optional procedure name. The procedure body has three parts: a declarative part, an executable part, and an optional exception-handling part.

The declarative part contains some local declarations, which are placed between the keywords IS and BEGIN. The keyword DECLARE, which introduces declarations in an anonymous PL/SQL block, is not used.

The executable part can hold one or more statements, which are placed between the keywords BEGIN and EXCEPTION (or END). At least one statement must appear in the executable part of a procedure. The NULL statement meets this requirement.

The exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION and END.

Before executing a procedure, you need to compile and load it to a schema. In other words, you have to make it “available” in your session. To do so, run the following statement at the SQL prompt:

Syntax for compiling a procedure:

SQL>@<SQL filename>

or SQL>start <SQL filename>

Page 4: CHAPTER 6 - SIUEbbordol/index/courses/563/Notes/…  · Web viewThe exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION

in which <SQL filename> is an .sql file which contains your procedure.

Notice that it is also the same command to run an unnamed block. Bear in mind that the filename needs NOT be the same as the procedure name. An .sql file ONLY contains the code for the procedure. If it compiles correctly, it is the procedure that is loaded to the database, not the .sql file. Therefore, in order to run a procedure at a SQL prompt, you need to execute the procedure, not the .sql file (We will discuss further about later).

If you are prompted with a warning message, type the following command to check the details about the error:

SQL> show errors;

After you compile a procedure, you can execute it.

Syntax for executing a procedure:

SQL> EXECUTE <procedure name> or EXEC <procedure name>

Let’s look at the following unnamed block:

SET SERVEROUTPUT ONDECLARE temp_emp_sal NUMBER(10,2);BEGIN SELECT emp_salary INTO temp_emp_sal FROM employee WHERE emp_ssn = '999666666'; IF temp_emp_sal > 4000 THEN DBMS_OUTPUT.PUT_LINE('Salary > 4000'); ELSE DBMS_OUTPUT.PUT_LINE('Salary < 4000'); END IF;EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('Employee not found ');END;/

Every time it is executed, it has to be parsed first. If we store this block in the database, we only need to parse or compile it once (the first time), unless we make some changes, or drop it. The following is an example of a procedure:

-- pro1.sql-- Note that the file name and the procedure name are different.

Page 5: CHAPTER 6 - SIUEbbordol/index/courses/563/Notes/…  · Web viewThe exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION

SET SERVEROUTPUT ONCREATE OR REPLACE PROCEDURE myproc1 IS temp_emp_sal NUMBER(10,2); -- local variable, and its constraint is required..BEGIN SELECT emp_salary INTO temp_emp_sal FROM employee WHERE emp_ssn = '999666666'; IF temp_emp_sal > 4000 THEN DBMS_OUTPUT.PUT_LINE('Salary > 4000'); ELSE DBMS_OUTPUT.PUT_LINE('Salary < 4000'); END IF;EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('Employee not found ');END myproc1;/

The keyword CREATE OR REPLACE directs the Oracle to create a new procedure, or replace it if a procedure with same name already exists in the same schema. OR REPLACE is optional. If the OR REPLACE is omitted, you have to drop the procedure and load it back again every time you change it.

The following gives you an example of how to compile and execute the above procedure, followed by its output:

SQL> @pro1

Procedure created.

SQL> exec myproc1Salary > 4000

PL/SQL procedure successfully completed.

The next thing to cover here is how to get values into and out of the procedure, we can do this by defining variables in the implicit declaration section as IN, OUT or IN OUT. As explained above, an IN variable is an input variable. An OUT variable is an output variable, or a variable used to hold the value that will be returned to the user when the program completes. An IN OUT variable serves as both. The following is an example with IN and OUT variables:

-- pro2.sqlSET SERVEROUTPUT ON

Page 6: CHAPTER 6 - SIUEbbordol/index/courses/563/Notes/…  · Web viewThe exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION

CREATE OR REPLACE PROCEDURE myproc2(temp_emp_ssn IN VARCHAR2,temp_emp_sal OUT NUMBER)IS temp_sal number(10,2);BEGIN SELECT emp_salary INTO temp_sal FROM employee WHERE emp_ssn = temp_emp_ssn; IF temp_sal > 4000 THEN DBMS_OUTPUT.PUT_LINE('Salary > 4000'); ELSE DBMS_OUTPUT.PUT_LINE('Salary < 4000'); END IF; temp_emp_sal := temp_sal; EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('Employee not found '); END myproc2;/

The following gives you an example of how to compile and execute the above procedure, followed by its output:

SQL> @pro2

Procedure created.

SQL> var par_sal number;

SQL> exec myproc2('999666666', :par_sal);Salary > 4000

PL/SQL procedure successfully completed.

SQL> print par_sal;

par_sal---------- 55000

USING BIND VARIABLES TO CHECK THE RESULT

In the above example, notice that a variable called par_sal is created after the procedure is compiled. Remember the program we created above takes two parameters, one IN

Page 7: CHAPTER 6 - SIUEbbordol/index/courses/563/Notes/…  · Web viewThe exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION

variable and one OUT variable? The variable par_sal is created to hold the input passed to the procedure or output value returned from the program. It is actually called a bind variable in Oracle.

A bind variable is a variable created in SQL*Plus and then referenced in other PL/SQL subprograms. If you create a bind variable in SQL*Plus, you can use the variable like a variable in your PL/SQL programs and then access the variable from SQL*Plus. In the above example, variable par_sal serves this purpose, which is storing the return value.

A bind variable is prefixed with a “:” during the execution of the program, like

:par_sal

To check the value of a bind variable, simply use:

SQL>PRINT par_sal;

Or

SQL>SELECT par_sal FROM dual;

Bear in mind that a procedure can have zero to many parameters, and can also return zero to many values.

DROPPING A PROCEDURE

As mentioned above, a procedure needs to be loaded before it can be executed. Once it is loaded, it can also be unloaded, or dropped.

The syntax for dropping a procedure:

SQL>DROP PROCEDURE <procedurename>;

FUNCTIONS

A function is similar to a procedure, except it returns only one value. A function can accept zero to many parameters, and it must return one and only one value. The data type of the return value must be declared in the header of the function.

Syntax for creating a function:

CREATE OR REPLACE FUNCTION <function name> (<parameter1 name> <mode> <data type>, <parameter1 name> <mode> <data type>,…) RETURN <function return value data type> IS

<Variable declarations>BEGIN

Page 8: CHAPTER 6 - SIUEbbordol/index/courses/563/Notes/…  · Web viewThe exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION

Executable CommandsRETURN (return value);…

EXCEPTIONException handlers

END.

It is not necessary for the RETURN statement to appear in the last line of the execution section, and there may also be more than one RETURN statement. Like procedure, OR REPLACE is optional when creating a function.

An example follows:

-- func1.sqlCREATE OR REPLACE FUNCTION myfunc1 RETURN NUMBERIS ret_sal NUMBER(10,2);BEGIN SELECT emp_salary INTO ret_sal FROM employee WHERE emp_ssn = '999666666'; RETURN (ret_sal);END myfunc1;/

The output of the above example is:

SQL> @func1

Function created.

SQL> var par_sal varchar2(20);SQL> EXECUTE :par_sal := myfunc2;

PL/SQL procedure successfully completed.

SQL> print par_sal;

par_sal---------- 55000

Like the procedure, we need to create a bind variable to hold the value returned from a function. In the above example, a variable par_sal is created for that purpose.

Page 9: CHAPTER 6 - SIUEbbordol/index/courses/563/Notes/…  · Web viewThe exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION

The following is an example of a function that accepts a parameter:

-- func2.sqlCREATE OR REPLACE FUNCTION myfunc2( i_dept_no NUMBER) RETURN varchar2IS dept VARCHAR2(20);BEGIN SELECT dpt_name INTO dept FROM department WHERE dpt_no = i_dept_no; RETURN (dept);END myfunc2;/

The output of the above example is:

SQL> @func2

Function created.

SQL> var par_dep varchar2(20);SQL> EXECUTE :par_dep := myfunc2(3);

PL/SQL procedure successfully completed.

SQL> print par_dep

PAR_DEP--------------------------------Admin and Records

DROPPING A FUNCTION

Syntax for dropping a function:

SQL>DROP FUNCTION <functionname>;

Oracle has some built-in functions, such as the numeric and aggregate functions. Please refer to Chapter 10 of Oracle SQL for more information. Also rememberthat some Oracle built-in functions, such as DECODE, cannot be used in PL/SQL program.

DATABASE TRIGGERS

Page 10: CHAPTER 6 - SIUEbbordol/index/courses/563/Notes/…  · Web viewThe exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION

A database trigger is a stored PL/SQL program unit associated with a specific database table. ORACLE executes (fires) a database trigger automatically when a given SQL operation (like INSERT, UPDATE or DELETE) affects the table. Unlike a procedure, or a function, which must be invoked explicitly, database triggers are invoked implicitly.

Database triggers can be used to perform any of the following: Audit data modification Log events transparently Enforce complex business rules Derive column values automatically Implement complex security authorizations Maintain replicate tables

You can associate up to 12 database triggers with a given table. A database trigger has three parts: a triggering event, an optional trigger constraint, and a trigger action. When an event occurs, a database trigger is fired, and an predefined PL/SQL block will perform the necessary action. The owner, not the current user, must have appropriate access to all objects referenced by the trigger action.

You cannot use COMMIT, ROLLBACK and SAVEPOINT statements within trigger blocks. You have to be careful with using triggers as it may be executed thousands of times for a large update, and therefore can seriously affect SQL execution performance.

The syntax for creating a trigger (the reserved words and phrases surrounded by brackets are optional):

CREATE [OR REPLACE] TRIGGER trigger_name{BEFORE|AFTER} triggering_event ON table_name[FOR EACH ROW][WHEN condition]DECLARE

Declaration statementsBEGIN

Executable statementsEXCEPTION

Exception-handling statementsEND;

The reserved word CREATE specifies that you are creating a new trigger. The reserved word REPLACE specifies that you are modifying an existing trigger. OR REPLACE is optional.

The trigger_name references the name of the trigger.

BEFORE or AFTER specify when the trigger is fired (before or after the triggering event).

Page 11: CHAPTER 6 - SIUEbbordol/index/courses/563/Notes/…  · Web viewThe exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION

The triggering_event references a DML statement issued against the table.

The table_name is the name of the table associated with the trigger.

The clause, FOR EACH ROW, specifies a trigger is a row trigger and fires once for each modified row.

A WHEN clause specifies the condition for a trigger to be fired.

Bear in mind that if you drop a table, all the associated triggers for the table are dropped as well.

PARTS OF A TRIGGER

A database trigger has three parts, namely, a trigger statement, a trigger body and a trigger restriction.

1. Trigger statement: The trigger statement specifies the DML statements like UPDATE, DELETE and INSERT, and it executes the trigger body if the condition is met.

2. Trigger Body: A trigger action is the procedure (PL/SQL block) that contains the SQL or PL/SQL code to be executed for a triggering statement. Like stored procedures, a trigger action can call SQL or PL/SQL statements, and define PL/SQL language constructs (variables, constants, cursors, exceptions, and so on).

3. Trigger restriction: Restrictions on a trigger can be set using the WHEN clause, as shown in the syntax for creating triggers. It basically specifies the condition under which the trigger should be fired.

TYPES OF TRIGGERS:

Triggers may be called BEFORE or AFTER the following events:

INSERT, UPDATE and DELETE.

The before/after options can be used to specify when the trigger body should be fired with respect to the triggering statement. If the user indicates a BEFORE option, then Oracle fires the trigger before executing the triggering statement. On the other hand, if an AFTER is used, Oracle fires the trigger after executing the triggering statement.

A trigger may be a ROW or STATEMENT type. If the statement FOR EACH ROW is present in the CREATE TRIGGER clause of a trigger, the trigger is a row trigger. A row trigger is fired for each row affected by an triggering statement.

A statement trigger, however, is fired only once for the triggering statement, regardless of the number of rows affected by the triggering statement. The following is an example of a statement trigger:

Page 12: CHAPTER 6 - SIUEbbordol/index/courses/563/Notes/…  · Web viewThe exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION

CREATE OR REPLACE TRIGGER mytrig1 BEFORE DELETE OR INSERT OR UPDATE ON employeeBEGIN IF (TO_CHAR(SYSDATE, 'day') IN ('sat', 'sun')) OR (TO_CHAR(SYSDATE,'hh:mi') NOT BETWEEN '08:30' AND '18:30') THEN RAISE_APPLICATION_ERROR(-20500, 'table is secured'); END IF;END;/

The above example shows a trigger that limits the DML actions to the employee table to weekdays from 8.30am to 6.30pm. If a user tries to insert/update/delete a row in the EMPLOYEE table, a warning message will be prompted. As exemplified above, you can customize error conditions via RAISE_APPLICATION_ERROR procedure to display an error number (which must be between -2001 and -20999) and an appropriate error message. Self Note : Give some more examples which use Exceptions (pp 542, Pl/SQL book)The following is an example of a row trigger:

CREATE OR REPLACE TRIGGER mytrig2 AFTER DELETE OR INSERT OR UPDATE ON employee FOR EACH ROWBEGIN IF DELETING THEN INSERT INTO xemployee (emp_ssn, emp_last_name,emp_first_name, deldate) VALUES (:old.emp_ssn, :old.emp_last_name,:old.emp_first_name, sysdate); ELSIF INSERTING THEN INSERT INTO nemployee (emp_ssn, emp_last_name,emp_first_name, adddate) VALUES (:new.emp_ssn, :new.emp_last_name,:new.emp_first_name, sysdate); ELSIF UPDATING('emp_salary') THEN INSERT INTO cemployee (emp_ssn, oldsalary, newsalary, up_date) VALUES (:old.emp_ssn,:old.emp_salary, :new.emp_salary, sysdate); ELSE INSERT INTO uemployee (emp_ssn, emp_address, up_date) VALUES (:old.emp_ssn, :new.emp_address, sysdate); END IF;END;/

The above trigger is used to keep track of all the transactions performed on the employee table. If any employee is deleted, a new row containing the details of this employee is stored in a table called xemployee. Similarly, if a new employee is inserted, a new row is created in another table called nemployee, and so on.

Page 13: CHAPTER 6 - SIUEbbordol/index/courses/563/Notes/…  · Web viewThe exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION

Note that we can specify the old and new values of an updated row by prefixing the column names with the :OLD and :NEW qualifiers.

The following is the output if we try to delete a record from the employee table. The details of the deleted employee are automatically inserted into the xemployee table (You must create the xemployee table first).

SQL> DELETE FROM employee WHERE emp_last_name = 'Joshi';

1 row deleted.

SQL> SELECT * FROM xemployee;

EMP_SSN EMP_LAST_NAME EMP_FIRST_NAME DELDATE------------- ------------------------- -------------------------- -----------------999333333 Joshi Dinesh 02-MAY-03

ENABLING AND DISABLING TRIGGERS

A trigger can be enables or disabled. An enabled trigger executes the trigger body if the triggering statement is issued. By default, triggers are enabled. A disabled trigger does not execute the trigger body even if the triggering statement is issued. We can disable a trigger using the following syntax:

SQL>ALTER TRIGGER trigger_name DISABLE;

We can issue the following syntax to disable all the triggers associated with the table,

SQL>ALTER TABLE table_name DISABLE ALL TRIGGERS;

To enable a trigger, which is disabled, we can use the following syntax:

SQL>ALTER TABLE table_name ENABLE trigger_name;

All triggers can be enabled for a specific table by using the following command

SQL> ALTER TABLE table_name ENABLE ALL TRIGGERS;

DROPPING TRIGGERS

The drop trigger command is used to drop a trigger from the database. The syntax is

SQL> DROP TRIGGER trigger_name;

Page 14: CHAPTER 6 - SIUEbbordol/index/courses/563/Notes/…  · Web viewThe exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION

PACKAGES

A package is a collection of PL/SQL objects grouped together under one package name. Packages include procedures, functions, cursors, declarations, types, and variables.

All of the variables that you have used so far are local variables, meaning they are visible only in the program in which they are declared. As soon as the program terminates, the memory used to store the variable is freed, and the variable cannot be accessed again. Sometimes it is necessary to have global variables, which can be shared among many PL/SQL programs. A global variable is declared using the same syntax as is used for declaring a local variable. While local variables are declared in the DECLARE section of an individual program, global variables are declared in the DECLARE section of a package.

PACKAGE SPECIFICATION

A package consists of a specification and a body. The package specification, also called the package header, declares global variables, cursors, procedures and functions that can be called or accessed by other program units.

Syntax:

PACKAGE <package name>IS

<variable declarations>;<cursor declarations>;<procedure and function declarations>;

END <package name>;

To declare a procedure in a package, you must specify the procedure name, followed by the parameters and variable types, using the following format:

PROCEDURE <procedure name> (param1 param1datatype, param2 param2datatype,…);

To declare a function in a package, you must specify the function name, parameters and return variable type as follows:

FUNCTION <function name> (param1 param1datatype, param2 param2datatype,…)RETURN <return data type>;

PACKAGE BODY

A package body contains the code for the programs declared in the package specification. The package body is optional. A package may have only package declarations and no programs.

Page 15: CHAPTER 6 - SIUEbbordol/index/courses/563/Notes/…  · Web viewThe exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION

Syntax:

PACKAGE BODY<package name>IS

<cursor specifications><module bodies>

END <package name>;

To create a package specification we use a variation on the CREATE command; all we need to put in the specification is each PL/SQL block header that will be public within the package. Procedures, functions, cursors, and variables that are declared in the package specification are global. They can be called, or used by external users that have the EXECUTE permission for the package, or that have EXECUTE ANY PROCEDURE privileges.

An example follows:

CREATE OR REPLACE PACKAGE pac_mag_empASPROCEDURE pro_find_ename( emp_id IN employee.emp_ssn%TYPE, employee_first_name OUT employee.emp_first_name%TYPE, employee_last_name OUT employee.emp_last_name%TYPE);FUNCTION fun_id_is_good( emp_id IN employee.emp_ssn%TYPE) RETURN BOOLEAN;END pac_mag_emp;/

To create a package body we now specify each PL/SQL block that makes up the package, note that we are not creating these blocks separately (no CREATE OR REPLACE is required for the procedure and function definitions).

The body of a package can contain the procedures declared in the package specification, functions declared in the package specification, definitions of cursors declared in the package specification, local procedures and functions not declared in the package specification and local variables.

An example follows:

CREATE OR REPLACE PACKAGE BODY pac_mag_empASPROCEDURE pro_find_ename( emp_id IN employee.emp_ssn%TYPE, employee_first_name OUT employee.emp_first_name%TYPE, employee_last_name OUT employee.emp_last_name%TYPE)

Page 16: CHAPTER 6 - SIUEbbordol/index/courses/563/Notes/…  · Web viewThe exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION

ISBEGIN SELECT emp_first_name,emp_last_name INTO employee_first_name, employee_last_name FROM employee WHERE emp_ssn = emp_id;EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Error in finding employee ssn: '||emp_id);END pro_find_ename;

FUNCTION fun_id_is_good( emp_id IN employee.emp_ssn%TYPE) RETURN BOOLEANIS v_id_cnt NUMBER;BEGIN SELECT COUNT(*) INTO v_id_cnt FROM employee WHERE emp_ssn = emp_id; RETURN (1 = v_id_cnt);EXCEPTION WHEN OTHERS THEN RETURN FALSE;END fun_id_is_good;END pac_mag_emp;/

CALLING STORED PACKAGES

To reference a variable, procedure or a function declared in the package specification, uswe the following notation:

<PACKAGE NAME>.<SUBPROGRAM NAME>

The following is an example of calling a procedure from another program:

-- findname.sqlSET SERVEROUTPUT ONDECLARE var_first_name employee.emp_first_name%type; var_last_name employee.emp_last_name%type;BEGIN pac_mag_emp.pro_find_ename(‘999666666’,var_first_name, var_last_name); DBMS_OUTPUT.PUT_LINE('The value returned is ' || var_first_name || var_last_name);

Page 17: CHAPTER 6 - SIUEbbordol/index/courses/563/Notes/…  · Web viewThe exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION

END;/

The output of the above example is:

SQL> @findname

The value returned is BijoyBordoloi

CURSORS IN PACKAGES

As we have learned in Chapter 2, a cursor is used to populate the result set of a multi-row query. However, a cursor is static because it is tied to a specific query inside a function or procedure. To make a cursor more dynamic (i.e. reusable and sharable among different procedures and functions), like placing a procedure or a function in a package, we can use a cursor variable.

A cursor variable has datatype REF CURSOR. It is like a pointer in C language, and it points to a query work area in which the result set is stored. Therefore, it can be passed freely as a parameter to other subprograms.

To create a cursor variable, you have to define a REF CURSOR type, followed by a cursor variable of that type.

The syntax for defining a REF CURSOR type:

TYPE ref_type_name IS REF CURSOR [RETURN <return_type>];

where <return_type> represents a row in a database table.

An example of cursor variable:

DECLARE TYPE item_val_cv_type IS REF CURSOR RETURN equipment%ROWTYPE; item_cv IN OUT item_val_cv_type;

This following example demonstrates the use of REF Cursors. It prints the equipment description for the equipment number assigned by the user.

-- pac_item_data.sqlCREATE OR REPLACE PACKAGE item_data AS TYPE item_val_cv_type IS REF CURSOR RETURN equipment%ROWTYPE; PROCEDURE open_item_cv ( item_cv IN OUT item_val_cv_type, item_number IN varchar2); --Note the cursor variable is IN OUT parameter that means it has some one in it after

Page 18: CHAPTER 6 - SIUEbbordol/index/courses/563/Notes/…  · Web viewThe exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION

--the procedure gets execited. It is this value which is inputed into the next preocedure. PROCEDURE fetch_item_data( item_cv IN item_val_cv_type, item_row OUT equipment%ROWTYPE);END item_data;/CREATE OR REPLACE PACKAGE BODY item_data AS PROCEDURE open_item_cv ( item_cv IN OUT item_val_cv_type, item_number IN varchar2) IS BEGIN -- here is where the cursor gets populated. OPEN item_cv FOR SELECT * FROM equipment WHERE eqp_no = item_number; END open_item_cv; PROCEDURE fetch_item_data ( item_cv IN item_val_cv_type,item_row OUT equipment%ROWTYPE) IS BEGIN FETCH item_cv INTO item_row; END fetch_item_data;END item_data;/SET SERVEROUTPUT ONDECLARE -- declare a cursor variable item_curs item_data.item_val_cv_type; item_number equipment.eqp_no%TYPE; item_row equipment%ROWTYPE;BEGIN item_number := '4321'; -- open the cursor using a variable item_data.open_item_cv(item_curs,item_number); -- fetch the data and display it LOOP item_data.fetch_item_data(item_curs,item_row); EXIT WHEN item_curs%NOTFOUND; DBMS_OUTPUT.PUT(item_row.eqp_no || ' '); DBMS_OUTPUT.PUT_LINE(item_row.eqp_description); END LOOP; END;/

The output of the above example is:

Page 19: CHAPTER 6 - SIUEbbordol/index/courses/563/Notes/…  · Web viewThe exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION

SQL> @pac_item_data

Package created.

Package body created.

4321 Computer, PC

PL/SQL procedure successfully completed.

ADVANTAGES OF PACKAGES1. Modularity - A package allows us to encapsulate related subprograms. As a result,

each package will help us to understand the concepts involved in an application in a better manner

2. Easier application handling - To design the application, we must first specify the objects or subprograms in the package specification. Once the specification has been compiled, stored subprograms that refer to the package can be compiled. Therefore, we need not define the package body completely, until we are ready with the specification of the application. In other words, we can code and compile a package specification without its body

3. Information hiding - We are aware of private and public objects. These objects can be used to protect the integrity of the package. For example, consider that out package consists of four subprograms, three public and one private subprogram. The package hides the definition of the private subprogram so that only the package (not out application) is affected if the definition changes. Thus, the implementation details are hidden from other users, thereby protecting the integrity of the package.

4. Added functionality - Public objects and cursors declared in the package specification can be shared by all procedures that are executed in the environment because they persist for the duration of a session.

5. Better performance - When we call a packaged program for the first time, the whole package is loaded in the memory. Therefore, subsequent calls require no disk input/output.

Summary: In this chapter, we have learned how to create, replace and drop a procedure, function, triggers, and packages.

Page 20: CHAPTER 6 - SIUEbbordol/index/courses/563/Notes/…  · Web viewThe exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION

REVIEW EXERCISES

Learn Theses Terms

1. Procedure: Procedures are simply named PL/SQL blocks.2. Functions: A function is similar to a procedure, except that when it is called, it returns

a single value that is assigned to a variable.3. IN: Parameter is passed to the procedure as a read-only value that cannot be changed

with in the procedure.4. OUT: Parameter is a write-only value that can only appear on the left side of an

assignment statement in the procedure.5. IN OUT: Combination of IN and OUT; the parameter is passed to the procedure, and

its value can be changed within the procedure.6. Package body: The package body contains the code for the programs declared in the

package specification.7. Package specification: The package specification, also called the package header,

declares global variables, cursors, procedures and functions that can be called or accessed by other program units.

8. Trigger: A trigger is PL/SQL code block attached and executed by an event, which occurs to a database table.

9. Row Trigger: A row trigger is fired as many times as there are rows affected by the triggering statement.

10. Statement Trigger: A statement trigger is fired once for the triggering statement. In other words, a statement trigger fires once, regardless of the number of rows affected by the triggering statement.

Concepts Quiz:

1. What is the distinguishing characteristic that makes functions different from procedures? (check all that apply)

a. Functions require a PRAGMA RESTRICT clause.b. Functions only take IN parameters.c. Functions are stored in the database.d. Functions require a return value.e. None of the above.

2. What statement(s) will cause control to return to the calling environment in a function?

a. The raising of an exception.b. The initialization of an OUT parameter.c. Writing to a database table.d. The RETURN statement.e. None of the above.

3. If a procedure has an IN parameter, then it must have an OUT parameter.a. Trueb. False

Page 21: CHAPTER 6 - SIUEbbordol/index/courses/563/Notes/…  · Web viewThe exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION

4. If a function declares a user-defined exception but never explicitly raises the exception, which of the following will be true?

a. The function will not be able to compile.b. The function will fail a purity level check.c. The exception will never be raised.d. As long as the exception has a RETURN clause, there is no error in having a

user-defined exception and not calling it.5. IN OUT parameters are permissible in functions.

a. Trueb. Falsec. The function will compile with an IN OUT parameter, but it is not advisable

to use them.6. Assume a trigger named mytrig1 already exists in the database. If you use the

CREATE clause to modify the existing trigger, what error message is generated? Explain your answer.

7. All procedures and functions in a package body must be declared in the package specification.

a. Trueb. False

8. The main advantages to grouping procedures and functions into packages are as follows (check all that apply):

a. It follows the trendy object method of programming.b. It is a more efficient way of utilizing the processor memory.c. It makes greater use of the security privileges of various users.d. It is a more efficient method to maximize tablespace storage.e. It keeps you on good terms with the DBA.

9. The package specification is merely a formality for other programmers to let them know what parameters are being passed in and out of the procedures and functions. It hides the program logic but in actuality it is not necessary and is incorporated into the package body.

a. Trueb. False

10. A trigger can fire for which of the following?a. Before a triggering event.b. After a triggering event.c. Before or after a triggering event.

11. How many times does a row trigger fire if a DML (INSERT, UPDATE, or DELETE) operation is issued against a table?

a. As many times as there are rows affected by the DML operation.b. Once per DML operation.

12. How many times does a statement trigger fire if a DML (INSERT, UPDATE, or DELETE) operation is issued against a table?

a. As many times as there are rows affected by the DML operation.b. Once per DML operation.

Page 22: CHAPTER 6 - SIUEbbordol/index/courses/563/Notes/…  · Web viewThe exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION

Coding Exercises and Questions

1. [easy] Write a function incr_salary, which takes two parameters, employee ssn and the percentage by which the salary needs to be raised and returns the new salary.

2. [easy] Write a procedure Get_On_Hand that has one IN and one OUT parameter. This procedure should take in equipment number and send the quantity on hand for this equipment through the out parameter.

3. [easy] Write a procedure called emp_dept which has one IN and one OUT parameter. This procedure should take in employee ssn and send the name of the department he is working for by getting it from the department table.

4. [easy] Write a trigger, which checks the quantity on hand in the equipment table for every update and displays an error message if the quantity on hand falls below 2.

5. [easy] Write a trigger, which fires before the update of employee table for each row and checks if the new salary is below 20000, if it is then it raises an error.

6. [moderate] Write a trigger on the department table which fires after deleting a row and stores the information of this department into a new table ‘xdept’ which has the same structure as that of the department and an additional field called deldate which stores the date the department is deleted.

7. [moderate] Write a package which has one procedure and one function in it. The procedure should take an employees ssn and return his name and department number. The function is to take employees ssn and a percentage by which his salary is to be raised and raise his salary accordingly and return the new salary.

8. [easy] Create a procedure to find out the SSN of the dept manager for an employee. In other words, write a procedure that takes an employee’s SSN as the input variable, and return the SSN of his or her dept manager using the same variable. Return ‘-1’ if no dept manager can be found.

9. [easy] The employees’ salary is to be classified as following:Class A: <= 30000Class B: > 30000 and <= 60000Class C: > 60000

Create a function to return the class of a salary for an employee, given his or her SSN.10. [moderate] Assuming each department is granted only 5000 dollar for purchasing

PCs, create a function to check if a new row can be added to the equipment table. In other words, create a function that takes a dept_no, eqp_qty_on_hand and eqp_value as the parameters, and returns a 0 if the total value (after adding the row) does not exceed the allowance, and return –1 if it does.

11. [easy] Create a trigger to ensure that no department manager or employee starts on Saturday and Sunday.

12. [moderate] Create a trigger to limit 5 assignments to one employee.13. [moderate] Create two tables, LT_ASGN_HISTORY and ASGN_HISTORY, both

with the following columns:

Column Name Datatype Size Commentswork_emp_ssn CHAR 9 Primary Key. Employee social security number.

Also Composite Foreign Key link to assignment table

Page 23: CHAPTER 6 - SIUEbbordol/index/courses/563/Notes/…  · Web viewThe exception-handling part contains the exception handlers, which should be placed between the keywords EXCEPTION

work_pro_number NUMBER

2 Primary Key. Project number. Also Composite Foreign Key link to assignment table.

work_hours_completed

NUMBER

(5,1)

Number of hours an employee has completed on a project.

date_last_updated DATE Primary Key. Date when this row is changed.

Create a trigger that does the following:When the work_hours_planned becomes 0, (not NULL, assuming that a work_hours_planned with NULL values means it is not assigned yet, while work_hours_planned = 0 means the assignment has been completed),

a. If the total work hours exceed 100, insert a new record to LT_ASGN_HISTORY (long term assignment history).

b. Else insert a new record to ASGN_HISTORY.

14. [easy] Create a procedure that calculate the total work hours planned for an employee given his or her ssn.