This action might not be possible to undo. Are you sure you want to continue?
packages), and in the Oracle Development Environment(Oracle Forms, Oracle Reports, and Oracle Graphics) It supports SQL Data types. PL SQL bridges the gap and the need for procedural programming capabilities. Benefits of PL/SQL : Improved performance : It is used to group SQl statements together within a single block and to send the entire block to the server in a single call, thereby reducing the network traffic. Modularised program Development : Group logically related statements within blocks. Nest sub-blocks inside larger blocks to build a powerful program Break down complex problems into a set of manageable, well-defined , logical modules Place reusable PL/SQL code in libraries to be shared between Oracle applications or store it in an Oracle server to make it available to any userapplication. Portability : PL/SQL programs can run anywhere the Oracle server is installed, you do not need to tailor them to each new environment. Identifiers : It allows you to declare variables, cursors, constants, and exceptions and then use them in SQL and Procedural statements. It allows to declare variable belonging to scalar, reference, composite and LOB data types Declare variable based on the columns in the tables.
Procedural language Control Structures : Execute a sequence of statements conditionally Execute a sequence of statements iteratively in a loop Process the individual rows returned by a multi-row query with an explicit cursors. Error Handling : Process Oracle-server errors with exception handling routines Declare user-defined error conditions and process them with exception-handling routines Structure of a PL/SQL Block Declare(optional) Contains all the variables, constants, cursors and user-defined exceptions that will be used in the executable section Begin(Mandatory)-----Executable section Contains SQL statements to manipulate data in the database and PL/SQl statements to manipulate data in the data-block Exception(Optional) Contains actions to be performed when errors and abnormal conditions arise in the executable section End; set serveroutput on for dbms_output.put_line to give output in SQL
declare vname students.studname%type; vtotal students.total%type; begin select studname into vname from students where rollno=1; select total into vtotal from students where rollno=1; dbms_output.put_line('Name of Student is :'||vname); dbms_output.put_line('Total of Student is :'||vtotal); end; /
PL/SQL Block Types Anonymous Blocks: These are unnamed blocks. They are declared in an application where they need to be executed and are passed to the Server for execution at run-time. Example : Triggers in Oracle Developer consists of such blocks [Declare] Begin [Exception] End; Sub-Programs : These are named PL/SQL blocks that can accept parameters and can be invoked as and when required. They are declared as Procedures or Functions. Generally use procedures to perform an action and a function to compute and return a value. Procedure name is Begin --statements [Exception] End; Function name return datatype Is Begin --statements return value; [Exception] End;
. Boolean data types(only stores NULL. PL/SQL also supports Boolean datatype Character. Deptno number(2) NOT NULL : =10. you have different kinds of data about an employee like name.Declaring PL/SQl variables Declare Birthdate date. variable type_name. hire date. NESTED TABLE and VARRAY.salary%type vgrade number(7. field declaration. This data is dissimilar in type but logically related. vvflag Boolean :=TRUE 2) Composite Composite data types such as records. Salary constant number : = 10000 PL/SQL variables 1) Scalar These are the data types that correspond to the data types of columns in tables. They have internal components that can be handled and manipulated individually.2). The %type attribute. Must contain one or more components of any scalar type. They are of 4 types : TABLE. TRUE . Instead of hardcoding the data type and size of a variable. …. RECORD: A record is a group of related data items stored as fields. Location varchar2(20) : = ‘Mumbai’. salary. Numeric Date and Boolean types of data types. Example . Also known as Collections. RECORD. you can use the %type attribute to declare a variable according to another previously declared variable or a column of a table. Type type_name IS RECORD ( field declaration. allows groups of fields to be defined and manipulated in PL/SQL blocks. vvgrade vgrade %type:=10.). Example : vsalary employees. each with it’s own name and data type. FALSE) vflag Boolean.
An INDEX BY Table : Is similar to an array Must contain 2 components A Primary Key of data type Binary_Integer that indexes the INDEX BY TABLE A Column of a scalar or record data type.first_name:=’Ramesh’. which stores the INDEX BY Table elements.%rowtype INDEX BY BINARY_INTEGER. emp_record emp_data. To reference or initialize an individual field : Record_name.Type emp_data IS RECORD (first_name varchar2(10).field_name. This attribute is useful when retrieving a row into variables with the Select * From tablename. Declaring Records with %rowtype The %rowtype attribute is used to declare a record based on a collection of columns in a database table or view Example : Declare Emp_record employees%rowtype. .column%type/table. identifier type_name. Type type_name is Table of column_type/variable %type/table. The number and the data types of the underlying database column may change at run time. TABLE : Objects of TABLE type are called INDEX By TABLES. The number and data types of the underlying database columns need not be known. last_name varchar2(10)). Emp_record. They use a primary key to provide you with array-like access to rows. Can increase dynamically because it is unconstrained.
Example : Set server output on. My_emp_table emp_table_type. Type ename_table_type IS TABLE OF employees. LAST. Ename_table(1) :=’Ramesh’. Declare Type ename_table_type IS TABLE OF employees%rowtype INDEX BY BINARY_INTEGER. Ename_table ename_table_type.Returns the index number that succeeds the index n in a table TRIM-removes oen element from the end of the PL SQL Table TRIM(n)-removes n elements from the end of the PLSQL Table DELETE.n)-removes all elements in the range m…n from a PL SQL table.returns the first and last index numbers Prior(n).first_name%type INDEX BY BINARY_INTEGER. Following methods are used by the INDEX BY Tables : Exists(n)-returns TRUE if the nth element exists Count-returns number of elements that a PL/SQL table currently contains FIRST.Returns the index number that preceeds the index n in a table Next(n). Type birthdate_table_type IS TABLE OF DATE INDEX BY BINARY_INTEGER. An explicit executable statement is required to initialize (populate) the Index By Table. Initially such a table is not populated. Birthdate_table birthdate_table_type. Ename_table ename_table_type. Birthdate_table(1) :=sysdate-10.first_name%type INDEX BY BINARY_INTEGER. it contains no keys or no values.Type ename_table_type IS TABLE OF employees.removes all elements from PL/SQL table DELETE(n)-removes the nth element from the PLSQL table. . DELETE(m.
End if. End loop. Statement 2. / 3) Reference These are the pointers to other program items. Statement 4. Statement 2. Conditional Constructs IF Statement If-then. If <condition(s)> then Statement 1. If-then-else-end if..end if. Else(optional) Statement 3. End if.put_line(my_emp_table(i). v_count Loop Select * into my_emp_table(i) from employees where employee_id=i. End loop. If <condition(s)> then Statement 1.(Not a part of the syllabus) 4) LOBs Also called locators that specify the location of large objects(such as graphic images that are stored out of line. End. Begin For i in 100 .first_name). .first .last Loop Dbms_output. my_emp_table.V_count number(3):=104. For i in my_emp_table..
Statement 6.total%type. . else dbms_output. Elsif <condition(s)> then Statement 3. "Average student" if total between 250 and <275. select total into vtotal from students where rollno=1.put_line(Vname||' is a very good student'). if total of Rollno=1 is more than 275. Statement 4. Statement 2. PL/SQL Block to display "Very Good Student". and "poor student" if total less than 250 declare vname students. If <condition(s)> then Statement 1. end. vtotal students.put_line(Vname||' is an average student'). if total of Rollno=1 is more than 275. select total into vtotal from students where rollno=1.If-then-elsif-elsif-else-end if. else display "Average student" declare vname students.studname%type.studname%type. Elsif <condition(s)> then Statement 5. vtotal students. Statement 8. if vtotal>=250 then dbms_output. End if. / PL/SQL Block to display "Very Good Student". end if.total%type. begin select studname into vname from students where rollno=1. begin select studname into vname from students where rollno=1. Else(optional) Statement 7.
end. End.put_line(Vname||' is a very good student').put_line(Vname||' is a poor student'). / Nesting of Ifs allowed as per situation.put_line(Vname||' is an average student'). elsif vtotal>=250 and vtotal<275 then dbms_output.if vtotal>=275 then dbms_output. end if. Declare vgrade char(1):=upper(‘&p_grade). CASE Expressions Case selector When expression1 then result1 When expression2 then result2 When expression3 then result3 When expressionN then resultN Else resultN+1(optional) End.put_line(‘Grade ‘||vgrade||’ Appraisal ‘ || vappraisal). Begin Vappraisal := CASE vgrade When ‘A’ then ‘Excellent’ When ‘B’ then ‘Very Good’ When ‘C’ then ‘Good’ Else ‘No such grade’ End. else dbms_output. Set serveroutput on. Dbms_output. vappraisal varchar2(20). / .
. / Numbers 1 to 10 in reverse order declare num number(2)..20 loop if mod(x. end loop.10 loop dbms_output. end. dbms_output. end loop Numbers 1 to 10 in order declare num number(2). / . dbms_output.LOOPS 1) For <variable> in [reverse] lowvalue..put_line('Number '||x||' is Odd').put_line('Number '||x||' is Even').. statement2.highvalue loop statement1.10 loop dbms_output.put_line('There are '||b||' odd numbers'). end. end if.put_line('There are '||a||' even numbers'). / Print odd and even numbers from 1 to 20 and their count declare a number:=0. begin for num in reverse 1. end loop.2)=0 then dbms_output. begin For x in 1. end.put_line('number '|| num).put_line('number '|| num). b:=b+1. else dbms_output. b number:=0. a:=a+1. end loop. begin for num in 1.
100 declare num number:=10. exit when num>50. print 5. / loop statement1.30. begin loop dbms_output. end. statement2...15.... num:=num+5. / . end loop.put_line(num).While <condition> loop statement1. end loop..put_line(num).50 declare num number:=5..20. end loop. num:=num+10.. statement2. print 10. exit when <condition>.10.20. end. begin while num<=100 loop dbms_output. end loop.
EXPLICIT For queries that return more than one row. explicit cursors are declared and named by the programmer. Declare Cursor cursor_name is Select ……. 2)Open This statement executes the query. It is now possible to reopen the cursor to re-establis a fresh active set. and manipulated in the block’s executable section. Following are the steps followed for handling explicit cursors : 1)declare Here we declare the cursor by naming it and define the structure of the query to be performed within it. Loop Fetch cursor_name into variable1. The row returned by the query are called the active set and are now available for fetching Open Cursor_name. There are 2 types of cursors : IMPLICIT These are declaredc by PLSQL implicitly for all DML and PLSQL Select statements. Close Cursor_name . 4)close It releases the active . variable 2. including queries that return only one row. Explicit Cursors Used to process each row returned by a multiple-row Select statement.CURSORS Cursors are names given to private SQL work areas created by the Oracle server to execute SQL statements and to store the processing information. Exit When End loop. 3)Fetch and process Here you actually fetch the rows into variable if required and carry out all the business logic or processing.
Do not use the INTO clause in the cursor declaration. dbms_output.put_line('Total :'||vtotal). exit when cstudent%notfound should be done immediately after fetch. total of all the students declare cursor cstudent is Select Rollno.rollno%type. to print the name. vtotal students. dbms_output. end. vname. If the row need to be processed in a particular order.studname. . vname students. or else the last record will be displayed twice. close cstudent. vtotal.put_line('Roll number :'||vrollno).Evaluates to TRUE if the most recent fetch returns a row %rowcount-Evaluates to the number of rows returned so far Example to retrieve row from employees table and populate them to another table with a similar structure Declare Cursor emp_cursor is select empid. loop fetch cstudent into vrollno.Evaluates to TRUE if the most recent fetch does not return a row %found. / Here. end loop.total from students. exit when cstudent%notfound. you may use the order by clause in the declaration. Begin Open emp_cursor. "notfound" is a cursor attribute which is used to find whether the cursor currently contains a record or has reached the end of the file or recordset Explicit Cursor attributes %isopen – Evaluates to True if the cursor is open %notfound.total%type.put_line('Name :'||vname). vrollno students. begin Open cstudent. dbms_output.studname%type. Emp_record emp_cursor%rowtype. last_name from employees.
Each time you open the cursor with a different set of values. / Cursor For Loop It is a shortcut for processing explicit cursors. Set serveroutput on.Loop Fetch emp_cursor into emp_record. For each execution. End loop. rows are fetched once for each iteration in the loop. the previous cursor is closed and reopnened with a new set of values. deptno from employees. Commit.first_name). returning a different active set. the loop exits when the last row is processed. because the cursor is opened. and the cursor is closed automatically. Begin For emp_record IN emp_cursor --implicit open and fetch occurs Loop If emp_record.last_name) End loop. Retrieving the employees one by one and printing them if they belong to department 80.put_line(‘Employee ‘ ||emp_record.empid. . Close emp_cursor. Thus you can open and close an explicit cursor several times in a block. End. --implicit close and implicit loop exit End. End loop. emp_record. Declare Cursor emp_cursor is select first_name . Statement2. name) values(emp_record. End if.deptno=80 then Dbms_output. For record_name IN Cursor_name Loop Statement1. Exit when emp_cursor%notfound. Insert into temp_emp(empno. / Cursors with Parameters You can pass parameters to the cursors.
: ‘ || emp_record.] Also. Sometimes it may happen that the rows which you want to lock are already locked by another user/transaction. Begin Open emp_cursor(80.employee_id ||’ Employee name :’ || emp_record. when querying multiple tables with a join.. you need to specify the FORMAL parameters. since the update/delete which you want to perform is based on those values. For emp_record IN emp_cursor Loop Dbms_output. Close emp_cursor Open emp_cursor(60. To prevent any other user/transaction from changing those values. [It is not necessary that the for update clause refers to a column . Only that table’s rows will be locked whose column is referred to in the For update [of column] clause. you can use the For update clause to ensure row locking to particular table of the join. but it is recommended by Oracle for better readability and maintenance. : ‘ || emp_record. you can lock those row retuned by the cursor through the FOR Update clause. For emp_record IN emp_cursor Loop Dbms_output.last_name). Hence it is important that no other user /transaction modifies those values. ‘Sales_Rep’). You have to specify the Formal parameter data types. Declare cursor emp_cursor(p_deptno number. last_name from employees whre department_id=p_deptno and job_id=p_job. / For Update [Of column] clause Sometimes you may want to perform some update or delete based on the values that the cursor has returned to you.employee_id ||’ Employee name :’ || emp_record.In the cursor declaration. End loop.put_line(‘Employee no. because of the for update . and each of there formal parameters will have to be passed an ACTUAL parameter or value in the Open statement. but not the size. ‘Programmer’). End loop. Close emp_cursor End.put_line(‘Employee no. p_job varchar2) is select employee_id.last_name).In such a case.
salary*1.department_id.department_id and employees. department name.salary<5000 then Update employees set salary=emp_record. / Cursors with subqueries Declare Cursor my_cursor is Select t1.department_name. Where current Of clause Sometimes you may want to update or delete the row being currently addressed.department_id=60 FOR Update of salary NOWAIT.clause your block will keep on waiting till the rows are released by the other user/transaction. departments where employees. so that instead of waiting indefinitely. last_name.department_id=departments. But for this you need to lock the rows with the FOR UPDATE clause so that the rows are locked on open. last_name. such that there are more than 3 employees working in each such department. End.department_id=t2. the active set will contain the department number. Begin For emp_record in sal_cursor Loop If emp_record. (Select department_id.department_id. without the need to refer to the ROWID. and the total number of employees working in that department. Declare Cursor emp_cursor is Select employee_id.department_id and t2.10 WHERE CURRENT OF sal_cursor. To avoid this type of waiting. End loop. salary from employees e.staff from departments t1. you can use the NOWAIT clause with the For update clause.deprtment_id=60 FOR UPDATE OF SALARY NOWAIT. .. departments d where d.department_id=e. the control is immediately passed to your program so that it can do some other work before trying to acquire the lock.staff>=3 When this cursor is opened. This is possible through the WHERE CURRENT OF clause. End if.department_id and d. Declare Cursor sal_cursor is Select e. department_name from employees. employee_id. t2.. t1. count(*) as staff from employees group by department_id) t2 where t1.
Do not declare them and oracle server will raise them implicitly No_data_found Too_many_rows Inavlid_cursor Zero_divide Dup_val_on_index. but the PL SQl block terminates successfully. then the PL SQL block terminates with failure and the exception is propogated to the calling environment. When an exception is raised. The exception being raised may be user-defined or pre-defined.EXCEPTIONS An exception is an identifier in a PL SQL Block that is raised during the execution of a block that terminates it’s main body of actions. then the control is not passed back to the enclosing block or environment or point where the exception was raised. You explicitly raise an exception by issuing the RAISE statement within the block. Exception types Implicitly raised : Predefined Oracle Server : 20 most common errors. the control is passed to the exception handler in the exception section. In such cases. Statement2. you can specify an exception handler to perform some other actions.. Declare them in the declaration section. etc Non Predefined Oracle Server : Other Oracle server errors.. If the exception is successfully handled. . But.] then Statement1. and oracle server will raise them implicitly Explicitly raised : User-defined : A situation which is abnormal from the user point of view. Declare them in the declaration section and raise them explicitly Declare Begin Exception When Exception1 [or exception2…. Exceptions are raised in 2 ways : An oracle-defined error occurs and the appropriate exception is raised automatically. If an exception is raised and there is no corresponding exception handler.
but to the exception handler. .put_line('the roll number is not correct'). [When others then Statement5. / Here. / The exception handling section traps only those exceptions that are specified. end. since the data is not found. begin select total into vtotal from students where rollno=16. besides the Exception section Trapping Predefined Exceptions : declare vtotal students. Statement4.] then Statement3.] End. an error has occurred and the control is transferred to the exception handler. which traps any exception which is not yet handled. others are not trapped. the control is not passed to the immediate next line. since when the error is encountered. unless you use the OTHERS exception handler.. OTHERS is the last exception handler that is defined optionally Guidelines for Trapping Exceptions : Begin the Exception-handling section with the EXCEPTION Keyword Define the required number of exception-handlers. Statement6. each with it’s own set of actions When an exception occurs PL SQL processes only one Exception-handler before leaving the block Place the OTHERS clause after all the other exception-handlers There can be only one OTHERS clause Exceptions cannot appear anywhere else.When Exception3 [or exception4…. dbms_output. and the line which is after the line that caused the error is not executed. Hence.put_line('Check the roll number').total%type. exception when no_data_found then dbms_output.
The PRAGMA EXCEPTION_INIT utility tells the compiler to associate an exception name with an Oracle error number.put_line(‘Cant delete department to_char(&p_deptno) ||’ It has got employees existing ‘). / Trapping Non-Predefined Exceptions : There are certain non-predefined standard Oracle errors. which always return a standard Oracle server error number. but are not associated with name(exception name/error name). Exception When e_emps_existing then Dbms_output. or by using the OTHERS handler. Commit.put_line('More than 1 row selected'). PRAGMA EXCEPTION_INIT(e_emps_existing. / Functions for trapping Exceptions : SQLCODE-returns the numeric value for the error code SQLERRM-Returns the message associated with the error number ‘ || . you may refer to that exception by name and write a specific handler for it. After doing this . They are raised implicitly. Such errors can be trapped by declaring it first . Define p_deptno=20 Declare e_emps_existing EXCEPTION. End. exception when too_many_rows then dbms_output.total%type. Example : Oracle returns error number –2292 when you try to delete a parent record which has got some child records. BEGIN Delete from departments where department_id=&p_deptno. end.declare vtotal students. PRAGMA directs the PL SQL compiler to associate all occurrences of that Oracle error number with the given exception name within that block. -2292). begin select total into vtotal from students where total>100.
exception when low_mark then dbms_output.put_line('Failed in English'). / Trapping User-Defined Exceptions : Declare the exception in the declarative section Raise the exception in the executable section Handle the exception in the Exception-handling section declare low_mark exception. end if. / . v_error_message varchar2(200).english%type. if venglish<35 then raise low_mark. begin select english into venglish from students where rollno=2. insert into errors values(v_error_code. v_error_message :=SQLERRM.SQLCODE value 0 1 +100 negative number Description No Exception encountered User-defined exception No_data_found exception Some standard Oracle server error number Example : to store all the error-numbers and error-messages in an ERRORS table Declare v_error_code number. venglish students. v_error_code:=SQLCODE. v_error_message). end. End. Begin Exception When OTHERS then Rollback.
/ Here no_data_found cannot be used . If SQL%NOTFOUND then Raise e_invalid_department. Commit.. Define p_department_desc =’Planning n esearch’ Define p_department_number=20 Declare e_invalid_department EXCEPTION. since it is an update statement and not a select statement.put_line(‘No such department number’). pragma exception_init(e_integrity. End. End if. -2292). Sub-blocks can handle an exception or pass the exception to the enclosing block Declare … … e_no_rows exception. End. / .if marks in english are less than 35 then the exception is raised and the message is displayed. When e_no_rows then……. End. Exception When e_integrity then……. Exception When e_invalid_department then Dbms_output. Update……. e_integrity exception. End if. Begin Update departments set department_name=’&p_department_desc’ where department_id=&p_department_number. End loop. Begin For erec in emp_cursor loop Begin Select ……. If SQL%NOTFOUND then Raise e_no_rows.
Raise_application_error(error_number.specified number for exceptions between -20000 to -20999 user-specified message upto 2048 bytes long. nonpredefined or userdefined error . Raise_application_error can be used in either(or both) the executable section and the exception section.Raise_Application_Error Procedure : This procedure is used to communicate a predefined exception/error with a nonstandard error number and a user-friendly error message from stored subprograms. It also handles the unhandled exceptions. error message) Error_number : Error message: must be a user. The error number and message are displayed to the user just like a predefined.
header Is/AS --this section after is/as and before the begin is the declarative section PL SQl block --. 2000). expression. It’s value cannot be changed in the procedure body. Cannot be assigned a default value. and then returned to the calling environment. It is a named PL SQL block that can accept parameters(called arguments). . OUT: Returned to the calling environment. It can stored in the database as a schema object. End hikesal.Procedures A procedure is a type of sub-program that performs an action. It has a Header section. Parameter Modes : IN(default) : Value passed to the procedure from the calling environment. parameter2 [mode] datatype. Actual parameters are the variables or expressions passed while calling the procedure Execute hikesal(v_empid. …] -. Cannot be assigned a default value.. The actual parameter can be a constant. The Formal parameter acts as a constant and only takes the values passed by the calling environment. Create or Replace Procedure procedure_name [parameter1 [mode] datatype. In OUT: Passed to the procedure. Formal versus Actual Parameters : Formal parameters are the variables declared in the parameter list of the procedure declaration Create or Replace procedure hikesal(p_empid number.executable and an optional exception section The pl sql block starts with either a BEGIN or the declaration of local variables and ends with END or End procedure_name. p_empsal number) …. declaration section. Must be passed as a variable.. executable section and an optional exception-handling section. Must be passed as a variable. or an initialised variable. But it can take a default value.
vsal OUT number) is begin select ename.sal%type. vdate1 emp.sal%type. vsal from emp where empno=veno.ename%type. . end. sal into vename. vs). sal. ve. dbms_output. end. end.Stored Procedure to display employee numbers and their salaries for department 10 create or replace procedure retemp(veno IN number.put_line('Employee name is '||ve). vs emp. / main plsql block declare cursor c2 is select empno.put_line('Employee number is '||erec.hiredate%type. end if. vsal1 emp. / main block declare cursor c1 is select empno from emp where deptno=10.05. vsal IN OUT number. hiredate from emp.put_line('Employee salary is '||vs). vename OUT varchar2.empno. years number. ve emp.empno). dbms_output. year IN number) is begin if year>=60 then vsal:=vsal*1. end loop. / to show increase in salary by 10 percent for all employees and an additional 5 percent for those who have completed more than 5 years of service create or replace procedure retemp(veno IN number. begin for erec in c1 loop retemp(erec. dbms_output.
/ at the calling environment : variable g_name varchar2(25) variable g_sal number variable g_comm. end loop.begin for rec in c2 loop dbms_output.put_line('Employee salary '||vsal1).hiredate) INTO YEARS from emp where empno=rec.commission_pct%type) is BEGIN Select first_name. dbms_output. p_comm from employees where employee_id=p_id.put_line('Employee salary '||vsal1).) print g_name print g_sal print The colon(:) is required to reference the host variable s in the execute command. Methods of passing Actual Parameters : Positional : Here the actual parameters are passed in the order in which the Formal parameters are given with the procedure definition . / Viewing OUT Parameters : Create or replace procedure query_emp (p_id In employees. salary.vsal1.put_line('Employee number '||rec. select months_between(sysdate. p_comm. End emp_query. vsal1:=rec. Number execute query_emp(100.empno.put_line('Employee salary '||rec. OUT employees.empno. :g_name. years). commission_pct into p_name.empno). :g_comm. end.sal*1.sal).first_name%type. :g_sal. p_name OUT employees. p_salary OUT employees.employee_id%type. dbms_output. retemp(rec. dbms_output. p_salary.1.salary%type.
department_name%type DEFAULT ‘unknown’.200).---Named association add_dept(p_loc=>400). p_loc). their scope is limited to the parent(enclosing) block in which they are defined. Because they are defined in the declaration section of another program/PL SQL Block/procedure. When you are declaring a sub-program in the declaration section of the main program.Named Association : Here the actual parameters are passed in ant arbitary order by associating it with the corresponding formal parameter using the => symbol. Executing/Calling the above procedure : Begin add_dept. and not to OUT or IN OUT Parameters. P_loc IN departments. ----positional add_dept(p_loc=>300. p_name=>’Medical’). / In Combinational method all the positional parameters must be before the named parameters. it must me the last item declared. department_name.will give an error as “a positional parameter may not follow a named parameter” Declaring Local Sub-procedures : The local procedures are not stored as Schema objects. or else there will be an error.location_id%type DEFAULT 100) IS Begin Insert into departments(department_id. End add_dept. Combination : Here the first actual parameter is passed positionally and the remaining are passed using the => symbol as in named association method.nextval. --. p_name.put_line('P1 is called'). location_id) values(departments_seq.both default add_dept(‘Welfare’. declare procedure p1 is begin dbms_output. Any variable declared after the local subprogram will cause a compilation error. Default Option for parameters Create or Replace procedure add_dept(p_name IN departments. end. . Example : Execute add_dept(p_name=>’Legal’.one default End. / Default values may be assigned only to In parameters . 500) -. -.
dbms_output. End del_emp. and dbms. is not types as line 1) The result is an infinite loop. end.put_line('In the main block'). p1. / it will show error : p1 must be declared(if procedure p1.employee_id%type) IS Procedure log_emp IS Begin Insert into log_table(user_id. Begin Delete from employees where employee_id=p_id.. end..put_line('In the main block'). / . dbms_output. log_exec. p2. SYSDATE). log)date) values(USER. begin p1.put_line('p2 called'). Procedure to delete an employees record and to log the entry of the user who deleted the record Create or Replace procedure del_emp(p_id IN employees. end. p2. is never executed.. end. End log_emp. / declare procedure p1. procedure p1 is begin dbms_output. procedure p2 is begin dbms_output.put_line('p1 called').begin p1.
/ . ‘Mumbai’. End. If the exception is handled. Begin For erec in emp_cursor Loop Raise_salary(erec. Begin Dbms_output. the control goes immediately to it’s exception section. Any DML statements issued before the exception was raised remain as part of the transaction. Commit. End loop. and the control goes to the calling program/environment. …… End. Select department_id into v_did from employees where employee_id=999. Commit. Consider the following tables LOCATIONS Location_ID City 1 Mumbai DEPARTMENTS Department_ID 5 Department_name Welfare Manager_ID 200 Location_ID 1 Create procedure Ins_dept(p_locid number) IS v_did number(4). then the block terminates. / Invoking a stored procedure from another Stored procedure : Create or replace procedure emp_proc IS Cursor emp_cursor is select employee_id from employees. / Handled Exceptions : When an exception is raised in a called procedure. Insert into departments values(5.employee_id). Begin Raise_salary(v_id). p_locid).put_line(‘Procedure INS_dept started’).Invoking a stored procedure from an anonymous block : Declare V_id number:=145. End emp_proc. 200.
department name=Welfare. then it raises no_data_found. The procedure ins_dept is supoosed to insert a new department with department id=5. the calling procedure terminates and the exception propagates to the calling environment.put_line(‘MAIN Procedure INS_LOC started’). End. Suppose there is no such employee. So.put_line(‘Inserted City ’|| v_city). the control is passed to the calling procedure ins_loc where the exception no_data_found is handled. if the exception section from the ins_loc is removed.put_line(‘Invoking Procedure INS_dept’). p_city). the DML in ins_dept is not rolled back. p_city varchar2) IS v_city varchar2(30). Procedure ins_dept selects the department id for an employee whose employee id=999. ‘Mumbai’) If the exception is handled in the calling procedure. Exception When no_data_found then Dbms_output. Thus.Create procedure Ins_loc(p_lid number. city) values(p_lid. department/location for any . which is not handled in procedure ins_dept.put_line(‘No such employee’). then the DMLs in both the procedures are rolled back if no employee with employee_id=999 is found. Insert into locations(location_id. and becomes a part of the transaction of procedure ins_loc procedure Execute ins_loc(1. Dbms_output. Manager ID=200 at the new location inserted through INS_loc. Select city into v_city from locations where location_id=p_lid. Begin Dbms_output. v_dname varchar2(30). If the exception is not handled by the calling procedure. ALL DML statements in the calling and called procedure are rolled back along with any changes to any host variables. Ins_dept(p_lid). Dbms_output. If in the above 2 procedures. / The procedure INS_loc inserts a new location into the locations table. all DML statements in the calling and called procedure remain as part of the transaction.
Create or Replace Function function_name [parameter1 [mode] datatype. declarative section. Local functions : Not stored in database Defined and called within the same program Functions do not have declare.header RETURN datatype Is/AS --this section after is/as and before the begin is the declarative section PL SQl block --. return 10. begin dbms_output. end.executable and an optional exception section End function_name. can be called thru another pl/sql block . function f1 return number is begin dbms_output. a function must have a RETURN clause in the header and at least one RETURN statement in the executable section. / Global or stored function : Stored in the database Defined and saved separately. If it is necessary to declare a variable it should be done in the declare part of the enclosing program declare x number.Functions Function is a named PL SQL block that can accept parameters and be invoked.put_line('value of x is'||x).put_line('Inside the Main'). Like a procedure. end. dbms_output. x:=f1. A function must return a value to the calling environment. …] -. parameter2 [mode] datatype. executable part and an optional exception section. a function has a header. In addition. Function is called as part of a SQL expression or as a part of a PL SQL expression.put_line('Inside the function'). whereas a procedure returns zero or more values. / The type of parameter mode should be only of type IN.
/ at the sql prompt :>show_error. begin select sal into vsal from emp where empno=veno. to show the errors in the function coding. End getsal.put_line('salary is not found'). create or replace function chkemp(veno number) return boolean is vsal emp. end.employee_id%type) RETURN number Is v_salary employee. which is a good programming practice.sal%type. RETURN v_salary. return true. to execute >@f1.Create or Replace Function getsal(p_id IN employees. dbms_output. / Executing functions : Declare a variable to hold the return value. Begin Select salary into v_salary from employees where employee_id=p_id.salary%type :=0. exception when no_data_found then dbms_output. as follows : variable gsalary number execute :gsalary :=getsal(130) print gsalary try the following on emp in scott : ed f1. .put_line('salary is '|| vsal). return false.
put_line('Employee Not Existing').main block declare y number :=&eno. / select text from user_source where type ='FUNCTION' and name='UPSAL' order by line main pl/sql block declare cursor c1 is select empno.put_line('Employee Existing'). commit.empno). begin flag:=chkemp(y). begin update emp set sal=sal+(sal*inc/100) where empno=veno. else dbms_output. flag boolean. / . incr). return vsal. select sal into vsal from emp where empno=veno. dbms_output. inc number) return number is vsal number. end loop. incr number :=&incr.empno. incsal number.put_line('Increased salary is '||incsal||' for employee '|| erec. end. end if. begin for erec in c1 loop incsal:=upsal(erec. / stored function to update the salaries of employees getting less than 3000 with increment of certain % percent create or replace function upsal(veno number. sal from emp where sal<3000. end. if flag=True then dbms_output. end.
do not use OUT and IN OUT with functions. End Tax. awkward or unavailable with SQL Increase data independence by processing complex data at the Oracle server level(since the stored functions are stored at the server). Locations from where you may call a User-defined function : Select list of a SELECT command Condition of the WHERE and HAVING clause Connect by . Advantages of Functions : To perform calculations that are complex. tax(salary) from employees where tax(salary) >(select max(tax(salary)) from employees where departmentid=30) order by tax(salary) desc Restrictions on calling function : The function must be a Stored Function It must accept only IN parameters Accept the parameters whose data type must be standard SQL data type and NOT a PL SQL data type . There can be a RETURN statement in the exception section also. OUT and IN OUT are available with functions. order by and group by clauses Values clause of the insert command SET clause of the update command Select empno.Although 3 parameter modes IN. start with. since the purpose of a function is to accept 0 or more parameters and return a single value. / INVOKING a function from a SQL Expression Suppose you have a table employees with salary column then you may use the above function as follows to calculate their tax Select empno. rather than retrieving data into an application.08). tax(salary) from employees. and it involves a lot of complications and side effects. Increase efficiency of queries by performing functions in the query rather than in the application Create or Replace Function tax(p_value IN NUMBER) Return NUMBER IS Begin Return(p_value * 0. salary. Having a function returning multiple values is a poor programming practice.
SET ROLE(session control statement). End. Return (s+a). Examples Create or Replace function abc(p_sal number) Return number is Begin Insert into employees(employee_id. sysdate-10. Return(p_sal +100). or DDL commands Functions called from a SQL Expression(as shown above) cannot contain a DML Statement. such a COMMIT(transaction control statement). ALTER SYSTEM(system control statement).The return data types must be a standard SQL data type and NOT a PL SQL data type Restrictions from where a stored function can be called : Functions called from an Update/Delete statements on a Table XYZ cannot contain a DML statement on the table XYZ Functions called from an Update/Delete statements on a Table XYZ cannot query the table XYZ When called from an INSERT/UPDATE/DELETE/SELECT statement. last_name. / Update employees set salary=xyz(100) where employee_id=95. such a table is called MUTATING table . the function cannot contain commands that end the transaction. End. Begin Select salary into s from employees where employee_id=95. appoint_date. We are calling the function thru the update command on the same table employees. 10000).’Pereira’. / The function fails with the folliwng : Update employees set salary=abc(2000) where emplyee_id=90. The function contains a DML statement on table employees. The update statement returns an error saying that the table is mutating Aslo Create or replace function xyz( a number) retutn number is s number. If a Function internally calls sub subprogram(that is another function or procedure) then that sub program even muts not violate any of the above mentioned restrictions. Here also the mutating table error is returned When the code in a function is querying or reading the data in a table which is being updated. salary) valurs(1001.
Function Executes as a PL SQL Block Invoked as part of an expressionm Exec Proc_name Does not contain a RETURN clause in Must contain a RETURN clause in the the Header Header May or may not return values Must return a single value Used to perform a series of actions Used to compute some value. which is returned to the calling environment .To drop a function : Drop function function_name. Procedure V/s.
. which is called DEFINER’s-RIGHTS. Alter. Drop or Execute subprograms. DIRECT ACCESS From Hemant schema grant object –level privilge on the table employees to user Manoj Manoj has created the procedure manoj_proc that queries the Employees table in the schema Hemant INDIRECT ACCESS Manoj grants execute privilge to Saloni on his procedure manoj_proc This Saloni can access By default subprograms execute under security domain of the owner. but only through a procedure manoj__proc which is created by the user MANOJ. Grant Execute any PROCEDURE to user_name. drop. Functions and Packages.Managing Subprograms : System privileges are required to Create. Grant Alter any PROCEDURE to user_name. If a PL SQL subprogram refers to any objects that are not in the same schema. System privileges are granted by the user SYSTEM or SYS Grant Create (any) PROCEDURE to user_name. The keyword PROCEDURE is used to assign such rights on Stored Procedures. The keyword ANY is optional for CREATE. then you must have EXECUTE privilege on that subprogram. not through a role If you are not the owner of a subprogram. alter. The keyword ANY means that you ca create. There is another user MANOJ and a third USER SALONI. or excute your own subprograms and those in another schema. Providing INDIRECT ACCESS to Data Suppose EMPLOYEES table in Scheme(user) HEMANT. Suppose we need to ensure that SALONI can access the table EMPLOYEES in the schema HEMANT. Grant Drop any PROCEDURE to user_name. then you must be granted access to those objects explicitly.
PACKAGE BODY.User_Objects To obtain names of all PL/SQL stored objects within a schema. Package Body LINE -Line number of the source code TEXT -Text of the source code line This table contains one record for each line of code. Function. Package Body LINE -Line number of the source code where error occurred Position -Position in the line where the error occurred Text -Text of the error message SHOW ERRORS [Function/Procedure/Package/Package body/Trigger/View This will show use the errors that occurred while trying to compile the articular program unit. PACKAGE. Package. SHOW ERRORS without any [parameter will show the compilation errors The following query will also show you an output which is similar to that of show errors . both of which contain an additional OWNER column. Function. FUNCTION. ALL_SOURCE and DBA_SOURCE contain the additional column Owner Select text from user_source where name=’PROCEDURE_name’ order by line. PROCEDURE. TRIGGER -Date of object creation -Date when object was last modified -Date and time when object was last recompiled -VALID or INVALID You can also examine the ALL_OBJECTS and DBA_OBJECTS. query the user_objects USER_OBJECTS Object_name Object_Id Object_type CreateLast_DDL_Time Timestamp Status -Name of Object -Internal identifier for the object -Whether TABLE. USER_SOURCE Name -Name of the object Type -Type of object : Procedure. USER_ERRORS Name -Name of the object Type -Type of object : Procedure. Package.
text from user_errors where name=’proc_name’ order by line.Select line || ‘/’||position. .
TRIGGERS Definition : Trigger is basically a PL/SQL block or PL/SQL procedure associated with a Table/View/Schema/Database and which executes implicitly whenever a particular event takes place Types of Triggers : Application Triggers which execute implicitly when a particular DML event occurs within an application such as Oracle Forms Developer Database Triggers which could be 1) Data Event or 2) System Event Data Event trigger fires implicitly whenever a DML operation occurs on table or a DDL event such as CREATE/ALTER are issued. It could also be an INSTEAD OF Trigger on a View. They are fired irrespective of the user connected and irrespective of the application used. System Event Triggers are fired when a system event occurs such as user logs on, user shutsdown, etc Guidelines for Designing Triggers Dos Design Triggers to guarantee that when a specific operation is performed, related actions are performed. Use Triggers only for Centralised, Global Operations that occur for the triggering event, regardless of the user or application that issues the triggering statement. Donts Do not use triggers when the functionality is already built into Oracle Server. Do not use triggers to implement integrity constraints. Use the built-in constraints Excessive use of triggers can result into complex interdependencies. If the logic is very lengthy, write a stored procedure for the same and invoke the stored procedure in the trigger body If multiple triggers of the same type are defined for a table, their order of execution is arbitary. To ensure that multiple triggers of the same type are executed in a particular order, write stored procedures for the different actions and have a single consolidated trigger in which you call those stored procedures in the required order. The Trigger Statement contains : Trigger Timing :BEFORE, AFTER for tables Triggering Event :INSERT, UPDATE or DELETE Table name :On table or view Trigger Type :Statement level or Row level Trigger Body :PL SQL block INSTEAD OF for views
BEFORE :Execute the trigger body before the triggering DML event on the table To determine whether the triggering statement should be allowed to complete To calculate some values before completing the triggering Insert or Update statement To validate or set some complex business logic To initialize some global variables or flags BEFORE :Execute the trigger body before the triggering DML event on the table To complete the triggering statement before executing the trigger body INSTEAD OF This type of trigger is used to modify data through a view that was otherwise not modifiable because of the inherently non-modifiable nature of the view. Such trigger works in the background by performing the action directly on the underlying base tables involved in the view. You may write INSERT, UPDATE or DELETE statements on a view. The Triggering Event can be INSERT, UPDATE or DELETE statement on a table. In case of UPDATE statement, you can specify the column, which if changed, causes the trigger to fire. The triggering event can contain one or two or all the three DML operations. The trigger type can be Statement Trigger or Row Trigger. A Statement Trigger is fired once for the triggering event. It may affect zero or more rows, but is fired only once. They are used when the trigger-action to be performed is independent of the data affected by the triggering event. A Row Trigger is fired once for each affected row. If no rows are effected, then the trigger is not fired. They are used when the trigger-action depends on the data or rows affected by the triggering event. The Trigger body defines the action that needs to be performed when the triggering action is issued. It is a PL SQL block containing SQL and PL SQL statements defining PL SQL types, item, variables, constants, cursors, exceptions, etc. You can call other PL SQL procedures or Java Procedures. Trigger size cannot be more than 32K. The Firing Sequence is as follows : BEFORE Statement Trigger -------- once BEFORE Row Trigger AFTER Row Trigger AFTER Statement Trigger -------- once for each affected row -------- once for each affected row --------- once
Syntax for Statement Level Trigger Create or Replace Trigger Trigger_name Timing Event1 or Event2 or Event3 On table_view_name Trigger_body The trigger name must be unique with respect to other triggers in the same schema. Trigger name need not be unique with respect to other schema objects like table, view, or procedure. A trigger to prevent insertion of records into the dept table on Saturdays or Sundays or on non-working hours on other days create or replace trigger check_deptno before insert on dept begin if (to_char(sysdate,'DY') in ('SAT','SUN')) or (to_char(sysdate,'HH24:MI') not between '09:00' and '17:00' ) then raise_application_error(-20500,'Insert Not allowed'); end if; end; / Raise_application_error is a server-side built-in procedure that returns an error to the user and causes the PL SQL block to fail. When the database trigger fails, the triggering statement is automatically rolledback by Oracle Server. Table : DEPT DEPTNO varchar2 DEPTNAME vrachar2 A trigger to prevent insert or update or delete operations on table dept create or replace trigger check_deptno before insert or update or delete on dept begin if deleting then raise_application_error(-20500,'Delete Not allowed'); elsif Inserting then raise_application_error(-20501,'Insert Not allowed'); elsif Updating('deptno') then raise_application_error(-20502,'Updating of deptno Not allowed'); else raise_application_error(-20503,'Updating of Table Not allowed'); end if; end; /
Special Conditional Predicates INSERTING. / with the WHEN clause you can specify a condition in the brackets. No colon(:) required if the Qualifiers are used in the WHEN clause. UPDATING. we can use the OLD and NEW Qualifiers to reference the value of a column before and after the data change by prefixing the column name with the OLD and NEW Qualifiers. Thus. New_dept varchar2(15). end. DELETING.'Hello'). The condition is evaluated for each row to determine whether or not the trigger body is executed. Old_deptno varchar2(15). the WHEN clause is to restrict the Trigger action to those rows that satisfy a certain condition With ROW Level trigger only. Time timestamp. UPDATING(‘column’) can be used in a single trigger for combining several triggering events into one single trigger Syntax for Row Level Trigger Create or Replace Trigger Trigger_name Timing Event1 or Event2 or Event3 On table_view_name For Each Row [When (condition)] Trigger_body create or replace trigger check_dept before insert on dept for each row when(new. Operation For INSERT For UPDATE For DELETE Old Value NULL Value before update Value before update New Value Newly Inserted value Value after update NULL Table : AUDT_DEPT create table audt_dept ( User_name varchar2(15). The WHEN clause is optional. New_deptname varchar2(15) ) . Old_deptname varchar2(15). You need to use the colon(:) as a prefix in every SQL and PL SQL statement. If the condition is satisfied then only we enter into the trigger body.deptno>50) begin raise_application_error(-20555.
:old. connect by.deptno.deptname. :new.create or replace trigger audt_dept after insert or update or delete on dept for each row begin insert into audt_dept values(user. Create or Replace Trigger Trigger_name INSTEAD OF Event 1 or event2 or event3 On View_name For each row Trigger_body Even if FOR EACH ROW is omitted. start. BEFORE and AFTER options are not valid. :new. group function. :old.deptname). end. group by clause. distinct operator or a join of 2 or more tables. sysdate.deptno. INSTEAD OF Triggers is still defined as a Row Trigger. The INSTEAD OF trigger must enforce the check. Unlike other triggers. The WITH CHECK option for views is not enforced when insertion/updation are performed by using the INSTEAD OF Trigger. this trigger is fired by Oracle sever instead of executing the triggering statement. Consider the following tables : Table Empid Empname Salary Deptno Table Deptno Deptname Totalsal : Employee : Dept_stat . Such triggers are Row Level Triggers. INSTEAD OF Trigger It is used to modify the data where a DML statement has been issued against an inherently non-updatable view(that is views which are non-updatable because the underlying query may contain set operator.
:old. Update dept_stat set totalsal=totalsal+:new.empname. Elsif Updating(‘Deptno’) then Update employee set deptno=:new. dept_stat d where e.deptno. Update dept_stat set totalsal=totalsal +(:new.deptno.deptno.salary . :new.deptno.empid.salary. Update dept_stat set totalsal=totalsal + :new.salary deptno=:old. Create or Replace Trigger New_emp_check INSTEAD OF INSERT OR DELETE OR UPDATE FOR EACH ROW Begin If INSERTING THEN Insert into employee values(:new.salary where deptno=:new.salary where deptno=:new.deptno.deptno where empid=:old. Elsif DELETING Then Delete from employee where empid=:old. Update dept_stat set totalsal=totalsal-:old. where Elsif UPDATING(‘SALARY’) then Update employee set salary=:new.salary where deptno=:old.empid.deptno).deptno.deptno=d. e. End if. Create view empl_view as Select e.empid. / To Enable/Disable a Trigger Alter Trigger Trigger_name DISABLE/ENABLE To Enable/Disable all Triggers on a table Alter Table Table_name DISABLE/ENABLE ALL TRIGGERS To Recomplie a Trigger Alter Trigger Trigger_name COMPILE .deptname from employee e.empname.salary where deptno=:old. d.deptno. :new. Update dept_stat set totalsal=totalsal :old.salary where empid=:old.salary. End. :new. e.empid. e.empid.Following trigger updates the total salary in Dept_stat table whenever rows are inserted/update/deleted from the Employee table.
Trigger_body : It is a complete PL SQL Block. Causes the Oracle Server to fire the trigger whenever a Create/Alter/Drop Statement modifies a Database Object in the Data Dictionary. Table. A Schema or Table Level Trigger fires only when that schema or table is involved. Index. Triggers A Database Level Trigger fires for all users. Package. Trigger. Synonym. Type . Function. Sequence. SYSTEM LEVEL TRIGGERS Triggers on system events can be defined at the Database Level or Schema Level. Tablespace. Role.This command is used to explicitly recompile a trigger. On Database/Schema Trigger_body Timing : BEFORE or AFTER DDL_Event : CREATE OR ALTER OR DROP. Events that can cause a System Level Trigger to fire are : A DDL statement on a object in the database or schema (the trigger can be Database Level or Schema Level) Specific User or any other User logs on or off (the trigger can be Database Level or Schema Level) Database Shutdown or Startup (the trigger can be Database Level only Triggers on DDL Statements : Create OR Replace Trigger Trigger_name Timing DDL_Event1 Or DDL_Event2 or…. On Database/Schema : You can create triggers on DDL Statements at the DATABASE or SCHEMA Level. Procedure. The DDL Triggers fire when the Object is a Cluster. To Drop a Trigger Drop Trigger Trigger_name. All the triggers on a table are dropped when the table is dropped. regardless of whether it is valid or invalid. On Database/Schema Trigger_body . View or a User Triggers on System Events : Create OR Replace Trigger Trigger_name Timing Database_Event1 Or Database_Event2 or….
SYSDATE.job_id. date. :new.salary) MUTATING TABLE When the code in a trigger is querying or reading the data in a table which is being updated. ‘Logged Off’). Create or Replace Trigger salary_check Before Update of Salary .job_id<>’YYZ’) CALL check_sal(:new. Java. INSERT OR DELETE statement and a ROW . END. but SHUTDOWN and STARTUP apply only to the Database Level. The CALL statement enables you to call a stored procedure. AFTER LOGON : Whenever a User Logs on to the Database BEFORE LOGOFF : Whenever a User Logs off the Database AFTER STARTUP : Whenever a Database is opened BEFORE SHUTDOWN: Whenever a Database is shut down These triggers can be created at the DATABASE or SCHEMA LEVEL. There is no semicolon at the end of the CALL Statement. / CALL Statement : It is recommended to create stored procedures and call them in the Trigger body rather than coding the PL SQL body in the trigger itself. ‘Logged On’). The procedures so called can be implemented in PL SQL. SYSDATE. action) values(USER.Database_Events : AFTER SERVERERROR : Whenever a Server Error Message is logged. job_id ON Employees For Each Row When(new. A mutating table is the one that is currently being modified by an UPDATE. / CREATE OR REPLACE TRIGGER logoff_trig AFTER LOGOFF ON SCHEMA BEGIN Insert into log_trig_table(userid. Reading and Writing data using triggers follows certain rules. C. action) values(USER. which are applicable to only row level triggers or a statement level trigger that is fired because of the referential integrity constraint ON DELETE CASCADE. date. END. CREATE OR REPLACE TRIGGER logon_trig AFTER LOGON ON SCHEMA BEGIN Insert into log_trig_table(userid. such a table is called MUTATING table.
v_maxsal from employees where job_id=:new. table on which table was created. User_errors : Contains details of the compilation errors that occurred while the trigger was compiling . select trigger_name. select object_name. triggering_event. trigger_body from user_triggers table_name. subobject_name. status. / Viewing Trigger Information User_objects : Contains name and status of the trigger and the date and time when the trigger was created.job_id <>’PROG’) Declare V_minsal employees.) A triggered table itself is mutating. status. and any other table referencing it with the FOREIGN KEY constraint is also mutating.level trigger on any such event is trying to read/write data into the same table. type. trigger body.salary%type.salary>v_maxsal then Raise_application_error(-20505. triggering event. referencing_names. END IF: END. BEGIN Select Min(salary). created from user_objects where object_type='TRIGGER' User_Triggers : Contains name.job_id IF :New. Create or Replace Trigger Check_Sal Before INSERT Or UPDATE OF salary. (A table is not mutating for STATEMENT level triggers. trigger_type.salary<v_minsal or :New.’Salary Out Of Range’). max(salary) into v_minsal. V_maxsal employees.salary%type. Consider a trigger which checks that the salary for a new employee or an existing employee is always between the minimum and maximum salaries for that job code. job_id On Employees When (new.
Can be referenced and changed(in case of variables) outside the package and are visible to the external users. subprograms(procedures and functions) into one single container. This allows to change the definition of a program construct in the package body without causing the Oracle server to invalidate the other schema objects that call or reference the program construct. The Replace option drops and recreates the package specification. cursors. Further calls to other constructs of the same package do not need any disk I/O. the entire package gets loaded into memory. Types of Package Constructs : Public or Global : Declared within the package specification and may be defined in the package body. Package Specification is the INTERFACE to your application. constants. In the Specification we declare the variables. The package cannot be itself parameterized. Creating the Package Specification Create or Replace Package package_name Is/as Public type and item declarations Subprogram specifications End package_name. exceptions or types. which are stored separately in the database. cursors and sub programs available for use Package Body fully defines the cursors and subprograms. Can only be referenced by other constructs which are part of the same package. Subprogram specification : Declares the PL SQL subprograms. Public type and item declarations : Declares variables. has two parts : Package Specification and Package Body. The public procedures or functions can be invoked repeatedly by other constructs in the same package or from outside the package. When you call a packaged construct for the first time. Private or Local : Declared and Defined within the package body. items. A Package. exceptions. constants.PACKAGES It is used to group together related PL SQL Types. Variables declared in the package specification are initialized to NULL by default. and thus implements the specification. . called or nested. types. generally.
END comm_package. Thus.declared and initialized procedure reset_comm(p_comm IN Number). Subprogram Bodies : Defines the PL SQL subprograms. / Create or Replace Package Body comm_package Is Function validate_comm(p_comm IN Number) Return Boolean Is v_max_comm Number. Subprograms and Cursors are declared(without their respective bodies) in the package specification. Else return(TRUE). If p_comm>v_max_comm then return(FALSE). Write a package that contains a function that validates the commission so that the commission may not be greater than the highest commission amongst all the employees. Begin Select max(commission_pct) into v_max_comm from employees. public and private. then the package body is not necessary.Creating the Package Body Create or Replace Package Body package_name Is/As Private type and item declarations Subprogram Bodies(Private and Public) End package_name. if a package specification does not declare subprograms and cursors and declares only types. variables. cursors. exceptions. End validate_comm. All private constructs must be declared before they are used in the public constructs. constants.10. But the package body can still be used to initialize items declared in the package specification. exceptions or types. -. constants. The function should be called through a procedure in the same package. Private type and item declarations : Declares variables. Create or Replace Package comm_package Is g_comm Number :=0. and they have their underlying implementation(or bodies) in the package body. The Replace option drops and recreates the package body. End if. and this procedure should display the appropriate messages and reset and validate the prevailing commission. .
you need not qualify it’s name with the package name.reset_comm(0.reset_comm@ny(0. Else Raise_application_error(-20210.6093.Procedure reset_comm(p_comm IN NUMBER) Is Begin If validate_comm(p_comm) then g_comm:=p_comm. The above function is a private function(declared and defined within the package body).’).6214. yard_2_meter constant number :=0. end global_consts. / Execute dbms_output.comm_package.9144. meter_2_yard constant number :=1. This package specification declares public(global) variables that exist for the duration of the user session.reset_comm(0.25) To invoke a procedure from a package through iSQL *Plus Execute comm_package.936. End comm_package. you need to qualify it’s name with the name of the package Comm_package.reset_comm(0.15) To invoke a procedure from a package through a remote database Execute comm_package. .’Invalid Commission’). End reset_comm.mile_2_kilo|| ‘ kms. End if.15) Declaring Bodiless Package Create Or Replace Package global_consts IS mile_2_kilo constant number :=1. kilo_2_mile constant number :=0. To invoke a package procedure or function from outside the package. hence it can be referenced by only other procedures/functions of the same package. / When you invoke a package or function from within the same package.15) To invoke a procedure from a package through a different schema Execute scott.put_line(’20 miles = ‘ ||20*global_consts.
To Drop the package body : Drop Package body package_name. order or data-type of the formal parameters of the subprograms. Added Functionality since it allows persistency of variables and cursors Overloading allowed. p_yard Out number) Is Begin p_yard:=p_meter * global_consts. can be overloaded. Advantages : Modularity since it encapsulates related constructs Easier Application Design. Overloading is a feature which enables you to have different packaged subprograms with the same name. since multiple subprograms of the same name are allowed Better Performance : Entire package loaded into memory when a package is first referenced Only one copy of the package in memory for all the users Dependency hierarchy is simplified Overloading support in Packages Packaged subprograms(procedures or functions) Overloading not possible for stand-alone subprograms. since specification and body are coded and compiled separately.Referencing a Public variable from a stand-alone procedure Create or Replace procedure meter_to_yard(p_meter IN number. End meter_to_yard. .meter_2_yard. but differing in the number. / at the sql prompt >variable yard number >execute meter_to_yard(1.:yard) > print yard To Drop the package Specification : Drop Package package_name. Hiding Information : Only package declarations made in the specification are visible and accessible to applications Private package constructs are hidden and inaccessible All the coding is hidden in the package body.
empname%type default ‘unknown’. .empage%type default 21).nextval.empname%type default ‘unknown’. Example : NUMBER and DECIMAL datatypes belong to the same family Subprograms which differ only in the subtypes of their parameters. Create or replace package overload Is Procedure add_employee(p_empno IN employees. It then starts matching the number. END overload.empno%type. End add_employee.RESTRICTIONS 1) 2) 3) Standalone subprograms cannot be overloaded Subprograms which differ only in the datatypes of their parameters. it starts searching in the enclosing scopes.empage%type default 21) Is Begin Insert into employees(empno. the compiler starts searching for a subprogram with that name in the current scope.empno%type. p_age IN employees. p_age IN employees. p_empname. but the different subtypes belong to the same family. Resolving a Subprogram call When a call is made to a subprogram. p_empage). p_empname IN employees. p_empname. empname. As soon as the compiler finds one or more subprograms with the required name. p_age IN employees. Procedure add_employee(p_empname IN employees. empage) values(empnoseq. empage) values(p_empno.empname%type default ‘unknown’. p_empage).empname%type default ‘unknown’. and if it does not find one in the current scope. order and datatypes of the actual parameters passed with the called subprogram with formal parameters of the one or more subprograms searched in a scope. but the different datatypes belong to the same family.empage%type default 21) Is Begin Insert into employees(empno. Procedure add_employee(p_empname IN employees. empname. the compiler stops the search. Example : VARCHAR and STRING are PL/SQL subtypes of VARCHAR2. Create or replace package body overload Is Procedure add_employee(p_empno IN employees. p_empname IN employees. p_age IN employees.empage%type default 21).
The subprogram body can appear anywhere after the forward declaration .TO_CHAR. To solve this. you call it as :STANDARD. 32) >Execute overload. where they are invisible to the applications.End add_employee END overload. if you have redeclared the to_char function. If you redeclare a built-in subprogram as a stand-alone subprogram then to access your sub-program you need to qualify it with your schema.add_employee(101. your local declaration overrides the built-in or standard subprogram. and the subprogram bodies go in the package body. The subprogram can be then defined after another subprogram that calls it. PL/SQL allows a special subprogram declaration called Forward declaration. you need to qualify it with the package name. which means that a subprogram cannot be referenced or called before it has been declared. Thus packages support forward declarations.’Rahul’. example scott. then to use the built-in to_char function . but both must appear in the same program unit. whereby you give the subprogram specification terminated by a semicolon. . The formal parameter list must appear in both the forward declaration and the subprogram body. since the subprogram specifications go in the package specification. because the function to_char belongs to the builtin package STANDARD.add_employee(’Rahul’. At the SQL PROMPT >Execute overload. To access the built-in subprogram. since public package constructs are already declared in the package specification. Thus. Forward declarations are used when you need to : Define subprograms in a logical or alphabetical order Define mutually recursive subprograms(which call each other directly/indirectly) Group subprograms in a package Use Forward Declarations in the cases of private constructs or private subprograms of the package.to_char Using Forward Declarations PL/SQL does not allow forward referencing. 23) If you redeclare a built-in subprogram in another PL SQL Program unit.
For such type of variables do not initialize them in the declaration. The keyword END is not used at the end of the One-Time-Only procedures. In such cases. Create or Replace Package otop Is Hra number.).) Is begin Calc_rating(…) End. ----declare all other public procedures/functions/variables END otop. since such procedures are executed only once when the package is invoked within a user session.. / .Create or Replace Package Body forwardpack Is Procedure calc_rating(. / One-time-Only Procedure When the derivation of the values is too complex it is difficult to initialize public or private variables to that value in the variable declaration.No End for this one-time-only procedure END otop. ----. because the value is reset by the one-time-only procedure. --forward declaration Procedure award_bonus(…. / Create or Replace Package Body otop Is ----declare all private procedures/functions/variables ----define private/public procedures/functions Begin Select rate into hra from rate_mast where rate_name=’HRA’. we use one-time-only procedures. Procedure calc_rating(…) Is Begin End. End forwardpack.
/ Create or Replace Package Body tax_calc_pack Is Function tax_calc(p_value in number) return number Is v_rate number :=0. End tax_calc_pack. procedure reset_comm(p_comm in number). End tax_calc. End tax_calc_pack. Create or Replace Package tax_calc_pack Is Function tax_calc(p_value in number) return number. / Create or Replace Package Body comm_package Is Function validate_comm(p_comm in number) return Boolean Is v_max_comm number. Else return(FALSE). If v_max_comm >=p_comm then return(TRUE). salary from emp. .tax_calc(salary). / To use the packaged function : Select tax_calc_pack. PERSISTENT State of a Package Create or Replace Package comm_package Is g_comm number :=10. create or rollback to a savepoint or alter the system session 2) A function called from a query statement or a DML statement cannot execute a DML statement or otherwise modify the database 3) A function called from a DML statement cannot read or modify the table on which the DML was fired. Begin Select max(commission_pct) into v_max_comm from employees. Begin return(p_value*v_rate).08. end comm_package. End validate_comm.Restrictions on Package Functions 1) A function called from a query or DML statement cannot end the current transaction. End if.
Invalid Commission Rollback .25) Assume maximum is 0. since user Y did not complete his transaction. End reset_comm. Max_comm=0. maximum is still 0.9>0.6) For this user. Max_comm=0.4.reset_comm(0.4>0. Exit Logged In again Since the earlier transaction was rolled back.5) Now maximum is 0.4.4 Execute comm_package.Procedure reset_comm(p_comm IN number) Is Begin If validate_comm(p_comm) then g_comm:=p_comm.25 User Y 0930 0935 Insert into employees(empno.5 Hence g_comm=0.reset_comm(0.3 Hence g_comm=0.9.reset_comm(0.4>0.4>0.0. Else raise_application_error(-20210. End comm_package. End if.reset_comm(0. Max_comm=0.3 1000 1100 1145 .5 Execute comm_package. / Time 0900 User X Execute comm_package.5 is Invalid Hence.9) Execute comm_package.25 Hence g_comm=0.3) Max_comm=0. max_comm is 0.’Invalid Commission’). commission_pct) values(‘Ram’.
Exit when c1%rowcount>=3. End loop. the next three rows are fetched and displayed. End loop. Procedure p2 is Begin Loop Fetch c1 into v_empno. When we continue to fetch in P2. and the cursor is not closed. Exit when c1%rowcount>=6. .put_line(‘Employee Number :’ || (v_empno)). End p2. The state does not persist across several sessions of the same user or acroos different users.put_line(‘Employee Number :’ || (v_empno)). The persistent state of a cursor/variable is maintained in a session of a user. Dbms_output. Close c1. Procedure p1. Procedure p2. / The cursor is opened in P1. End pack_cur. Loop Fetch c1 into v_empno.Persistent State of a Packaged Cursor Create or Replace Package pack_cur Is Cursor c1 is select empno from emp order by empno desc. three rows are fetched and displayed. / Create or Replace Package Body pack_cur Is v_empno number. Thus packages maintain a persistent state of the package cursors. Procedure p1 is Begin Open c1. End p1. Dbms_output. End pack_cur.
photo BLOB). etc. unstructured data such as text. graphic images. NCLOB. but the LOB locator is stored in the row. A BLOB< CLOB or NCLOB can be used in one of the following : Column of a table Attribute of a user-defined type PL SQL variable. video clippings. . the following interfaces are used : PL/SQL package DBMS_LOB Oracle Call Interface(OCI) Oracle Objects for Object Linking & Embediing(OLE) Pro*C/C++/Pro*COBOL precompilers JDBC Suppose you have the following table : Create table employee (emp_id number(5). based on the byte-length of the national character set To interact with LOB. similar to LONG RAW. BFILEs can be accessed only in the read-only mode from an Oracle server Components of a LOB : The 2 distinct components of an LOB are : LOB value : It is the data that constitutes the real object being stored LOB locator : It is a pointer to the location of the LOB value stored inside the database The LOB value may be stored anywhere in the database. There are 4 large object data types BLOB for Binary large objects such as video clip CLOB for character large objects NCLOB for multibyte chracter large objects BFILE for a binary file stored at the OS level outside the database. BLOB) stored in the database External files(BFILE) stored outside the database. parameter or return value(result) BLOB is interpreted by the Oracle server as a bit-stream. CLOB is interpreted by the Oracle server as a single-byte character stream NCLOB is interpreted by the Oracle server as a multiple-byte character stream. fname varchar2(25). The BFILE column stores a file locator that points to the external file LOBs are characterized in two ways : Internal LOBs(CLOB. Internal LOBs : They are stored inside the Oracle server in the LOB segment. lname varchar2(25).LOB LOB is a data type to store large. resume CLOB.
amount of data to be written offset number. If the record is already there. resume CLOB default empty_clob(). You could have done the initialization work at the time of table definition as follows : Create table employee (emp_id number(5). ‘Hemant’.getlength(lobloc)+2. it must contain a locator that points to an empty or populated LOB value. from where and text to write . Now the columns have been initialized.’ Pangam’. Updating CLOB using DBMS_LOB in PL/SQL : Declare lobloc clob. then you could have used UPDATE command. that is. such columns must be made non-null. but not yet populated by data. This can be done through the insert or update statements as follows : Insert into employee empty_blob()). OCP Ph. empty_clob().Tech. ‘M. MCP. lname varchar2(25). MCSD. values(10. You may initialize CLOB and BLOB columns by using the functions EMPTY_CLOB() and EMPTY_CLOB() functions respectively. fname varchar2(25).write(lobloc. dbms_lob.where to start writing Begin Select resume into lobloc from employee where emp_id=10 FOR Update. OCP’. offset. amount number.Before you start writing data to CLOB/BLOB columns using DBMS_LOB package or OCI(oracle call interface) .’ ‘Manoj’. --serves as the LOB locator text varchar2(30000):='Corporate Trainer'. NULL).write at lob location. Select resume from employee. text). Insert into employee values(20. -. Now we can put values as follows : Insert into employee values(10.MCDBA. NULL). amount :=length(text). amount to be written. photo BLOB default empty_blob()).D’. ‘Hemant’. ‘MCA. ‘Pangam’. -. MCP. MCSD. -. amount.MCDBA. Pangam’. ---For update locks the row and returns the LOB locator for the ---resume lob column offset :=DBMS_LOB.
Managing BFILES Create a directory ‘saloni’ as a oracle user and give the path of the directory which contains your files as follows : Create or replace directory SALONI as ‘d:\saloni\saloni’ Give read privileges to users on that directory as follows : grant read on directory SALONI to public.substr(resume. End. Dbms_output. Amount:=length(text) . Col2 BLOB).'c1.'c2. 5). / Selecting CLOB values using DBMS_LOB select dbms_lob. To disassociate a LOB value from a row: Update employee set resume =empty_clob() where emp_id=40 To Add LOB columns Alter table table_name add(col1 CLOB. End.bmp are existing in the folder : insert into x values(‘c1’.append at lob location.instr(resume. amount. dbms_lob.writeappend(lobloc. 'Cor') from employee Selecting CLOB values in PL/SQL Declare Text varchar2(4000).bmp')).text:='Corporate Consultant cum System Analyst'. bfilename('saloni'. Begin Select resume into text from employee where emp_id=10. text). / Removing LOBs To delete row containing LOBs : Delete from employee where emp_id=30.put_line(‘Resume is : ‘ || text). insert into x values(‘c2’. amount to be written and text to write commit. Use the BFILENAME function to inset values as follows. bfilename('saloni'.bmp')) . create the following table : create table x(col1 varchar2(10). ensuring tha the files c1. Select resume into lobloc from employee where emp_id=20 FOR Update.bmp and c2. col2 bfile). dbms_lob. -. 5.
bmp'. cursor emp_cursor is select col1 from x for update. update x set col2=v_file where current of emp_cursor. dbms_lob. Then the following procedure is used to load a BFILE pointer to an image of each employee into the table ‘X’ using DBMS_LOB package Create or Replace procedure load_emp (p_file_loc IN varchar2) IS v_file BFILE. v_filename varchar2(20).Once physical files are associated with the records using SQL.put_line('Loaded File :' || v_filename ||' size : '|| dbms_lob.getlength(v_file)). End loop. dbms_lob. v_file:=BFILENAME(p_file_loc. you may now use subsequent read operations on BFILE using the PL/SQL dbms_lob package and OCI. End load_emp. Begin For erec IN emp_cursor Loop v_filename:=erec. v_filename). dbms_output.fileclose(v_file).fileopen(v_file). / .col1||'.
This action might not be possible to undo. Are you sure you want to continue?
We've moved you to where you read on your other device.
Get the full title to continue reading from where you left off, or restart the preview.