CIS4368: Advanced Database Slide # 1 PL/SQL PL/SQL Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 2 PL/SQL Procedural Language for SQL (PL/SQL) is an extension of Oracle SQL The basic intent of PL/SQL is increase the expressiveness of SQL process query results in a tuple-oriented way develop modular database application programs reuse program code, and reduce the cost for maintaining and changing applications. The basic construct of PL/SQL is a block constants and variables can be declared, and variables can be used to store query results. Statements in a PL/SQL block include: SQL statements Control structures (loops) Condition statements (if-then-else) Exception handling Calls of other PL/SQL blocks. Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 3 PL/SQL Each block builds a (named) program unit, and blocks can be nested. The structure of a PL/SQL looks as follows: (brackets [ ] enclose optional parts) [<Block header>] [declare <Constants> <Variables> <Cursors> <User defined exceptions>] begin <PL/SQL statements> [exception <Exception handling>] end; Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 4 PL/SQL Consider the following simple code: Needed to display output Our local variable of data type DATE Get today’s date and store it in our variable Display the contents of the variable Program Output Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 5 PL/SQL Numeric operations in PL/SQL: Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 6 PL/SQL Bind Variables: Host variables: Declared in the SQL “Host Environment” Remain active for the length of the SQL Session Can be displayed with the SQL Print Command Can only be accessed in the program when prefaced with a colon (:) Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 7 PL/SQL Interactive Input: Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 8 PL/SQL Control Structures: IF-THEN: Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 9 PL/SQL Control Structures: IF-THEN-ELSE: Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 10 PL/SQL Control Structures: IF-THEN-ELSIF: Dr. Peeter Kirs (Note Spelling) Spring, 2003 CIS4368: Advanced Database Slide # 11 PL/SQL Control Structures: Basic Loop: Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 12 PL/SQL Control Structures: While: Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 13 PL/SQL Control Structures: For: Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 14 PL/SQL SQL in PL: We must be careful about single record/field queries and multiple return queries Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 15 PL/SQL Single Return Queries: The data type applied to field studentname is automatically applied Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 16 PL/SQL Multiple Record Queries: Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 17 PL/SQL Remember our problem about calculating a student grade? Variable Declarations: /* This program calculates a grade */ declare cursor studentgrade is select lastname, firstname, quiz1, quiz2, quiz3 from grades; studentlastname grades.lastname%type; studentfirstname grades.firstname%type; q1 grades.quiz1%type; q2 grades.quiz2%type; q3 grades.quiz3%type; average number; sgrade grades.grade%type; nblanks number; blanks char(5); Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 18 PL/SQL Remember our problem about calculating a student grade? begin dbms_output.put_line('Student Name Grade'); dbms_output.put_line('------------------ -----'); open studentgrade; loop fetch studentgrade into studentlastname, studentfirstname, q1, q2, q3; exit when studentgrade%notfound; average := (q1 + q2 + q3)/3; nblanks := 20 - (length(trim(studentfirstname)) + length(trim(studentlastname))); if average >= 90 then sgrade := 'A'; elsif average >= 80 then sgrade := 'B'; elsif average >= 70 then sgrade := 'C'; elsif average >= 60 then sgrade := 'D'; else sgrade := 'F'; end if; dbms_output.put_line(trim(studentfirstname) || ' ' || trim(studentlastname) || lpad(' ',nblanks,' ') || sgrade); update grades set grade = sgrade; end loop; close studentgrade; end; Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 19 PL/SQL Remember our problem about calculating a student grade? Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 20 PL/SQL Exceptions: Act as error handling routines Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 21 PL/SQL Types of Exceptions: Exception Name No_data_found Too_Many_rows Zero_Divide Value_Error Storage_Error Login_Denied Program_Error Access_Into_Null Description Single row select returned no data Single row select returned multiple rows Attempt to divide by zero Arithmetic, Conversion, Truncation error PL/SQL ran out of memory or memory corrupted Invalid Username or password Run Time error Attempt to assign values to uninitialized object Invalid_Cursor Rowtype_Mismatch Illegal cursor operation Cursor variable involved in incompatible return types --- And Others --- Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 22 PL/SQL Procedures: Remember our Grading program? We could have created it as stored Procedure: Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 23 PL/SQL To run the program: Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 24 PL/SQL Functions, which are called by procedures, can also be created and stored: Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 25 PL/SQL To call the function: Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 26 PL/SQL Triggers: A stored block which is implicitly called when an event occurs A triggering event is based on a Data Manipulation Language statement such as: • INSERT • UPDATE • DELETE Execution of the trigger is known as firing the trigger Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 27 PL/SQL Recall our problem about determining whether or not a student had enrolled for two classes at the same time Information about students in a class was found only in the table enrollment Information about when a class met was found only in the table class If the information were in one table we could apply a constraint which would not allow a student to enroll in both classes: Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 28 PL/SQL However, even if we had created this table, it still would not stop a student from enrolling in two classes that meet at the same time Enrollment in a class is done by entering a record in table enrollment (not table temp_table) One way to stop dual enrollment is to set a trigger which tries to insert the record (from enrollment) into table temp_table (which contains the constraint) If the record can be inserted into temp_table, it will then be inserted into table enrollment If the record can NOT be inserted into temp_table, it will NOT be inserted into table enrollment Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 29 PL/SQL The trigger might appear as: FOR EACH ROW is a row trigger which fires once for each row inserted: :NEW refers to the new record to be inserted Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 30 PL/SQL Suppose we look up the Spring 2003 (semester = 102) schedule for Yao Ming (studentid = 21098765): There is one other class that meets at the same time Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 31 PL/SQL If we now try and enroll Yao for the other class: Dr. Peeter Kirs Spring, 2003 CIS4368: Advanced Database Slide # 32 PL/SQL Dr. Peeter Kirs Spring, 2003