Download presentation
Presentation is loading. Please wait.
1
Programming in Oracle with PL/SQL
Extension to SQL Procedural Language
2
Overview Overview of PL/SQL Data type and Variables Program Structures
Triggers Database Access Using Cursors Records PL/SQL Tables Built-in Packages Error-Handling PL/SQL Access to Oracle 10g Objects
3
PL/SQL Allows using general programming tools with SQL, for example: loops, conditions, functions, etc. This allows a lot more freedom than general SQL, and is lighter-weight than JDBC. We write PL/SQL code in a regular file, for example PL.sql, and load it in the sqlplus console. PL/SQL is a special language available for developers to code stored procedures which are integrated seamlessly with the database objects via SQL. The language, however, has far more potential than the simple commands of SQL (UPDATE, SELECT, INSERT & DELETE). The language allows for modularity and complexity of standard procedural languages. Loops and variables are permitted within this language which makes if far more useful for data extraction and manipulation than the standard SQL. PL/SQL is used to enforce the logic and business rules of the database application. It is a simple language which has all the logic constructs of a programming language and the advantage of a robust error handling system which is not common in other procedural languages. The modularization of code is another advantage to the language and allows for the re-use of code once created in a procedure. PL/SQL is the only programming language which will natively interact with a Oracle database and within the database environment. The language is managed centrally within the database and the DBA manages the source code and execution privileges in the same way as they manage other database objects. Once a procedure has been created is is treated the same way as other DB objects.
4
Other Databases All have procedural facilities
SQL is not functionally complete Lacks full facilities of a programming language So top up functionality by embedding SQL in a procedural language PL/SQL techniques are specific to Oracle but procedures and functions can be ported to other systems
5
Why use PL/SQL Manage business rules – through middle layer application logic. Generate code for triggers Generate code for interface Enable database-centric client/server applications The main disadvantage of a client/server application is the difficulty in maintaining the business rules for an application. The middle layer of Oracle application logic means that the business rules are no longer decentralised throughout the application. The data is validated etc. before being written to the database i.e.: data is entered via the client end …. The business rules are applied ….. The data is written to the database. This gives the advantage that the code is centrally managed by the DBA of a system, this is where the authority to access a procedure by a user or object is granted, it also means that any changes to either business rules or authorities are managed in one place making the system more robust. Once a procedure has been complied that change is automatically available to those who have authority to view or access that procedure. On business systems where the logic is stored on the client end of the application the change will have to be reflected throughout the distributed system. The risk of a system being missed is reduced. PL/SQL procedures are all stored on the central database, they are processed on the server not the client, one change to the procedure is all that is needed rather than the change having to be reflected on every client. Also because the procedure is performed on the server the processing time is server dependent not client (ie better) Triggers on tables etc. will be coded in PL/SQL which gives them more power the code is also easy to read and therefore debugging the code or maintaining the code for other developers or DBA is more straight forward (this does not mean that the developer can reduce the number of comments within the code !). If an interface is used and Oracle forms is used then PL/SQL may be used to interface between the client and the database. This is the same as coding in the “middle layer” of the system and is a way of ensuring that the data is correct prior to being written to the database. “Database-centric client/server application” this basically is the same as the first point but it’s a fancy way of saying it :O)
6
Using PL/SQL as a programming language
Permits all operations of standard programming languages e.g. Conditions IF-THEN-ELSE-END IF; Jumps GOTO Provides loops for controlling iteration LOOP-EXIT; WHEN-END LOOP; FOR-END LOOP; WHILE-END LOOP Allows extraction of data into variables and its subsequent manipulation
7
Overview Overview of PL/SQL Data type and Variables Program Structures
Triggers Database Access Using Cursors Records PL/SQL Tables Built-in Packages Error-Handling PL/SQL Access to Oracle 10g Objects
8
Use of Data-Types Number – used to store any number
<variable-name> <datatype> [not null][: =<initial-value>]; <constant-name> constant <datatype> : = <value>]; Number – used to store any number Char(size) & varchar2(size) e.g.: char(10) – used to store alphanumerical text strings, the char data type will pad the value stored to the full length declared. Date – used to store dates Long – used to store large blocks of text up to 2 gigabytes in length (limited operations) PL/SQL offers great flexibility in variable declaration. There are several data types that can be used in PL/SQL that correspond to the datatypes used on the database these are detailed on the next 2 slides. You should be aware of them but will not be expected to know them all. The ones above are the most common used. The aim of these following slides is to illustrate to you the flexibility of the datatypes available and to give a brief description of what each datatype if for so that if you see code in books you will have a better understanding of what it being stored in the database.
9
More data-types Long raw – stores large blocks of data stored in binary format Raw – stores smaller blocks of data in binary formal Rowid – used to store the special format of rowid’s on the database
10
Variable and constant declaration
<variable-name> <datatype> [not null][: =<initial-value>]; <constant-name> constant <datatype> [: = <value>];
11
Anchored Data Type <variable-name> <object> %type [not null][: =<initial-value>]; Variables can also be declared to have anchored data types Data types are determined by looking up another object’s data type. This another data type could be a column in the database, thereby providing the ability to match the data types of PL/SQL variables with the data types of columns defined in the database.
12
Anchored Data Type Example
<variable-name> <object> %type [not null][: =<initial-value>]; commission real(5,2) := 12.5 X commission%type; Cname employee.empname%type; Record.element notation will address components of tuples (dot notation) Empid empname addr1 addr2 addr3 postcode grade salary employee
13
Anchored Data Type Example
Select values into PL/SQL variables using INTO %rowtype allows full rows to be selected into one variable Empid empname addr1 addr2 addr3 postcode grade salary V_employee employee%rowtype The SQL statements are seamlessly integrated into the PL/SQL scripts. There are no special characters required to prefix the commands with as the database will automatically internally handle these commands. The only concession required is the INTO clause. All values which are returned by a select statement must be stored in a variable. The statement INTO indicates where to store the data. By referencing the record and specifying the element of that record you can update or delete specific data in the system (example on the next slide). %rowtype is a datatype that has not been stated earlier, what this means is that an entire row is held as a variable. By declaring a variable as a rowtype of a specific table you are able to retrieve whole rows of data and store that data in one record. This will then be used to support record.element notation
14
Anchored Data Type Example
Selects entire row of data into 1 variable called v_employee Is updating the value of salary based on selected element of a variable p1.sql The use of %rowtype is similar to an array, each row is held in one variable and then data from specific elements of the record are accessed by their field name in the same way an array accesses data based on the position of that data in the array.
15
Overview Overview of PL/SQL Data type and Variables Program Structures
Triggers Database Access Using Cursors Records PL/SQL Tables Built-in Packages Error-Handling PL/SQL Access to Oracle 10g Objects
16
Program Structures: Procedures and Functions
A set of SQL and PL/SQL statements grouped together as a unit (block) to solve a specific problem or perform a set of related tasks. An anonymous block is a PL/SQL block that appears within your application and it is not named or stored in the database. In many applications, PL/SQL blocks can appear wherever SQL statements can appear. A stored procedure is a PL/SQL block that Oracle stores in the database and can be called by name from an application. May or may not return a value. Functions always return a single value to the caller; procedures do not return values to the caller. Packages are groups of procedures and functions.
17
PL/SQL Blocks PL/SQL code is built of Blocks, with a unique structure.
Anonymous Blocks: have no name (like scripts) can be written and executed immediately in SQLPLUS can be used in a trigger
18
Anonymous Block Structure
DECLARE (optional) /* Here you declare the variables you will use in this block */ BEGIN (mandatory) /* Here you define the executable statements (what the block DOES!)*/ EXCEPTION (optional) /* Here you define the actions that take place if an exception is thrown during the run of this block */ END; (mandatory) / A correct completion of a block will generate the following message: PL/SQL procedure successfully completed Always put a new line with only a / at the end of a block! (This tells Oracle to run the block)
19
Anonymous Blocks customers cursor c SQL> start p2.sql
c-rec (row of c) c_table SQL> start p2.sql Gets all the rows from customers table and prints the names of the customers on the screen. It uses tables and cursors.
20
DECLARE Syntax Examples identifier [CONSTANT] datatype [NOT NULL]
[:= | DEFAULT expr]; Notice that PL/SQL includes all SQL types, and more… Declare birthday DATE; age NUMBER(2) NOT NULL := 27; name VARCHAR2(13) := 'Levi'; magic CONSTANT NUMBER := 77; valid BOOLEAN NOT NULL := TRUE;
21
Declaring Variables with the %TYPE Attribute
Examples Accessing column sname in table Sailors DECLARE sname Sailors.sname%TYPE; fav_boat VARCHAR2(30); my_fav_boat fav_boat%TYPE := 'Pinta'; ... Accessing another variable
22
Declaring Variables with the %ROWTYPE Attribute
Declare a variable with the type of a ROW of a table. And how do we access the fields in reserves_record? Accessing table Reserves reserves_record Reserves%ROWTYPE; reserves_record.sid:=9; Reserves_record.bid:=877;
23
Creating a PL/SQL Record
A record is a type of variable which we can define (like ‘struct’ in C or ‘object’ in Java) DECLARE TYPE sailor_record_type IS RECORD (sname VARCHAR2(10), sid VARCHAR2(9), age NUMBER(3), rating NUMBER(3)); sailor_record sailor_record_type; ... BEGIN Sailor_record.sname:=‘peter’; Sailor_record.age:=45; …
24
Creating a Cursor We create a Cursor when we want to go over a result of a query (like ResultSet in JDBC) Syntax Example: DECLARE cursor c is select * from sailors; sailorData sailors%ROWTYPE; BEGIN open c; fetch c into sailorData; sailorData is a variable that can hold a ROW from the sailors table Here the first row of sailors is inserted into sailorData
25
SELECT Statements INTO clause is required.
DECLARE v_sname VARCHAR2(10); v_rating NUMBER(3); BEGIN SELECT sname, rating INTO v_sname, v_rating FROM Sailors WHERE sid = '112'; END; / INTO clause is required. Query must return exactly one row. Otherwise, a NO_DATA_FOUND or TOO_MANY_ROWS exception is thrown
26
Conditional logic If <cond> then <command>
Nested conditions: If <cond> then <command> elsif <cond2> then <command2> else <command3> end if; If <cond> then if <cond2> <command1> end if; else <command2>
27
IF-THEN-ELSIF Statements
. . . IF rating > 7 THEN v_message := 'You are great'; ELSIF rating >= 5 THEN v_message := 'Not bad'; ELSE v_message := 'Pretty bad'; END IF; IF-THEN-ELSIF Statements When possible, use the ELSIF clause instead of nesting IF statements. The code is easier to read and understand, and the logic is clearly identified. If the action in the ELSE clause consists purely of another IF statement, it is more convenient to use the ELSIF clause. This makes the code clearer by removing the need for nested END IFs at the end of each further set of conditions and actions. Example IF condition1 THEN statement1; ELSIF condition2 THEN statement2; ELSIF condition3 THEN statement3; END IF; The example IF-THEN-ELSIF statement above is further defined as follows: For a given value entered, return a calculated value. If the entered value is over 100, then the calculated value is two times the entered value. If the entered value is between 50 and 100, then the calculated value is 50% of the starting value. If the entered value is less than 50, then the calculated value is 10% of the starting value. Note: Any arithmetic expression containing null values evaluates to null.
28
Suppose we have the following table:
mylog create table mylog( who varchar2(30), logon_num number ); logon_num who 3 Peter 4 John 2 Moshe Want to keep track of how many times someone logged on to the DB When running, if user is already in table, increment logon_num. Otherwise, insert user into table
29
Solution DECLARE cnt NUMBER; BEGIN select logon_num
into cnt //variable store current logon nums from mylog where who = user;//func returns current user name if cnt > 0 then update mylog set logon_num = logon_num + 1 where who = user; else insert into mylog values(user, 1); end if; commit; end; /
30
SQL Cursor SQL cursor is automatically created after each SQL query. It has 4 useful attributes: SQL%ROWCOUNT Number of rows affected by the most recent SQL statement (an integer value). SQL%FOUND Boolean attribute that evaluates to TRUE if the most recent SQL statement affects one or more rows. SQL%NOTFOUND Boolean attribute that evaluates to TRUE if the most recent SQL statement does not affect any rows. SQL%ISOPEN Always evaluates to FALSE because PL/SQL closes implicit cursors immediately after they are executed. SQL Cursor Attributes SQL cursor attributes allow you to evaluate what happened when the implicit cursor was last used. You use these attributes in PL/SQL statements such as functions. You cannot use them in SQL statements. You can use the attributes, SQL%ROWCOUNT, SQL%FOUND, SQL%NOTFOUND, and SQL%ISOPEN in the exception section of a block to gather information about the execution of a data manipulation statement. PL/SQL does not consider a DML statement that affects no rows to have failed, unlike the SELECT statement, which returns an exception.
31
Solution (2) BEGIN update mylog set logon_num = logon_num + 1
where who = user; if SQL%ROWCOUNT = 0 then insert into mylog values(user, 1); end if; commit; END; /
32
Loops: Simple Loop create table number_table( num NUMBER(10) );
DECLARE i number_table.num%TYPE := 1; BEGIN LOOP INSERT INTO number_table VALUES(i); i := i + 1; EXIT WHEN i > 10; END LOOP; END; 1 to 10
33
Loops: Simple Cursor Loop
create table number_table( num NUMBER(10) ); DECLARE cursor c is select * from number_table; cVal c%ROWTYPE; BEGIN open c; LOOP fetch c into cVal; EXIT WHEN c%NOTFOUND; insert into number_table values(cVal.num*2); END LOOP; END;
34
Loops: FOR Loop DECLARE i number_table.num%TYPE; BEGIN
FOR i IN LOOP INSERT INTO number_table VALUES(i); END LOOP; END; Notice that i is incremented automatically
35
Loops: For Cursor Loops
DECLARE cursor c is select * from number_table; BEGIN for num_row in c loop insert into doubles_table values(num_row.num*2); end loop; END; / Cursor FOR Loops A cursor FOR loop processes rows in an explicit cursor. The cursor is opened, rows are fetched once for each iteration in the loop, and the cursor is closed automatically when all rows have ben processed. The loop itself is terminated automatically at the end of the iteration where the last row was fetched. Notice that a lot is being done implicitly: declaration of num_row, open cursor, fetch cursor, the exit condition (refer to slide 19 for details)
36
Loops: WHILE Loop DECLARE TEN number:=10; i number_table.num%TYPE:=1;
BEGIN WHILE i <= TEN LOOP INSERT INTO number_table VALUES(i); i := i + 1; END LOOP; END; WHILE Loop In the example in the slide, the quantity increases with each iteration of the loop until the quantity is no longer less than the maximum price allowed for spending on the item.
37
Printing Output You need to use a function in the DBMS_OUTPUT package in order to print to the output If you want to see the output on the screen, you must type the following (before starting): set serveroutput on format wrapped size Then print using dbms_output. put_line(your_string); dbms_output.put(your_string);
38
Input and output example
set serveroutput on format wrap size ACCEPT high PROMPT 'Enter a number: ' DECLARE i number_table.num%TYPE:=1; BEGIN dbms_output.put_line('Look, I can print from PL/SQL!!!'); WHILE i <= &high LOOP INSERT INTO number_table VALUES(i); i := i + 1; END LOOP; END;
39
Reminder- structure of a block
DECLARE (optional) /* Here you declare the variables you will use in this block */ BEGIN (mandatory) /* Here you define the executable statements (what the block DOES!)*/ EXCEPTION (optional) /* Here you define the actions that take place if an exception is thrown during the run of this block */ END; (mandatory) /
40
Functions and Procedures
41
Functions and Procedures
It is useful to put code in a function or procedure so it can be called several times Once we create a procedure or function in a Database, it will remain until deleted (like a table).
42
Creating Procedures Modes: Default Mode is: IN
CREATE [OR REPLACE] PROCEDURE procedure_name [(parameter1 [mode1] datatype1, parameter2 [mode2] datatype2, . . .)] IS|AS PL/SQL Block; Modes: IN: procedure must be called with a value for the parameter. Value cannot be changed OUT: procedure must be called with a variable for the parameter. Changes to the parameter are seen by the user (i.e., call by reference) IN OUT: value can be sent, and changes to the parameter are seen by the user Default Mode is: IN
43
Procedures Creation command Variable declarations Body of code
Create or replace procedure sample1 as v_num1 constant number := 2.5; v_num2 constant number := 4; v_product number; BEGIN v_product := v_num1 * v_num2; END; This is a very simple procedure and one which would not be used in the real world but it should illustrate to you the syntax of a procedure creation. There are a number of unofficial conventions which are apparent here but will be expanded upon now. The first is the naming conventions. Variables on the example are named with the v_ prefix, this is therefore apparent to those reading the code that these are variables and not field names, this becomes more useful the more complex the code. In the same way a cursor will be prefixed with cur_ so that it is obvious when the code is read that a cursor is being accessed etc.
44
Example- what does this do?
Table mylog create or replace procedure num_logged (person IN mylog.who%TYPE, num OUT mylog.logon_num%TYPE) IS BEGIN select logon_num into num from mylog where who = person; END; / logon_ num who 3 Pete 4 John 2 Joe Output the number of logons to variable num given the name of person from person
45
Calling the Procedure declare howmany mylog.logon_num%TYPE; begin
num_logged(‘John',howmany); dbms_output.put_line(howmany); end; / More procedures: p3.sql
46
Errors in a Procedure When creating the procedure, if there are errors in its definition, they will not be shown To see the errors of a procedure called myProcedure, type SHOW ERRORS PROCEDURE myProcedure in the SQLPLUS prompt For functions, type SHOW ERRORS FUNCTION myFunction
47
Creating a Function Almost exactly like creating a procedure, but you supply a return type CREATE [OR REPLACE] FUNCTION function_name [(parameter1 [mode1] datatype1, parameter2 [mode2] datatype2, . . .)] RETURN datatype IS|AS PL/SQL Block;
48
NOTE THAT YOU DON'T SPECIFY THE SIZE
A Function create or replace function rating_message(rating IN NUMBER) return VARCHAR2 AS BEGIN IF rating > 7 THEN return 'You are great'; ELSIF rating >= 5 THEN return 'Not bad'; ELSE return 'Pretty bad'; END IF; END; / NOTE THAT YOU DON'T SPECIFY THE SIZE
49
Calling the function declare paulRate:=9;
Begin dbms_output.put_line(ratingMessage(paulRate)); end; / More functions: p4.sql
50
Creating a function: Using the function:
create or replace function squareFunc(num in number) return number is BEGIN return num*num; End; / Using the function: BEGIN dbms_output.put_line(squareFunc(3.5)); END; /
51
Stored Procedures and Functions
The procedures and functions we discussed were called from within the executable section of the anonymous block. It is possible to store the procedure or function definition in the database and have it invoked from various of environments. This feature allows for sharing of PL/SQL code by different applications running in different places.
52
Stored Procedures Program code . HIRE_EMP(…); HIRE_EMP(…) BEGIN END; Database Applications Stored Procedure Database Created in a user's schema and stored centrally, in compiled form in the database as a named object that can be: interactively executed by a user using a tool like SQL*Plus called explicitly in the code of a database application, such as an Oracle Forms or a Pre compiler application, or in the code of another procedure or trigger When PL/SQL is stored in the database, applications can send blocks of PL/SQL to the database rather than individual SQL statements reducing network traffic. .
53
Stored Procedures and Functions
CREATE [OR REPLACE] PROCEDURE procedure_name [(parameter1 [mode1] datatype1, parameter2 [mode2] datatype2, . . .)] AS PL/SQL Block; AS keyword means stored procedure/function IS keyword means part of anonymous block So does stored function
54
Stored function: p5.sql Call Stored function
SQL>SELECT CNO, CNAME, get_city(cno) 2 from customers; CNO CNAME GET_CITY(CNO) 1111 Charles Wichita 2222 Bertram Wichita get_city function returns city name given customer number. customers(cno, cname, zip) zipcodes(cnum, zip, city)
55
Benefits of Stored Procedures I
Security Control data access through procedures and functions. E.g. grant users access to a procedure that updates a table, but not grant them access to the table itself. Performance The information is sent only once between database and application and thereafter invoked when it is used. Network traffic is reduced compared with issuing individual SQL statements or sending the text of an entire PL/SQL block A procedure's compiled form is readily available in the database, so no compilation is required at execution time. The procedure might be cached
56
Benefits of Procedures II
Memory Allocation Stored procedures take advantage of the shared memory capabilities of Oracle Only a single copy of the procedure needs to be loaded into memory for execution by multiple users. Productivity By designing applications around a common set of procedures, you can avoid redundant coding and increase your productivity. Procedures can be written to insert, update, or delete rows from a table and then called by any application without rewriting the SQL statements necessary to accomplish these tasks. If the methods of data management change, only the procedures need to be modified, not all of the applications that use the procedures.
57
Benefits of Procedures III
Integrity Stored procedures improve the integrity and consistency of your applications. By developing all of your applications around a common group of procedures, you can reduce the likelihood of committing coding errors. You can test a procedure or function to guarantee that it returns an accurate result and, once it is verified, reuse it in any number of applications without testing it again. If the data structures referenced by the procedure are altered in any way, only the procedure needs to be recompiled; applications that call the procedure do not necessarily require any modifications.
58
Packages collection of procedures and function
In a package, you can allow some of the members to be "public" and some to be "private" There are also many predefined Oracle packages
59
Packages Example A package called process_orders in p6.sql
Contains three procedures add_order takes user input and insert a new row to orders table. add_order_details receives input and add a new row to odetails table. ship_order updates shipped value for the order. Execute procedures in the package: SQL> execute process_orders.add_order(2000,111,1000,null); SQL> execute process_orders.add_order_details(2000,10509,50) ; SQL> execute process_orders.ship_order(2000,10509,50);
60
Exercises in bb4.utc.edu Create three databases using the scripts from blackboard. File name is plsql.ch02. Start and test procedures or functions from p1.sql to p6.sql. File name is plsql.ch03.
Similar presentations
© 2024 SlidePlayer.com Inc.
All rights reserved.