PL/SQL PL/SQL stands for Procedural Language/SQL.

PL/SQL extends SQL by adding control Structures found in other procedural language.PL/SQL combines the flexibility of SQL with Powerful feature of 3rd generation Language. The procedural construct and database access Are present in PL/SQL.PL/SQL can be used in both in database in Oracle Server and in Client side application development tools. Advantages of PL/SQL Support for SQL, support for object-oriented programming,, better performance, portability, higher productivity, Integration with Oracle a] Supports the declaration and manipulation of object types and collections. b] Allows the calling of external functions and procedures. c] Contains new libraries of built in packages. d] with PL/SQL , an multiple sql statements can be processed in a single command line statement. Oracle Supports PL/SQL version 8.0.4.0.0 PL/SQL Datatypes Scalar Types BINARY_INTEGER ,DEC,DECIMAL,DOUBLE ,,PRECISION,FLOAT,INT,INTEGER,NATURAL, NATURALN,NUMBER, NUMERIC, PLS_INTEGER,POSITIVE,POSITIVEN,REAL,SIGNTYPE, SMALLINT,CHAR,CHARACTER,LONG,LONG RAW,NCHAR,NVARCHAR2,RAW,ROWID,STRING, VARCHAR,VARCHAR2, Composite Types TABLE, VARRAY, RECORD LOB Types BFILE, BLOB, CLOB, NCLOB Reference Types REF CURSOR BOOLEAN, DATE DBMS_OUTPUT.PUT_LINE : It is a pre-defined package that prints the message inside the parenthesis ATTRIBUTES Allow us to refer to data types and objects from the database.PL/SQL variables and Constants can have attributes. The main advantage of using Attributes is even if you Change the data definition, you don’t need to change in the application. %TYPE It is used when declaring variables that refer to the database columns. Using %TYPE to declare variable has two advantages. First, you need not know the exact datatype of variable. Second, if the database definition of variable changes, the datatype of variable changes accordingly at run time. %ROWTYPE The %ROWTYPE attribute provides a record type that represents a row in a table (or view). The record can store an entire row of data selected from the table or fetched from a cursor or strongly typed cursor variable.

1

CONTROL STRUCTURES Conditional Control Sequence of statements can be executed based on a certain condition using the if statement.There are three forms of if statements, namely, if then,if then else and if the Elsif. ITERATIVE CONTROL A sequence of statements can be executed any number of times using loop constructs. Loops can be broadly classified into: • Simple Loops , For Loops , While Loops Simple Loops Key Word loop should be placed before the first statement in the sequence and the key word end loop after the last statement in the sequence. EXIT : It is a command that comes out of the loop. While Loop This statement includes a condition associated with a sequence of statement. If the Condition evaluates to true, then the sequence of statements will be executed, and again Control resumes at the beginning of the loop else the loop is bypassed and control passes To next statement. For Loop The number of iterations for a while loop is unknown until the loop terminates, whereas The number of iterations in a for loop is known before the loop gets executed. The for loop statement specifies a range of integers, to execute the sequence of statements once for each integer. REVERSE: Reverse key word is used to print the values from upper bound to lower bound. EXCEPTION An Exception is raised when an error occurs. In case of an error then normal execution stops and the control is immediately transferred to the exception handling part of the PL/SQL Block. Exceptions are designed for runtime handling, rather than compile time handling. Exceptions improve readability by letting you isolate error-handling routines. Types Pre-defined Exception, User-defined Exception USER – DEFINED EXCEPTIONS User – defined exception must be defined and explicitly raised by the user EXCEPTION_INIT A named exception can be associated with a particular oracle error. This can be used to trap the error specifically. PRAGMA EXCEPTION_INIT(exception_name, Oracle_error_number); The pragma EXCEPTION_INIT associates an exception name with an Oracle,error number. That allows you to refer to any internal exception by name and to write a specific handler RAISE_APPLICATION_ERROR The procedure raise_application_error lets you issue user-defined error messages from stored subprograms. That way, you can report errors to your application and avoid returning unhandled exceptions. To call raise_application_error, you use the syntax raise_application_error(error_number, message[, {TRUE | FALSE}]); 2

where error_number is a negative integer in the range -20000 .. -20999 and message is a character string up to 2048 bytes long. PRE – DEFINED EXCEPTIONS

3

WHEN OTHERS THEN -. Unhandled Exceptions PL/SQL returns an unhandled exception error to the host environment.handle the error END. Handling Raised Exceptions When an exception is raised. EXCEPTION WHEN deadlock_detected THEN -. which determines the outcome.. SQLCODE returns the number of the Oracle error. SQLERRM returns the corresponding error message. THEN RAISE out_of_balance. PRAGMA EXCEPTION_INIT – EGS DECLARE deadlock_detected EXCEPTION.another handler sequence_of_statements2 . EXCEPTION WHEN out_of_balance THEN -. The pointer that points to the context area is a cursor. CURSORS Oracle allocates an area of memory known as context area for the processing of SQL statements. in which case SQLCODE returns +100. -.handle the error END. whichis formatted as follows: EXCEPTION WHEN exception_name1 THEN -.raise the exception END IF.. The message begins with the Oracle error code.handler sequence_of_statements1 WHEN exception_name2 THEN -.. PRAGMA EXCEPTION_INIT(deadlock_detected. BEGIN IF ..EG DECLARE out_of_balance EXCEPTION. BEGIN . The number that SQLCODE returns is negative unless the Oracle error is no data found.USER DEFINED EXCEPTION .. -60).. When Others It is used when all exception are to be trapped.optional handler sequence_of_statements3 Using SQLCODE and SQLERRM For internal exceptions. 4 . TYPES 1 ] Static Cursor • EXPLICIT • IMPLICIT 2] Dynamic Cursors 3] REF Cursors. normal execution of your PL/SQL block or subprogram stops and control transfers to its exception-handling part.

EMPNO). Usage . To refer an element of the record use <record name.If the SELECT statement returns more that one row then explicit cursor should be used.ENAME). 3] Supporting data modification to the rows at the current position in the result set. DBMS_OUTPUT. END LOOP.PUT_LINE(ROW1.column name> EXPLICIT CURSOR WITH FOR LOOP DECLARE CURSOR C1 IS SELECT EMPNO.SAL FROM EMP. DBMS_OUTPUT. A] EXPLICIT EXPLICIT CURSOR -Multiple row SELECT statement is called as an explicit cursor. BEGIN FOR ROW1 IN C1 LOOP DBMS_OUTPUT. SYNTAX FOR <RECORD NAME> IN <CURSOR NAME> LOOP STATEMENTS END LOOP.PUT_LINE(ROW1. END LOOP.PUT_LINE(ROW1.ENAME. 2] Returning one row or block of rows from the current position in the result set.PUT_LINE(ROW1. fetches the rows and closes the cursor automatically. Steps • • • • Declare a cursor Open a cursor Fetch data from the cursor Close the cursor Syntax CURSOR <CURSOR NAME> IS <SELECT STATEMENT> OPEN <CURSOR NAME> FETCH <CURSOR NAME> INTO <COLUMN NAMES> CLOSE <CURSOR NAME> EXPLICIT CURSOR ATTRIBUTES • %FOUND (Returns true if the cursor has a value) • %NOTFOUND (Returns true if the cursor does not contain any value) • %ROWCOUNT (Returns the number of rows selected by the cursor) • %ISOPEN (Returns the cursor is opened or not) CURSOR FOR LOOPS A cursor FOR loop implicitly opens a cursor.SAL FROM EMP) LOOP DBMS_OUTPUT. TYPES 1] STATIC CURSOR SQL statement is determined at design time.ENAME.Merits 1] Allowing to position at specific rows of the result set. WITH FOR LOOP USING SUBQUERIES 5 .EMPNO).ENAME). EXPLICIT CURSOR BEGIN FOR ROW1 IN (SELECT EMPNO. END.

EMPNO%TYPE.DNO. COMMIT. LOOP EXIT WHEN C1%ROWCOUNT=5 OR C1%NOTFOUND.SAL1. END IF.SAL. EMPNAME EMP. SAL1 EMP.50 WHERE DEPTNO=&DNO. B ] IMPLICIT CURSOR An IMPLICIT cursor is associated with any SQL DML statement that does not have a explicit cursor associated with it. 6 . IF SQL%NOTFOUND THEN DBMS_OUTPUT.DNO).DEPTNO%TYPE. This includes : " All INSERT statements " All UPDATE statements " All DELETE statements IMPLICIT CURSOR ATTRIBUTES " SQL%FOUND (Returns true if the DML operation is valid) " SQL%NOTFOUND (Returns true if the DML operation is invalid) " SQL%ROWCOUNT (Returns the no. FETCH C1 INTO ENO. Sucessfully Updated ' ).IMPLICIT BEGIN UPDATE EMP51 SET SAL=SAL+50. SQL%ROWCOUNT . END. SALARY ' || SAL1).PUT_LINE(SQL%ROWCOUNT ||' Rows END IF.PUT_LINE(SQL%ROWCOUNT ||' Rows ELSif SQL%FOUND THEN DBMS_OUTPUT. CLOSE C1.EMPNAME. BEGIN OPEN C1. EXPLICIT CURSOR ROW POSITIONING DECLARE CURSOR C1 IS SELECT EMPNO.PUT_LINE('Invalid Salary Updation' ). of rows affected by the DML operation) SQL%FOUND .PUT_LINE('EMPNO ' || ENO ||' EMPNAME ' || EMPNAME ||' INSERT INTO EMP51 VALUES(ENO. END. IF SQL%NOTFOUND THEN DBMS_OUTPUT.IMPLICIT BEGIN UPDATE EMP51 SET SAL=SAL+50.ENAME. DNO EMP.SAL%TYPE.SAL1. DBMS_OUTPUT.ENAME%TYPE.EMPNAME. ENO EMP.END. END LOOP.DEPTNO FROM EMP ORDER BY sal. ELSif SQL%FOUND THEN DBMS_OUTPUT.50 WHERE DEPTNO=&Department_No.PUT_LINE('Sucessfully Updated' ). Sucessfully Updated ' ). END.

Ref Cursor Ref are the best way of uniqely referring to object instances. Oracle Forms application.ENAME%TYPE. DBMS_OUTPUT. Neither PL/SQL nor any of its clients owns a result set. which points to the work area. LOOP FETCH C1 INTO ENO. you use cursor variables to pass query result sets between PL/SQL stored subprograms and various clients. a] Strong Cursor .ENAME1. ESAL EMP.Whose return type not specified.SAL FROM EMP WHERE DEPTNO=DNO. OPEN C1. EXIT WHEN C1%NOTFOUND. a pointer has datatype REF X. ENO EMP. an OCI client.PUT_LINE(C1%ROWCOUNT).ENAME.It is only supported way of getting at OID ( object identifier ). To execute a multi-row query. b] Week Cursor . ELSE UPDATE EMP SET COMM=SAL*.DEPTNO%TYPE:=&DEPT_NO. you can use a cursor variable. ENAME1 EMP. To access the information.A SQL statement is dynamic. END LOOP. CLOSE C1. For example.Like VALUE.5 WHERE DEPTNO=DNO AND (SAL>1500).PUT_LINE(ENO). END IF. DBMS_OUTPUT.4 WHERE DEPTNO=DNO AND (SAL>1200 AND SAL<=1500). 7 . they simply share a pointer to the query work area in which the result set is stored.ESAL. BEGIN END. you can use an explicit cursor. CURSOR C1 IS SELECT EMPNO.it return the value of an object.Unlike value. Therefore. IF ESAL<1200 THEN UPDATE EMP SET COMM=SAL*. where REF is short for REFERENCE and X stands for a class of objects. COMMIT.you DREF.UPDATION DECLARE DNO EMP.It is a effecient and light means of passing object information as a information Dref It is the 'deference operator. if it is constructed at run time and then executed.Whose return type specified. 2 ]DYNAMIC CURSOR Dynamic Cursor can be used along with DBMS_SQL package .6 WHERE DEPTNO=DNO AND (SAL<1200).PUT_LINE(ENAME1). In PL/SQL. Oracle opens an unnamed work area that stores processing information. ELSIF ESAL>1200 AND ESAL<=1500 THEN UPDATE EMP SET COMM=SAL*. 3 ] REF CURSOR Declaring a cursor variable creates a pointer. Or. which names the work area.EXPLCIT CURSOR . Dref's input is a REF to an column in a table and you want reterive the target instead of the pointer. DBMS_OUTPUT. a cursor variable has datatype REF CURSOR.EMPNO%TYPE. Mainly.SAL%TYPE. and Oracle Server can all refer to the same work area. not an item.

PUT_LINE('=========================='). A1 NUMBER.DNAME. EXIT WHEN A%NOTFOUND. DBMS_OUTPUT.C1.PUT_LINE('ID LOCNAME COUNTRY').B1. END. DBMS_OUTPUT.1 DECLARE TYPE RE1 IS REF CURSOR. '||B1||' '||C1).PUT_LINE('=========================='). / REF CURSOR .C1. OPEN SQL_STMT FOR SELECT EMPNO.PUT_LINE(A1||' '||B1||' '||C1). END LOOP. / LOOP '||C1).PUT_LINE(A1||' '||B1||' END LOOP. DBMS_OUTPUT. DBMS_OUTPUT.REF CURSOR .CLOSE SQL_STMT. B RE1. B1 VARCHAR2(20). EXIT WHEN SQL_STMT%NOTFOUND.B1. C1 VARCHAR2(20).PUT_LINE(A1||' '||B1||' '||C1).PUT_LINE(A1||' END LOOP. A1 NUMBER. C1 VARCHAR2(20). LOOP FETCH A INTO A1. LOOP FETCH SQL_STMT INTO A1. BEGIN DBMS_OUTPUT.B1.C1.JOB FROM EMP. SQL_STMT RE1.COUNTRY FROM LOCMAST.ENAME. DBMS_OUTPUT. OPEN SQL_STMT FOR SELECT LOCID. EXIT WHEN SQL_STMT%NOTFOUND.PUT_LINE('==========================').LOC_NAME. B1 VARCHAR2(20). CLOSE A.CLOSE SQL_STMT. BEGIN OPEN A FOR SELECT EMPNO.2 CREATE OR REPLACE PROCEDURE PREF2 IS TYPE RE1 IS REF CURSOR.C1. DBMS_OUTPUT. OPEN SQL_STMT FOR SELECT DEPTNO. 8 .ENAME. A RE1.LOC FROM DEPT.JOB FROM EMP. LOOP FETCH SQL_STMT INTO A1. ----. DBMS_OUTPUT. FETCH SQL_STMT INTO A1.B1.PUT_LINE('------------------------------------------------'). DBMS_OUTPUT. END LOOP. ------CLOSE SQL_STMT. END. ----. EXIT WHEN SQL_STMT%NOTFOUND.

Merits Reusability Subprograms once executed can be used in any number of applications Maintainability . END LOOP.REF CURSOR . SQL_STMT RE1. B1 VARCHAR2(20).PUT_LINE('=========================='). LOOP FETCH SQL_STMT INTO A1. A1 NUMBER. OPEN SQL_STMT FOR SELECT DEPTNO. EXCEPTION WHEN NO_DATA_FOUND THEN RAISE_APPLICATION_ERROR(-20023.DNAME.C1. OPEN SQL_STMT FOR SELECT EMPNO.PUT_LINE('=========================='). EXAMPLE FOR IN PARAMETER CREATE OR REPLACE PROCEDURE P1 (ENO IN EMP51.C1. ------CLOSE SQL_STMT.PUT_LINE(A1||' '||B1||' '||C1).B1. SUB PROGRAMS 1 ] PROCEDURES Procedure is a subprogram that contains set of SQL and PL/SQL statements.JOB FROM EMP WHERE DEPTNO=DNO. DBMS_OUTPUT.DEPTNO%TYPE) IS TYPE RE1 IS REF CURSOR. BEGIN DBMS_OUTPUT. ----.3 [ With Procedure ] CREATE OR REPLACE PROCEDURE PREF1(DNO DEPT. Exec pref1(20).ENAME.B1. LOOP FETCH SQL_STMT INTO A1.EMPNO%TYPE) IS 9 . IS CREATE OR REPLACE PROCEDURE <PROCEDURE NAME>[PARAM LIST] <local declarations> begin executable statement end.PUT_LINE('==========================').LOC FROM DEPT WHERE DEPTNO=DNO.CLOSE SQL_STMT.PUT_LINE(A1||' '||B1||' '||C1). subprogram will be affected only its definition changes Parameter IN OUT IN OUT SYNTAX The IN parameter is used to pass values to a subprogram when it is invoked The OUT parameter is used to return values to the caller of a subprogram The IN OUT parameter is used to pass initial values to the subprogram when invoked and also it returns updated values to the caller.'INVALID DEPARTMENT NUMBER'). C1 VARCHAR2(20). EXIT WHEN SQL_STMT%NOTFOUND. DBMS_OUTPUT. DBMS_OUTPUT. DBMS_OUTPUT. / Exec pref1(10).Subprogram can simplify maintenance. END LOOP. EXIT WHEN SQL_STMT%NOTFOUND. END.

SAL FROM EMP WHERE DEPTNO=DNO. END.:GNAME). TRY AGAIN').'SALES1').BODY . ELSE B1:=B1-100.PUT_LINE('NO EMPS' ). EXEC P1004(10. 10 . A NUMBER:=&AA. BEGIN SELECT SAL INTO B1 FROM EMP WHERE EMPNO=A1. Procedure .IN OUT .ENAME%TYPE) IS BEGIN SELECT ENAME INTO ENAME1 from emp51 WHERE EMPNO=ENO.DEPTNO%TYPE) IS DNO EMP. END.Exception – Raise Application Error . CURSOR C1 IS SELECT EMPNO.PUT_LINE('MORE ROWS').01 WHERE EMPNO=ENO. EXAMPLE FOR OUT PARAMETER – EXECUTION / BODY SQL> VARIABLE GNAME VARCHAR2(25) SQL> EXECUTE P50(7000. EXAMPLE FOR OUT PARAMETER . PROCEDURE . END. Procedure . EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT. END IF.IN .SPECIFICATION CREATE OR REPLACE PROCEDURE P50 (ENO IN EMP51.Implicit Cursor . PROCEDURE .DEPTNO%TYPE.B).DNAME%TYPE) IS BEGIN UPDATE DEPT SET DNAME=B1 WHERE DEPTNO=A1.Put_Line(ENAME1).SPECIFICATION CREATE OR REPLACE PROCEDURE P1002(A1 IN EMP. ENAME1 OUT EMP51.ENAME.Explicit Cursor for loop -Update CREATE OR REPLACE PROCEDURE P1007(DNO1 DEPT. END. IF B1<2000 THEN B1:=B1+200.EMPNO%TYPE. Dbms_output. IMPLICIT CURSOR CREATE OR REPLACE PROCEDURE P1004(A1 IN DEPT. DBMS_OUTPUT.PUT_LINE(B). END. IF SQL%ROWCOUNT=0 THEN RAISE_APPLICATION_ERROR(-20204.BEGIN UPDATE EMP51 SET SAL=SAL+SAL*.SAL%TYPE) IS C1 NUMBER.B1 IN DEPT.'INVALID UPDATES. EXCEPTION WHEN TOO_MANY_ROWS THEN DBMS_OUTPUT.B1 IN OUT EMP.IN OUT . END IF. BEGIN P1002(A. DBMS_OUTPUT.IMPLEMENTATION DECLARE B NUMBER.EMPNO%TYPE.DEPTNO%TYPE:=DNO1.PUT_LINE(SQL%ROWCOUNT).

BEGIN R1 C1%ROWTYPE.. Functions and procedures are structured alike. FUNCTION NAME [(PARAMETER[. Functions Advantage EXAMPLES Function – Specification Function is a subprogram that computes and returns a single value..SAL%TYPE.])] RETURN DATATYPE IS [LOCAL DECLARATIONS] BEGIN EXECUTABLE STATEMENTS [EXCEPTION EXCEPTION HANDLERS] A function has two parts: the specification and the body. FOR R1 IN C1 LOOP EXIT WHEN C1%ROWCOUNT>1. The function body begins with the keyword IS and ends with the keyword END followed by an optional function name.PUT_LINE(A).075 WHERE DEPTNO=DNO AND (SAL>1000 AND SAL<=3000). BEGIN A:=F1000(&EMPNO). The function specification begins with the keyword FUNCTION and ends with the RETURN clause. RETURN ESAL. VIEW SOURCE CODE FOR PROCEDURES SELECT TEXT FROM USER_SOURCE WHERE NAME='&P1' AND TYPE=’PROCEDURE’ FUNCTIONS Function is a subprogram that computes and returns a single value. Functions that take no parameters are written without parentheses. . Parameter declarations are optional. except that functions have a RETURN clause. 11 . Function – . END LOOP. BEGIN SELECT SAL INTO ESAL FROM EMP WHERE EMPNO=ENO. Reusability CREATE OR REPLACE FUNCTION F1000(ENO NUMBER) RETURN NUMBER IS ESAL EMP. A function is a subprogram that computes a value. END.'THIS EMPLOYEE ID NOT EXITST'). DBMS_OUTPUT. PARAMETER. which specifies the datatype of the result value.PUT_LINE(SQL%ROWCOUNT). END. Function – Body DECLARE A NUMBER. DBMS_OUTPUT. UPDATE EMP SET COMM=SAL*.08). EXCEPTION WHEN NO_DATA_FOUND THEN RAISE_APPLICATION_ERROR(-20345.Specification CREATE OR REPLACE FUNCTION F1001(P_VALUE IN NUMBER) RETURN NUMBER IS BEGIN RETURN (P_VALUE*0. END. COMMIT.

The scope of these declarations is local to your database schema and global to the package. and subprograms.ENAME. Benefits of Stored Procedures and Functions In addition to modularizing application development. Packages usually have two parts. and subprograms are public (visible and accessible) or private (hidden and inaccessible). rather than by retrieving the data into an application • Increases efficiency of queries by performing functions in the query rather than in the application • Manipulates new types of data (for example. or not at all. Advantages • Permits calculations that are too complex. • Modify routines online without interfering with other users • Modify one routine to affect multiple applications • Modify one routine to eliminate duplicate testing • Improved data security and integrity • • Control indirect access to database objects from non privileged users with security privileges Ensure that related actions are performed together. Anywhere a built-in SQL function can be placed.SAL. you can specify which types. items. stored procedures and functions have the following benefits: • Improved performance • Avoid reparsing for multiple users by exploiting the shared SQL area • 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 • Improved maintenance. a specification and a body. PACKAGE A package is a schema object that groups logically related PL/SQL types. you protect the integrity of the package.END. 12 . So. or unavailable with SQL • Increases data independence by processing complex data analysis within the Oracle Server.COMM. Parts of Package Parts of Package PACKAGE SPECIFICATION The package specification contains public declarations. by funneling activity for related tables through a single path Calling Stored Functions from SQL Expressions SQL expressions can reference PL/SQL user-defined functions. Merits Simplify security Limit recompilation Performance Information Hiding Hiding No need to issue GRANT for every procedure in a package Change the body of the procedure or function without changing specification First call to package loads whole package into memory With packages. items. Implementation details from users. a userdefined function can be placed as well. latitude and longitude) by encoding character strings and using functions to operate on the strings.F1001(SAL) FROM EMP WHERE DEPTNO=10. awkward. the declared items are accessible from your application and from anywhere in the package. Function – Execution at SQL*Plus SQL>SELECT EMPNO.

MNAME OUT VARCHAR2). RETURN (SL).PUT_LINE (ENAME1). / 13 . DBMS_OUTPUT. PRAGMA RESTRICT_REFERENCES(MY_FUNC.WNPS). the package body contains the definition of every cursor and subprogram declared in the package specification.PUT_LINE (ESAL). END MY_PROC. BEGIN SELECT SAL INTO ESAL FROM EMP WHERE EMPNO=A1. END P1101. CREATE OR REPLACE PACKAGE PC1000 IS PROCEDURE P1100 (A1 IN NUMBER).SAL%TYPE. END PC1000.THE PACKAGE BODY The package body implements the package specification. FUNCTION MY_FUNC(MDEPTNO IN NUMBER) RETURN NUMBER. BEGIN SELECT ENAME INTO ENAME1 FROM EMP WHERE EMPNO=A1.PUT_LINE ('EMPNO NO NOT EXISTS'). PROCEDURE MY_PROC(MEMPNO IN NUMBER.PUT_LINE ('EMPNO NO NOT EXISTS'). Keep in mind that subprograms defined in a package body are accessible outside the package only if their specifications also appear in the package specification. MNAME OUT VARCHAR2) IS BEGIN SELECT ENAME INTO MNAME FROM EMP WHERE EMPNO=MEMPNO. EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT. END MY_PACK. FUNCTION MY_FUNC(MDEPTNO IN NUMBER) RETURN NUMBER IS SL NUMBER. / show err CREATE OR REPLACE PACKAGE BODY PC1000 IS PROCEDURE P1100 (A1 IN NUMBER) IS ENAME1 EMP. END MY_PACK. EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT. END P1100. BEGIN SELECT SUM(SAL) INTO SL FROM EMP WHERE DEPTNO = MY_PACK. PROCEDURE P1101 (A1 IN NUMBER) IS ESAL EMP. END PC1000. PROCEDURE P1101 (A1 IN NUMBER). END MY_FUNC. Body CREATE OR REPLACE PACKAGE BODY MY_PACK AS PROCEDURE MY_PROC(MEMPNO IN NUMBER. That is. Example: Specification CREATE OR REPLACE PACKAGE MY_PACK AS PACK_DEPTNO NUMBER(2) := 10.ENAME%TYPE. PACK_EMPNO NUMBER(4) := 7369. DBMS_OUTPUT.WNDS.PACK_DEPTNO.

CREATE OR REPLACE PACKAGE PC1000 IS PROCEDURE P1101 (A1 IN NUMBER). RETURN EXP1. BEGIN SELECT (SYSDATE-HIREDATE)/365 INTO EXP1 FROM EMP WHERE EMPNO=Z1. FUNCTION F1104(Z1 IN NUMBER) RETURN varchar2. 14 .PUT_LINE('EMP NOS NONE'). EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE(A2).SAL%TYPE.PUT_LINE(A2). FUNCTION F1101(Z1 IN NUMBER) RETURN varchar2. END F1104. / show err ------------------------------------------------CREATE OR REPLACE PACKAGE PC1003 IS FUNCTION F1103(Z1 IN NUMBER) RETURN NUMBER. EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.SAL%TYPE. END PC1000. END PC1000. FUNCTION F1104(Z1 IN NUMBER) RETURN varchar2 IS EXP1 EMP. CREATE OR REPLACE PACKAGE BODY PC1003 IS FUNCTION F1103(Z1 IN NUMBER) RETURN NUMBER IS EXP1 EMP. BEGIN SELECT SAL INTO ESAL FROM EMP WHERE EMPNO=A1. BEGIN SELECT ename INTO EXP1 FROM EMP WHERE EMPNO=Z1.ename%TYPE.F1103(&EMPNO).PUT_LINE('EMP NOS NONE'). BEGIN A2:=PC1003. END. / show err -------------------------------------------------------------------------------DECLARE A2 NUMBER. / show err CREATE OR REPLACE PACKAGE BODY PC1000 IS PROCEDURE P1101 (A1 IN NUMBER) IS ESAL EMP. DBMS_OUTPUT.F1104(&EMPNO). DECLARE A2 varchar2(25). BEGIN A2:=PC1003. DBMS_OUTPUT. RETURN EXP1. END. END F1103. END PC1003. END PC1003.show err CREATE PACKAGE PC1000 IS PROCEDURE P1100 (A1 IN NUMBER).

EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT. DBMS_OUTPUT. DBMS_OUTPUT.F1101(&EMPNO). ENAME1 VARCHAR2(25).ENAME1.ENAME.(SYSDATE-HIREDATE)/365 SERVICE FROM EMP where deptno=dno .2) ). / 15 '||ROUND(EXP1. EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT. END PC1000. FUNCTION F1101(Z1 IN NUMBER) RETURN VARCHAR2 IS EXP1 EMP.EXP1. CLOSE C1. BEGIN A2:=PC1000. END PC1106.PUT_LINE (ESAL). RETURN EXP1. / SHOW ERR DECLARE A2 VARCHAR2(25). EXP1 NUMBER. END.deptno%type). BEGIN SELECT ENAME INTO EXP1 FROM EMP WHERE EMPNO=Z1. END PC1 ================================================================== CREATE OR REPLACE PACKAGE PC1106 IS PROCEDURE P1106(dno dept.PUT_LINE(A2). . END F1101. BEGIN OPEN C1.PUT_LINE('EMP NOS NONE'). ENO1 NUMBER. END P1106. END PC1106. FUNCTION <FUN NAME> RETURN NUMBER. EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE ('EMPNO NO NOT EXISTS').PUT_LINE ('EMPNO NO NOT EXISTS'). -------------------------CREATE OR REPLACE PACKAGE BODY PC1106 IS PROCEDURE P1106(dno dept.PUT_LINE(ENO1||' '||ENAME1||' END LOOP.deptno%type) IS CURSOR C1 IS SELECT EMPNO. EXIT WHEN C1%NOTFOUND.DBMS_OUTPUT. ================= CREATE OR REPLACE PACKAGE PC1 IS PROCEDURE <PROC NAME>. LOOP FETCH C1 INTO ENO1. END P1101.ENAME%TYPE.

PACKAGE OVERLOADING PL/SQL allows two or more packaged subprograms to have the same name. TO_DATE(TRANS_DATE. improved maintenance.show err COMPARING PROCEDURES AND FUNCTIONS Procedure Execute as a PL/SQL statement No RETURN datatype Can return none. TRANS_DATE NUMBER ). TRANS_DATE VARCHAR2). ’FUNCTION’) ORDER BY OBJECT_NAME LIST THE CODE OF PROCEDURES AND FUNCTIONS WHERE OBJECT_TYPE IN SELECT TEXT FROM USER_SOURCE WHERE NAME = ’QUERY_EMP’ ORDER BY LINE. CREATE PACKAGE BODY JOURNAL_ENTRIES AS PROCEDURE JOURNALIZE (AMOUNT NUMBER. improved data security and integrity LIST ALL PROCEDURES AND FUNCTIONS SELECT OBJECT_NAME. one or many values Function Invoke as part of an expression Must contain a RETURN datatype Must return a single value Benefits of Sub Programs (Stored Procedures and Functions) Improved performance. END JOURNALIZE. PROCEDURE JOURNALIZE (AMOUNT NUMBER. TRANS_DATE VARCHAR2) IS BEGIN INSERT INTO JOURNAL VALUES (AMOUNT. use the DESCRIBE SQL*Plus command. List Compilation Errors Using SHOW ERRORS Use SHOW ERRORS without any arguments at the SQL prompt to obtain compilation errors for the last object you compiled. PROCEDURE JOURNALIZE (AMOUNT NUMBER. ’J’)). END JOURNAL_ENTRIES. TRANS_DATE NUMBER) IS BEGIN INSERT INTO JOURNAL VALUES (AMOUNT. DESCRIBING PROCEDURES AND FUNCTIONS To display a procedure or function and its parameter list. COMPILATION ERRORS USING USER_ERRORS To obtain the text for compile errors. the following package defines two procedures named journalize: CREATE PACKAGE JOURNAL_ENTRIES AS PROCEDURE JOURNALIZE (AMOUNT NUMBER. ’DD-MONYYYY’)). Also examine the ALL_ERRORS and DBA_ERRORS views. 16 . OBJECT_TYPE FROM USER_OBJECTS (’PROCEDURE’. END JOURNAL_ENTRIES. for the owner of the object. For example. END JOURNALIZE. each of which contains the additional column OWNER. This option is useful when you want a subprogram to accept parameters that have different datatypes. use the USER_ERRORS data dictionary view or the SHOW ERRORS SQL*Plus command. TO_DATE(TRANS_DATE.

n NUMBER. a pointer has datatype REF X. END. they simply share a pointer to the query work area in which the result set is stored. Dref's input is a REF to an column in a table and you want retrieve the target instead of the pointer. • Fetches have to be performed to retrieve the results of a sub query. you can use an explicit cursor. For example. each procedure handles the data appropriately. Yet. CURSOR – Cotn………… OTHER CURSORS 1 ] DYNAMIC CURSOR Dynamic Cursor can be used along with DBMS_SQL package . b] Week Cursor . which names the work area.A SQL statement is dynamic.It is only supported way of getting at OID ( object identifier ). EMPCUR1 REFCURSORTYPE. Or.The first procedure accepts trans_date as a character string. Oracle opens an unnamed work area that stores processing information. it returns a cursor in the SELECT list corresponding to the cursor expression. emprow employees%rowtype. • For each row of the parent query. which points to the work area. In PL/SQL. Mainly. you can use a cursor variable. FETCH empcur2 INTO emprow. FETCH empcur1 INTO empcur2. empcur2 refcursortype. To access the information. empcur1 refcursortype. Neither PL/SQL nor any of its clients owns a result set. it returns the value of an object.Whose return type specified. CURSOR SUBQUERY IN REF CURSOR: EXAMPLE DECLARE TYPE refcursortype IS REF CURSOR. BEGIN OPEN empcur1 FOR SELECT cursor(SELECT * FROM employees) FROM departments. 2 ] REF CURSOR To execute a multi-row query. you DREF. 17 .It is a effecient and light means of passing object information as a information a] Strong Cursor . an OCI client. Like VALUE. Unlike value. you use cursor variables to pass query result sets between PL/SQL stored subprograms and various clients. while the second procedure accepts it as a number (the Julian day). where REF is short for REFERENCE and X stands for a class of objects. Ref are the best way of uniqely referring to object instances. CLOSE empcur1. a cursor variable has datatype REF CURSOR. CURSOR SUBQUERY IN EXPLICIT CURSOR: EXAMPLE DECLARE TYPE REFCURSORTYPE IS REF CURSOR.Whose return type not specified. if it is constructed at run time and then executed. not an item. and Oracle Server can all refer to the same work area. CURSOR SUBQUERY • The cursor sub query opens a nested cursor for each evaluation of the cursor expression. Oracle Forms application. DREF It is the 'deference operator. Therefore. Declaring a cursor variable creates a pointer.

CLOSE C1. The ref cursor can be declared in PL/SQL block.ENAME.PUT_LINE(A||' '|| B||' '||C ). /*. EXIT WHEN C_VAR1%NOTFOUND. /*. Subprograms and Packages. 1. OPEN C_VAR2 FOR SELECT DEPTNO.DIPLAYS THE DEPTNO. C_VAR2 C_REF. END LOOP.B.DNAME. B VARCHAR2(20).STATEMENT1*/ LOOP FETCH C_VAR1 INTO A. declaring a variable of the cursor. /*DISPLAYS THE EMPNO.ENAME. For example Cursor C_cur is select * from emp.C. we have to give a select statement for that.DEPARTMENT_ID)FROM DEPARTMENTS D. EXIT WHEN C_VAR2%NOTFOUND.LOC*/ 18 . … END. C_VAR1 C_REF. CURSOR SUBQUERY: NESTED CURSOR ATTRIBUTES • A nested cursor is prepared the first time an operation is performed on it. it will execute only this select statement .ie it is meant for the Select * from emp. If you want to execute multiple select statements. Example: DECLARE TYPE C_REF IS REF CURSOR.LOC FROM DEPT.JOB*/ END LOOP. declaring a ref cursor 2.B.CURSOR C1 IS SELECT DEPARTMENT_NAME. If you call the cursor C_cur anywhere or anytime.JOB FROM EMP. DBMS_OUTPUT. DBMS_OUTPUT.DEPARTMENT_ID=D. So. OPEN C1.C.CURSOR(SELECT EMPLOYEE_ID FROM EMPLOYEES E WHERE E. A NUMBER. LOOP FETCH C1 INTO V_DNAME. we have to declare multiple cursors. then it will be easy for the programmer. • Resources are released after all the nested cursors associated with this cursor have been prepared. EMPROW EMPLOYEES%ROWTYPE. There are two steps to handle the ref cursor. CLOSE C_VAR1. It will be cumbersome. BEGIN V_DNAME DEPARTMENTS. /*DECLARING REF CURSOR NAMED C_REF */ /*DECLARING TWO CURSOR VARIABLES NAMED C_VAR1 AND C_VAR2 OF REF CURSOR C_REF*/ BEGIN OPEN C_VAR1 FOR SELECT EMPNO. REF CURSOR If any normal cursor is declared. C VARCHAR2(20).DNAME. FETCH EMPCUR1 INTO EMPROW. • The parent is checked at each preparation to verify if this is the last nested cursor so that resources can be released.PUT_LINE(A||' '|| B||' '||C ). if there is a single cursor which can open multiple select statements.DEPARTMENT_NAME%TYPE. /*-STATEMENT2*/ LOOP FETCH C_VAR2 INTO A.EMPCUR1.

A database trigger is a stored subprogram associated with a table. Triggers may be used to supplement declarative referential integrity. DATABASE TRIGGERS A Trigger defines an action the database should take when some database related event occurs. The number of triggers you can have a for a table is 14 triggers. Triggers allow table access according to data values. The number of triggers you can have a for a table is 14 triggers. END. The following table shows the number of triggers that you can have for a table. BEFORE and AFTER Triggers Since triggers occur because of events. STATEMENT LEVEL TRIGGERS Statement Level triggers execute once for each transaction. to enforce complex business rules. Triggers track values for data operations on tables. with single ref cursor. Row level triggers are create using FOR EACH ROW clause in the create trigger command.END LOOP. they may be set to occur immediately before or after those events. CLOSE C_VAR2. we can declare any number of cursor variables and each variable can be used for different select statements. 19 . or DELETE statement affects the table. For example if you insert 100 rows in a single transaction then statement level trigger will be executed once. Triggers are executed when a specific data manipulation command are performed on specific tables ROW LEVEL TRIGGERS Row Level triggers execute once for each row in a transaction. The following table shows the number of triggers that you can have for a table. The Oracle Server tracks data operations on tables. You can have Oracle automatically fire the trigger before or after an INSERT. ROW LEVEL TRIGGER BEFORE INSERT UPDATE DELETE INSTEAD OF INSTEAD OF ROW STATEMENT LEVEL TRIGGER INSERT UPDATE DELETE AFTER INSERT UPDATE DELETE INSERT UPDATE DELETE ADVANTAGES OF TRIGGERS Feature Security Auditing Enhancement The Oracle Server allows table access to users or roles. Thus. UPDATE.

CREATE OR REPLACE TRIGGER <TRIGGER NAME> [ BEFORE | AFTER | INSTEAD OF ] (INSERT OR UPDATE OR DELETE) ON <TABLE NAME> ROW BEGIN END.'DELETE IS NOT POSSIBLE'). Triggers copy tables Synchronously into replicas.Data integrity Referential integrity Table replication Derived data Event logging Syntax: The Oracle Server enforces integrity constraints.QTY WHERE ITEMID=:NEW. Triggers compute derived data values automatically.ITEMID. Example 1: CREATE OR REPLACE TRIGGER MY_TRIG BEFORE INSERT OR UPDATE OR DELETE ON DETAIL FOR EACH ROW BEGIN IF LTRIM(RTRIM(TO_CHAR(SYSDATE. END IF. ELSIF DELETING THEN RAISE_APPLICATION_ERROR(-20001. MQTY NUMBER. EXCEPTION WHEN NO_DATA_FOUND THEN INSERT INTO STOCK VALUES (:NEW.ITEMID. The Oracle Server copies tables asynchronously into snapshots. ELSIF UPDATING THEN RAISE_APPLICATION_ERROR(-20001. Triggers log events transparently. END.'DAY')))='FRIDAY' THEN IF INSERTING THEN RAISE_APPLICATION_ERROR(-20001.QTY).'INSERT IS NOT POSSIBLE'). UPDATE STOCK SET QTY=QTY+:NEW. Triggers implement nonstandard functionality. Example 2: CREATE OR REPLACE TRIGGER MY_TRIG AFTER INSERT ON ITEM FOR EACH ROW DECLARE MITEMID NUMBER.'UPDATE IS NOT POSSIBLE'). END IF. 20 REFERENCING OLD AS OLD | NEW AS NEW FOR EACH . The Oracle Server computes derived data values manually. END. BEGIN SELECT ITEMID INTO MITEMID FROM STOCK WHERE ITEMID = :NEW.ITEMID. :NEW. The Oracle Server enforces standard referential integrity rules. The Oracle Server logs events explicitly. Triggers implement complex integrity rules.

SAL*2 WHERE EMPNO=:OLD. BEGIN SELECT USER INTO U1 FROM DUAL. END. / SHOW ERR EMP100 21 . / SHOW ERR Example 6: CREATE OR REPLACE TRIGGER TR03 AFTER UPDATE ON EMP FOR EACH ROW BEGIN UPDATE EMP100 SET SAL=:OLD. END IF.DEPTNO).'DY'). IF D1 IN('TUE'.'DELETE').'TRY ON ANOTHER DAY').EMPNO. END. END. Example 4: CREATE OR REPLACE TRIGGER TR02 BEFORE INSERT OR UPDATE OR DELETE ON EMP100 DECLARE D1 VARCHAR(3).'MON') THEN RAISE_APPLICATION_ERROR(-20025. :OLD.:OLD.Example 3: CREATE OR REPLACE TRIGGER MY_TRIG AFTER DELETE ON EMP FOR EACH ROW BEGIN INSERT INTO EMP_BACK VALUES (:OLD.SAL. Example 5: CREATE OR REPLACE TRIGGER TR01 AFTER DELETE ON DEPT200 FOR EACH ROW BEGIN INSERT INTO DEPT1 VALUES (:OLD. :OLD.DEPTNO. BEGIN SELECT USER INTO U1 FROM DUAL. INSERT INTO USER1 VALUES(U1. END.SYSDATE. END. BEGIN D1:=TO_CHAR(SYSDATE.'UPDATE').EMPNO.:OLD. / SHOW ERR Example 8: CREATE OR REPLACE TRIGGER TR06 AFTER DELETE ON DECLARE U1 VARCHAR2(50). :OLD. / SHOW ERR Example 7: CREATE OR REPLACE TRIGGER TR05 AFTER UPDATE ON EMP100 DECLARE U1 VARCHAR2(50). INSERT INTO USER1 VALUES(U1.SYSDATE.LOC). END.DNAME.ENAME.

Thus.PL/SQL RECORD A record is a group of related data items stored in fields.LOC INTO REC_VAR2 FROM DEPT WHERE DEPTNO = 10.SAL INTO REC_VAR1 FROM EMP WHERE EMPNO = 7788. DECLARE TYPE EMP_REC IS RECORD ( A NUMBER(4). However. DBMS_OUTPUT. TYPE DEPT_REC IS RECORD ( A NUMBER(2). We can't store the record type in the database. DBMS_OUTPUT.ENAME||' '||R2. B VARCHAR2(30).'INVALID EMPLOYEE NUMBER'). We can declare the record type in pl/sql block. C NUMBER(10. /* FETCH COLUMN VALUES AND STORE IN THE RECORD VARIABLE*/ DBMS_OUTPUT. Declaring a record and 2.PUT_LINE(REC_VAR2. EXCEPTION WHEN NO_DATA_FOUND THEN RAISE_APPLICATION_ERROR(-20023. DECLARE TYPE R1 IS RECORD(EMPNO NUMBER(5). each with its own name and datatype.PUT_LINE(REC_VAR2.PUT_LINE(R2.DECLARING VARIABLE OF RECORD TYPE*/ END. Suppose you have various data about an employee such as name. END. DISPLAYS THE EMPNO DISPLAYS THE ENAME DISPLAYS THE SAL DISPLAYS THE NAME OF THE DEPARTMENT DBMS_OUTPUT.HIREDATE). A record containing a field for each item lets you treat the data as a logical unit.B).A). DBMS_OUTPUT. SELECT DEPTNO. 22 .PUT_LINE(REC_VAR1. C VARCHAR2(30)). /*. The datatype RECORD lifts those restrictions and lets you define your own records. -. BEGIN SELECT EMPNO. DEPT_REC. The attribute %ROWTYPE lets you declare a record that represents a row in a database table. ENAME VARCHAR2(10). 1. Declaring a variable of the record. you cannot specify the datatypes of fields in the record or declare fields of your own. These items are logically related but dissimilar in type.2)). Thus. -. records make it easier to organize and represent information.PUT_LINE(REC_VAR1. records make it easier to organize and represent information.C).DISPLAYS THE NAME OF THE DEPARTMENT DBMS_OUTPUT. salary.DNAME. HIREDATE DATE).DISPLAYS THE NAME OF THE LOCATION ----EMP_REC.EMPNO||' '||R2.C).PUT_LINE(REC_VAR2. R2 R1. subprograms and package. A record containing a field for each item lets you treat the data as a logical unit. /* DECLARING RECORD TYPE*/ REC_VAR1 REC_VAR2 BEGIN SELECT EMPNO. B VARCHAR2(30).PUT_LINE(REC_VAR1.HIREDATE INTO R2 FROM EMP WHERE EMPNO=&ASK_EMPNO.ENAME. DBMS_OUTPUT.and hire date.A).B). There are two steps to declare a record.ENAME.

CURSOR C1 IS SELECT EMPNO. BEGIN OPEN C1. BEGIN OPEN C1. CURSOR C1 IS SELECT EMPNO. 23 .DEPT WHERE EMP.LOC%TYPE). ENAME VARCHAR2(10). LOOP EXIT WHEN C1%NOTFOUND. ENAME VARCHAR2(10).HIREDATE INTO R2 FROM EMP WHERE EMPNO=ENO.DEPTNO%TYPE) IS TYPE R1 IS RECORD(EMPNO NUMBER(5).ENAME. R2 R1.HIREDATE).WITH PROCEDURE SET SERVEROUT ON.ENAME||' '||R2. ENAME VARCHAR2(10).DEPTNO. DBMS_OUTPUT. BEGIN SELECT EMPNO. EXCEPTION WHEN NO_DATA_FOUND THEN RAISE_APPLICATION_ERROR(-20023. HIREDATE DATE.'INVALID EMPLOYEE NUMBER').ENAME.EMPNO||' '||R2.ENAME. END.HIREDATE).HIREDATE.LOC FROM EMP. CREATE OR REPLACE PROCEDURE PR1 (DNO EMP. CREATE OR REPLACE PROCEDURE PR_PLRECORD (ENO EMP. R2 R1.EMPNO%TYPE) IS TYPE R1 IS RECORD(EMPNO NUMBER(5).'INVALID DEPARTMENT NUMBER').DEPTNO=EMP. CREATE OR REPLACE PROCEDURE PR2 (DNO EMP. HIREDATE DATE).EMPNO||' '||R2. EXCEPTION WHEN NO_DATA_FOUND THEN RAISE_APPLICATION_ERROR(-20023. DBMS_OUTPUT.PUT_LINE(R2.DEPTNO%TYPE) IS TYPE R1 IS RECORD(EMPNO NUMBER(5). HIREDATE DATE). / SHOW ERR -------------------------------------------------------------------------------------------WITH CURSOR / PROCEDURE -JOINS SET SERVEROUT ON. FETCH C1 INTO R2.PUT_LINE(R2. END LOOP. END. -------------------------------------------------------------------------------------------WITH CURSOR / PROCEDURE SET SERVEROUT ON.ENAME||' '||R2. CLOSE C1. R2 R1. LOC DEPT.DEPTNO=DNO AND DEPT.HIREDATE FROM EMP WHERE DEPTNO=DNO.

PUT_LINE(R2. DBMS_OUTPUT. EXCEPTION WHEN TOO_MANY_ROWS THEN RAISE_APPLICATION_ERROR(-20023. FETCH C1 INTO R2. BEGIN FOR I IN 1.DEPTNO). DECLARE TYPE R1 IS TABLE OF EMP.1 SET SERVEROUT ON. END. CLOSE C1. The column data type can belong to any scalar data type.'MORE THAN ONE ROWS').EMPNO||' END LOOP.HIREDATE||' '||R2. / ========================= PL/SQL TABLE . END. EXCEPTION WHEN NO_DATA_FOUND THEN RAISE_APPLICATION_ERROR(-20023.'INVALID DEPARTMENT NUMBER'). R2(I):=R3. R2 R1.10 LOOP SELECT * INTO R2(I) FROM DEPT WHERE DEPTNO=10. R2 R1.LOOP EXIT WHEN C1%NOTFOUND.LOC).PUT_LINE(R2(I).ENAME%TYPE INDEX BY BINARY_INTEGER. '||R2. 24 '|| . R2 R1.2A DECLARE TYPE R1 IS TABLE OF DEPT%ROWTYPE INDEX BY BINARY_INTEGER. PL/SQL TABLE EXAMPLE PL/SQL TABLE . CURSOR C1 IS SELECT * FROM DEPT. I BINARY_INTEGER:=0.2 DECLARE TYPE R1 IS TABLE OF DEPT%ROWTYPE INDEX BY BINARY_INTEGER.ENAME.DNAME ||' '||R2(I). DBMS_OUTPUT. / SHOW ERR -------------------------------------------------------------------------------------------PL/SQL TABLE . END. / SHOW ERR PL/SQL TABLES PL/SQL tables are temporary array like objects used in a PL/SQL block.ENAME||' '||R2. END LOOP. DBMS_OUTPUT.. BEGIN FOR R3 IN (SELECT ENAME FROM EMP) LOOP I:=I+1. END LOOP.PUT_LINE(R2(I)).LOC||' R2(I).

PUT_LINE('MR. EXEC PR_PL1(30). BEGIN FOR R3 IN (SELECT ENAME FROM EMP WHERE DEPTNO=DNO) LOOP I:=I+1. CREATE OR REPLACE PROCEDURE PR_PL1 (DNO EMP.LOC). R2(I):=A. BEGIN FOR A IN C1 LOOP I:=I+1. -DBMS_OUTPUT.PUT_LINE(R2(I)).'INVALID DEPARTMENT NUMBER'). / EXEC PR_PL1(20). DBMS_OUTPUT. '||R2(I)). or you may want to write a report on how long you are logged on for.3 DECLARE TYPE R1 IS TABLE OF EMP.ENAME%TYPE INDEX BY BINARY_INTEGER.PUT_LINE((I)||' A. EXCEPTION WHEN TOO_MANY_ROWS THEN RAISE_APPLICATION_ERROR(-20023.ENAME. PL/SQL TABLE .. END LOOP. I BINARY_INTEGER:=0.4 SET SERVEROUT ON. If you were a DBA wanting to do this. DBMS_OUTPUT. I BINARY_INTEGER:=0.PUT_LINE(DNAME). END LOOP. DBMS_OUTPUT. you would replace SCHEMA with DATABASE.ENAME%TYPE INDEX BY BINARY_INTEGER. DBMS_OUTPUT.DNAME||' '|| DNAME:=A.DEPTNO||' '||A. < SYSTEM LEVEL TRIGGERS > LOGON and LOGOFF Trigger Example You can create this trigger to monitor how often you log on and off. R2 R1.DNAME.ENAME.'MORE THAN ONE ROWS').I BINARY_INTEGER:=0. END LOOP. END. 1. END. EXCEPTION WHEN NO_DATA_FOUND THEN RAISE_APPLICATION_ERROR(-20023. DNAME VARCHAR2(25). END. / PL/SQL TABLE . CREATE OR REPLACE TRIGGER LOGON_TRIG AFTER logon ON SCHEMA 25 .PUT_LINE(R2(I)). R2(I):=R3.DEPTNO%TYPE) IS TYPE R1 IS TABLE OF EMP. CURSOR C1 IS SELECT ENAME FROM EMP. '||A. R2 R1. Trigger Cotn………. BEGIN FOR A IN C1 LOOP I:=I+1.

INSERT INTO log_trig_table 5 (user_id. log_date.BEGIN END. So. so its name. some programs must build and process a variety of SQL statements at run time. 26 . EXECUTE IMMEDIATE or OPEN-FOR/FETCH/CLOSE Execute Immediate: To process most dynamic SQL statements. ’Logging on’). Dynamic SQL statements are stored in character strings built by your program at run time. to which you must prefix a colon. Such strings must contain the text of a valid SQL statement or PL/SQL block. CREATE [OR REPLACE] TRIGGER trigger_name timing event1 [OR event2 OR event3] ON table_name [REFERENCING OLD AS old | NEW AS new] [FOR EACH ROW] [WHEN condition] CALL procedure_name CREATE TRIGGER TEST3 BEFORE INSERT ON EMP CALL LOG_EXECUTION ORACLE SUPPLIED PACKAGES • Provided with the Oracle Server • Extend the functionality of the database • Allow access to certain SQL features normally restricted for PL/SQL DYNAMIC SQL: Static SQL Statement: Most PL/SQL programs do a specific. So. sysdate. 2. Such statements can. a general-purpose report writer must build different SELECT statements for the various reports it generates. action) VALUES (user. In this case. you use the EXECUTE IMMEDIATE Statement. CREATE OR REPLACE TRIGGER LOGOFF_TRIG BEFORE logoff ON SCHEMA BEGIN INSERT INTO log_trig_table (user_id. predictable job. the full text of the statement is unknown until run time. does not matter. log_date. change from execution to execution. rather than coding the PL/SQL body in the trigger itself. In this case. ’Logging off’). a stored procedure might accept an employee number and salary increase. Such statements do not change from execution to execution. Dynamic SQL Statement: However. For example. they are called dynamic SQL statements. action) VALUES (user. and probably will. They can also contain placeholders for bind arguments. they are called static SQL statements. sysdate. END. CALL STATEMENT This allows you to call a stored procedure. A placeholder is an undeclared identifier. For example. then update the sal column in the emp table. DYNAMIC SQL • Is a SQL statement stored as character string • Allows general purpose code to be written • Allows DDL statements to be written and executed from PL/SQL • Is written using DBMS_SQL. the full text of the UPDATE statement is known at compile time.

CLOSE CURSOR BEFORE EXITING. /* CLOSE CURSOR.PARSE(CID. EXCEPTION /* IF AN EXCEPTION IS RAISED. */ DBMS_SQL.V7).OPEN_CURSOR. RAISE. */ WHEN OTHERS THEN DBMS_SQL. 27 . BEGIN /* OPEN NEW CURSOR AND RETURN CURSOR ID.CLOSE_CURSOR(CID). */ DBMS_SQL. */ CID := DBMS_SQL.USING DDL AND DYNAMIC SQL CREATE OR REPLACE PROCEDURE DROP_TABLE (TABLE_NAME IN VARCHAR2) AS CID INTEGER. 'DROP TABLE ' || TABLE_NAME. DBMS_SQL. -. /* PARSE AND IMMEDIATELY EXECUTE DYNAMIC SQL STATEMENT BUILT BY CONCATENATING TABLE NAME TO DROP TABLE COMMAND.CLOSE_CURSOR(CID).RERAISE THE EXCEPTION END DROP_TABLE.

displays the name of the department dbms_output. records make it easier to organize and represent information.declaring variable of record type*/ rec_var2 dept_rec. Declaring a variable of the record.dname. type dept_rec is record ( a number(2). begin select empno. select deptno.displays the ename dbms_output. records make it easier to organize and represent information. There are two steps to declare a record. PL /SQL RECORD -1 Declare Type r1 is record(empno number(5).COMPOSITE DATA TYPE PL/SQL RECORD A PL/SQL Record is a collection of individual fields that represent a row in a table.displays the empno dbms_output. -. b varchar2(30). and hire date. c varchar2(30)). By using records we can group the data into one structure and then manipulate this structure as one entity r logical unit.hiredate into r2 from emp where empno=&Ask_Empno. However.sal into rec_var1 from emp where empno = 7788.2)). The datatype RECORD lifts those restrictions and lets you define your own records. ename varchar2(10). 28 . We can declare the record type in pl/sql block. b varchar2(30).b). -.b). each with its own name and data type. These items are logically related but dissimilar in type.ename||' '||r2. /* fetch column values and store in the record variable*/ dbms_output.a). Suppose you have various data about an employee such as name.c).a).put_line(rec_var1.put_line(rec_var2.put_line(rec_var1.put_line(rec_var2. Exception when no_data_found then raise_application_error(-20023. -.put_line(rec_var2.ename.displays the sal dbms_output. salary. -. dbms_output. r2 r1. -. -.loc into rec_var2 from dept where deptno = 10. A record containing a field for each item lets you treat the data as a logical unit. A record containing a field for each item lets you treat the data as a logical unit. A record is a group of related data items stored in fields.hiredate). Declaring a record and 2.'Invalid Employee Number'). Thus. The attribute %ROWTYPE lets you declare a record that represents a row in a database table.put_line(r2. subprograms and package.put_line(rec_var1. Begin select empno. /*.empno||' '||r2.ename. you cannot specify the datatypes of fields in the record or declare fields of your own. c number(10. We can't store the record type in the database.c). declare type emp_rec is record ( a number(4).displays the name of the location end. /* declaring record type*/ rec_var1 emp_rec.displays the name of the department dbms_output. hiredate date). Thus. 1.

End Loop. / show err PL/SQL TABLE . Declare Type r1 is table of emp.put_line(r2(i).dname ||' '||r2(i).2 set serverout on.put_line(r2(i)).loc||' End Loop.hiredate into r2 from emp where empno=eno.2 Declare Type r1 is table of dept%rowtype index by Binary_Integer. 29 . Begin For r3 in (Select ename from emp) Loop i:=i+1.End. '||r2(i). With Procedure – PL/SQL RECORD . Exception when no_data_found then raise_application_error(-20023. End.ename. r2 r1.'Invalid Employee Number'). i binary_integer:=0. dbms_output.1 set serverout on.empno||' '||r2.empno%type) is Type r1 is record(empno number(5). r2 r1. Begin for i in 1. dbms_output. Exception When Too_many_rows Then Raise_Application_Error(-20023.10 Loop select * into r2(i) from dept where deptno=10. r2(i):=r3.ename. The column data type can belong to any scalar data type.ename%type index by binary_integer.put_line(r2. create or replace procedure pr_plrecord (eno emp. End.hiredate). ename varchar2(10).deptno). End. Begin Select empno. PL/SQL TABLE .. r2 r1. hiredate date). dbms_output. PL/SQL TABLES PL/SQL tables are temporary array like objects used in a PL/SQL block.ename||' '||r2.'More than one rows').

DNAME FROM E.DEPTNONO=80 FOR UPDATE OF SALARY NOWAIT. [ Retrieve the Employees who work in department 80 and update their Salary ] 2. FOR UPDATE WAIT Clause • • Lock the rows before the update or delete. Use the WHERE CURRENT OF clause to refer the current row from an explicit cursor. SELECT * FROM EMPLOYEES WHERE DEPARTMENT_ID = 10 FOR UPDATE WAIT 20. [ The cursor have been declared with the FOR UPDATE clause] Example of Using FOR WHERE CURRENT OF Clause 1. Syntax Cursor eipc1 is select * from emp for update [ of column_reference ] [ NOWAIT ] Column Reference NOWAIT It is column in the table against which the query is performed [ A list of column may also be used ] Returns an Oracle Error if the rows are locked by another session. DECLARE CURSOR EMP_CURSOR IS SELECT EMPNO. 2. • If NOWAIT is specified.10 WHERE CURRENT OF EMP_CURSOR.SAL<5000 THEN UPDATE EMP SET SALARY=I. • The SELECT. The WHERE CURRENT OF Clause • • • Use cursors to update or delete the cursor row. FOR UPDATE statement has been modified to allow the user to specify how long the command should wait if the rows being selected are locked.DEPTNO=DEPT. LOOP IF I.D. Include the FOR UPDATE clause in the cursor query to lock the row first.DEPTNONO=80 FOR UPDATE OF SALARY NOWAIT.DEPT WHERE EMP. Use explicit locking to deny access for the duration of a transaction. DECLARE CURSOR EMP_CURSOR IS SELECT EMPNO.ORACLE 9I Advanced Explicit Cursor Concepts 1.DEPT WHERE EMP. BEGIN FOR I IN EMP_CURSOR. Example of Using FOR UPDATE WAIT Clause 1.. Syntax WHERE CURRENT OF < cursor_name > Cursor_Name -It is the name of a declared cursor. then an error is returned immediately if the lock cannot be obtained.DEPTNO AND EMP. DNAME FROM EMP.. ENAME. 30 .SAL*1. ENAME.EMP.DEPTNO AND EMP.DEPTNO=DEPT.

User defined exceptions are exception specific to your application. EMPROW EMPLOYEES%ROWTYPE. DECLARE TYPE REFCURSORTYPE IS REF CURSOR.DEPARTMENT_ID) FROM DEPARTMENTS D. ] 3. CURSORS WITH SUB QUERIES Sub queries are often used in the WHERE clause of select statement. 31 . [ The Example loops through each employee in department 80 . V_DNAME DEPARTMENTS. a warning or error condition is called an exception. END LOOP. creating a temporary data source for the query.DEPARTMENT_ID =D. Predefined exceptions are error conditions that are defined by the Oracle server.END IF. LOOP FETCH C1 INTO V_DNAME. EMPCUR1 REFCURSORTYPE.CURSOR(SELECT EMPLOYEE_ID FROM EMPLOYEES E WHERE E. The where current of clause in the UPDATE statement refers to the currently fetched records. BEGIN OPEN C1. and checks whether the salary is less than 5000.If salary is less than . It can be used to FROM clause. END. CURSOR C1 IS SELECT DEPARTMENT_NAME.EMPCUR1. FETCH EMPCUR1 INTO EMPROW. EXCEPTION In • • • PL/SQL.DEPARTMENT_NAME%TYPE. the salary is raised by 10%. CLOSE C1. END. … END LOOP. No predefined exceptions are any other standard Oracle Server Error.