Download presentation
Presentation is loading. Please wait.
Published byFlorence Malone Modified over 9 years ago
1
Introduction to PL/SQL with Oracle - Self Study P S Despande
2
Programming in Oracle with PL/SQL ProceduralLanguageExtension toSQL
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 with @PL in the sqlplus console.
4
Bordoloi and Bock PL/SQL : INTRODUCTION
5
Bordoloi and Bock PL/SQL PL/SQL is Oracle's procedural language extension to SQL, the non-procedural relational database language. With PL/SQL, you can use SQL statements to manipulate ORACLE data and the flow of control statements to process the data. Moreover, you can declare constants and variables, define subprograms (procedures and functions), and trap runtime errors. Thus, PL/SQL combines the data manipulating power of SQL with the data processing power of procedural languages.
6
Bordoloi and Bock PL/SQL Many Oracle applications are built using client-server architecture. The Oracle database resides on the server. The program that makes requests against this database resides on the client machine. This program can be written in C, Java, or PL/SQL. While PL/SQL is just like any other programming language, it has syntax and rules that determine how programming statements work together. It is important for you to realize that PL/SQL is not a stand-alone programming language. PL/SQL is a part of the Oracle RDBMS, and it can reside in two environments, the client and the server.
7
Bordoloi and Bock PL/SQL As a result, it is very easy to move PL/SQL modules between server-side and client-side applications. When the PL/SQL engine is located on the server, the whole PL/SQL block is passed to the PL/SQL engine on the Oracle server. The PL/SQL engine processes the block according to the Figure 2.1.
8
Bordoloi and Bock
9
PL/SQL When the PL/SQL engine is located on the client, as it is in the Oracle Developer Tools, the PL/SQL processing is done on the client side. All SQL statements that are embedded within the PL/SQL block are sent to the Oracle server for further processing. When PL/SQL block contains no SQL statement, the entire block is executed on the client side.
10
Bordoloi and Bock DIFFERENCE BETWEEN PL/SQL AND SQL When a SQL statement is issued on the client computer, the request is made to the database on the server, and the result set is sent back to the client. As a result, a single SQL statement causes two trips on the network. If multiple SELECT statements are issued, the network traffic increase significantly very fast. For example, four SELECT statements cause eight network trips. If these statements are part of the PL/SQL block, they are sent to the server as a single unit. The SQL statements in this PL/SQL program are executed at the server and the result set is sent back as a single unit. There is still only one network trip made as is in case of a single SELECT statement.
11
Bordoloi and Bock Comparison of SQL*PLUS and PL/SQL
12
Bordoloi and Bock PL/SQL BLOCKS PL/SQL blocks can be divided into two groups: 1. Named and 2. Anonymous. Named blocks are used when creating subroutines. These subroutines are procedures, functions, and packages. The subroutines can be stored in the database and referenced by their names later on. In addition, subroutines can be defined within the anonymous PL/SQL block. Anonymous PL/SQL blocks do not have names. As a result,they cannot be stored in the database and referenced later.
13
Bordoloi and Bock PL/SQL BLOCK STRUCTURE PL/SQL blocks contain three sections 1. Declare section 2. Executable section and 3. Exception-handling section. The executable section is the only mandatory section of the block. Both the declaration and exception-handling sections are optional.
14
Bordoloi and Bock PL/SQL BLOCK STRUCTURE PL/SQL block has the following structure: DECLARE Declaration statements BEGIN Executable statements EXCETION Exception-handling statements END ;
15
Bordoloi and Bock DECLARATION SECTION The declaration section is the first section of the PL/SQL block. It contains definitions of PL/SQL identifiers such as variables, constants, cursors and so on. Example DECLARE v_first_name VARCHAR2(35) ; v_last_name VARCHAR2(35) ; v_counter NUMBER := 0 ;
16
Bordoloi and Bock EXECUTABLE SECTION The executable section is the next section of the PL/SQL block. This section contains executable statements that allow you to manipulate the variables that have been declared in the declaration section. BEGIN SELECT first_name, last_name INTO v_first_name, v_last_name FROM student WHERE student_id = 123 ; DBMS_OUTPUT.PUT_LINE (‘Student name :’ || v_first_name ||‘ ’|| v_last_name); END;
17
Bordoloi and Bock EXCEPTION-HANDLING SECTION The exception-handling section is the last section of the PL/SQL block. This section contains statements that are executed when a runtime error occurs within a block. Runtime errors occur while the program is running and cannot be detected by the PL/SQL compiler. EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE (‘ There is no student with student id 123 ’); END;
18
Bordoloi and Bock HOW PL/SQL GETS EXECUTED Every time an anonymous block is executed, the code is sent to the PL/SQL engine on the server where it is compiled. The named PL/SQL block is compiled only at the time of its creation, or if it has been changed. The compilation process includes syntax checking, binding and p-code generation. Syntax checking involves checking PL/SQL code for syntax or compilation errors. Once the programmer corrects syntax errors, the compiler can assign a storage address to program variables that are used to hold data for Oracle. This process is called Binding.
19
Bordoloi and Bock HOW PL/SQL GETS EXECUTED After binding, p-code is generated for the PL/SQL block. P-code is a list of instructions to the PL/SQL engine. For named blocks, p-code is stored in the database, and it is used the next time the program is executed. Once the process of compilation has completed successfully, the status for a named PL/SQL block is set to VALID, and also stored in the database. If the compilation process was not successful, the status for a named PL/SQL block is set to INVALID.
20
Bordoloi and Bock PL/SQL IN SQL*PLUS SQL*Plus is an interactive tool that allows you to type SQL or PL/SQL statements at the command prompt. These statements are then sent to the database. Once they are processed, the results are sent back from the database and displayed on the screen. There are some differences between entering SQL and PL/SQL statements.
21
Bordoloi and Bock SQL EXAMPLE SELECT first_name, last_name FROM student; The semicolon terminates this SELECT statement. Therefore, as soon as you type semicolon and hit the ENTER key, the result set is displayed to you.
22
Bordoloi and Bock PL/SQL EXAMPLE DECLARE v_first_name VARCHAR2(35); v_last_name VARCHAR2(35); BEGIN SELECT first_name, last_name INTO v_first_name, v_last_name FROM student WHERE student_id = 123; DBMS_OUTPUT.PUT_LINE ('Student name: '||v_first_name||' '||v_last_name); EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE ('There is no student with student id 123'); END;. /
23
Bordoloi and Bock PL/SQL EXAMPLE There are two additional lines at the end of the block containing “.” and “/”. The “.” marks the end of the PL/SQL block and is optional. The “/” executes the PL/SQL block and is required. When SQL*Plus reads SQL statement, it knows that the semicolon marks the end of the statement. Therefore, the statement is complete and can be sent to the database. When SQL*Plus reads a PL/SQL block, a semicolon marks the end of the individual statement within the block. In other words, it is not a block terminator.
24
Bordoloi and Bock PL/SQL EXAMPLE Therefore, SQL*Plus needs to know when the block has ended. As you have seen in the example, it can be done with period and forward slash.
25
Bordoloi and Bock EXECUTING PL/SQL PL/SQL can be executed directly in SQL*Plus. A PL/SQL program is normally saved with an.sql extension. To execute an anonymous PL/SQL program, simply type the following command at the SQL prompt: SQL> @DisplayAge
26
Bordoloi and Bock GENERATING OUTPUT Like other programming languages, PL/SQL provides a procedure (i.e. PUT_LINE) to allow the user to display the output on the screen. For a user to able to view a result on the screen, two steps are required. First, before executing any PL/SQL program, type the following command at the SQL prompt (Note: you need to type in this command only once for every SQL*PLUS session): SQL> SET SERVEROUTPUT ON; or put the command at the beginning of the program, right before the declaration section.
27
Bordoloi and Bock GENERATING OUTPUT Second, use DBMS_OUTPUT.PUT_LINE in your executable section to display any message you want to the screen. Syntax for displaying a message: DBMS_OUTPUT.PUT_LINE( ); in which PUT_LINE is the procedure to generate the output on the screen, and DBMS_OUTPUT is the package to which the PUT_LINE belongs. DBMS_OUTPUT_PUT_LINE(‘My age is ‘ || num_age);
28
Bordoloi and Bock SUBSTITUTIONVARIABLES SQL*Plus allows a PL/SQL block to receive input information with the help of substitution variables. Substitution variables cannot be used to output the values because no memory is allocated for them. SQL*Plus will substitute a variable before the PL/SQL block is sent to the database. Substitution variables are usually prefixed by the ampersand(&) character or double ampersand (&&) character.
29
Bordoloi and Bock EXAMPLE DECLARE v_student_id NUMBER := &sv_student_id; v_first_name VARCHAR2(35); v_last_name VARCHAR2(35); BEGIN SELECT first_name, last_name INTO v_first_name, v_last_name FROM student WHERE student_id = v_student_id; DBMS_OUTPUT.PUT_LINE ('Student name: '||v_first_name||' '||v_last_name); EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('There is no such student'); END;
30
Bordoloi and Bock EXAMPLE When this example is executed, the user is asked to provide a value for the student ID. The example shown above uses a single ampersand for the substitution variable. When a single ampersand is used throughout the PL/SQL block, the user is asked to provide a value for each occurrence of the substitution variable.
31
Bordoloi and Bock EXAMPLE BEGIN DBMS_OUTPUT.PUT_LINE('Today is ‘||’&sv_day'); DBMS_OUTPUT.PUT_LINE('Tomorrow will be ‘||’ &sv_day'); END; This example produces the following output: Enter value for sv_day: Monday old 2: DBMS_OUTPUT.PUT_LINE('Today is ‘||’ &sv_day'); new 2: DBMS_OUTPUT.PUT_LINE('Today is ‘||’ Monday'); Enter value for sv_day: Tuesday old 3: DBMS_OUTPUT.PUT_LINE('Tomorrow will be ‘||’ &sv_day'); new 3: DBMS_OUTPUT.PUT_LINE('Tomorrow will be ‘||’ Tuesday'); Today is Monday Tomorrow will be Tuesday PL/SQL procedure successfully completed.
32
Bordoloi and Bock EXAMPLE When a substitution variable is used in the script, the output produced by the program contains the statements that show how the substitution was done. If you do not want to see these lines displayed in the output produced by the script, use the SET command option before you run the script as shown below: SET VERIFY OFF;
33
Bordoloi and Bock EXAMPLE Then, the output changes as shown below: Enter value for sv_day: Monday Enter value for sv_day: Tuesday Today is Monday Tomorrow will be Tuesday PL/SQL procedure successfully completed. The substitution variable sv_day appears twice in this PL/SQL block. As a result, when this example is run, the user is asked twice to provide the value for the same variable.
34
Bordoloi and Bock EXAMPLE BEGIN DBMS_OUTPUT.PUT_LINE('Today is '||'&&sv_day'); DBMS_OUTPUT.PUT_LINE('Tomorrow will be ‘||’ &sv_day'); END; In this example, substitution variable sv_day is prefixed by double ampersand in the first DBMS_OUTPUT.PUT_LINE statement. As a result, this version of the example produces different output.
35
Bordoloi and Bock OUTPUT Enter value for sv_day: Monday old 2: DBMS_OUTPUT.PUT_LINE('Today is ‘||’ &&sv_day'); new 2: DBMS_OUTPUT.PUT_LINE('Today is ‘||’ Monday'); old 3: DBMS_OUTPUT.PUT_LINE('Tomorrow will be ‘||’ &sv_day'); new 3: DBMS_OUTPUT.PUT_LINE('Tomorrow will be ‘||’ Monday'); Today is Monday Tomorrow will be Monday PL/SQL procedure successfully completed. It is clear that the user is asked only once to provide the value for the substitution variable sv_day. As a result, both DBMS_OUTPUT.PUT_LINE statements use the value of Monday entered previously by the user.
36
Bordoloi and Bock Substitution Variables Ampersand(&) character and double ampersand (&&) characters are the default characters that denote substitution variables. There is a special SET command option available in SQL*Plus that allows to change the default character (&) to any other character or disable the substitution variable feature. This SET command has the following syntax: SET DEFINE character or SET DEFINE ON or SET DEFINE OFF
37
Bordoloi and Bock Substitution Variables The first set command option changes the prefix of the substitution variable from an ampersand to another character. This character cannot be alphanumeric or white space. The second (ON option) and third (OFF option) control whether SQL*Plus will look for substitution variables or not. In addition, ON option changes the value of the character back to the ampersand.
38
Overview Overview of PL/SQL Development of a coded block Interacting with an Oracle database Controlling PL/SQL process flow Cursor handling Error handling
39
Re-visiting SQL Instructions to Oracle identifying the information you wish to select, insert, delete or update SQL*Plus is Oracle's simple interface for interaction with Oracle DBMS using SQL. Notes on SQL are on Blackboard
40
PL/SQL - introduction Procedural extension allowing for modularity, variable declaration, loops and logical constructs. Allows for advanced error handling Communicates natively with other oracle database objects. Managed centrally within the Oracle database.
41
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
42
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
43
Centralised V’s De-centralised Begin : End; Begin : End; Begin : End; Begin : End; Common copy of executed code – one copy to maintain Multiple copies of executable code on the decentralised system – multiple copies to maintain leading to increase difficulty in maintaining the system Server
44
Advantages of using PL/SQL to access Oracle PL/SQL is managed centrally within the database Code is managed by the DBA and execution privileges are managed in the same way as with other objects PL/SQL objects are first-class Oracle DB objects Easy to read With modularity features and error handling
45
Centralised control Enables DBA to: Specify rules in one place (as procedure, function, package in PL/SQL) Force user access through the predefined PL/SQL so users cannot write their own procedural code and use this instead. Define for instance security privileges giving users access to table(s) only through a particular procedure
46
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
47
Modules in PL/SQL There are 4 types of modules in PL/SQL Procedures – series of statements may or may not return a value Functions – series of statements must return a single value Triggers – series of PL/SQL statements (actions) executing after an event has triggered a condition (ECA) Packages – collection of procedures and function that has 2 parts: a listing and a body.
48
Procedures Creation command Variable declarations Body of procedure 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;
49
Use of Data-Types 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)
50
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 rowids in the database
51
Non-database Data Types DEC, DECIMAL, REAL, INTEGER, INT – these are numerical data types that are a subset of number. Binary_integer – binary format for number type but can not be stored in database unless converted first. Character – same as char Boolean – true/false value Table/record – tables can be used to store the equivalent of an array while records store the variables with composite data types.
52
Using SQL in procedures Select values into PL/SQL variables using INTO Record.element notation will address components of tuples (dot notation) %rowtype allows full rows to be selected into one variable Empid empnameaddr1addr2addr3 postcodegradesalary V_employeeemployee%rowtype
53
Example (Anonymous Block of Code) Declare v_employee employee%rowtype; Begin select * into v_employee from employee where empid = 65284; update employee set salary = v_employee.salary + 1000 where empid = v_employee.empid; End; Selects entire row of data into 1 variable called v_employee Is updating the value of salary based on selected element of a variable
54
Cursor overview Very powerful in PL/SQL modules Allows more than one set of data to be retrieved and accessed at the same time in loops Sets are created by executing SQL statements embedded in the PL/SQL code Cursor attributes - %notfound, %rowcount, %found & %isopen
55
Error handling Prevents database locking Ensures that errors are presented to the user in a sensible format Makes code robust Essential when using PL/SQL as formal programming language or interfacing with Oracle applications.
56
PL/SQL Blocks PL/SQL code is built of Blocks, with a unique structure. There are two types of blocks in PL/SQL: 1. Anonymous Blocks: have no name (like scripts) can be written and executed immediately in SQLPLUS can be used in a trigger 2. Named Blocks: Procedures Functions
57
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) / Always put a new line with only a / at the end of a block! (This tells Oracle to run the block) A correct completion of a block will generate the following message: PL/SQL procedure successfully completed
59
DECLARE Syntax Examples identifier [CONSTANT] datatype [NOT NULL] [:= | DEFAULT expr]; identifier [CONSTANT] datatype [NOT NULL] [:= | DEFAULT expr]; Declare birthdayDATE; age NUMBER(2) NOT NULL := 27; name VARCHAR2(13) := 'Levi'; magicCONSTANT NUMBER := 77; validBOOLEAN NOT NULL := TRUE; Declare birthdayDATE; age NUMBER(2) NOT NULL := 27; name VARCHAR2(13) := 'Levi'; magicCONSTANT NUMBER := 77; validBOOLEAN NOT NULL := TRUE; Notice that PL/SQL includes all SQL types, and more…
60
Declaring Variables with the %TYPE Attribute Examples DECLARE snameSailors.sname%TYPE; fav_boatVARCHAR2(30); my_fav_boatfav_boat%TYPE := 'Pinta';... Accessing column sname in table Sailors Accessing another variable
61
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? reserves_record Reserves%ROWTYPE; reserves_record.sid:=9; Reserves_record.bid:=877; Accessing table Reserves
62
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), ageNUMBER(3), rating NUMBER(3)); sailor_recordsailor_record_type;... BEGIN Sailor _ record.sname:= ‘ peter ’ ; Sailor _ record.age:=45; … DECLARE TYPE sailor_record_type IS RECORD (sname VARCHAR2(10), sid VARCHAR2(9), ageNUMBER(3), rating NUMBER(3)); sailor_recordsailor_record_type;... BEGIN Sailor _ record.sname:= ‘ peter ’ ; Sailor _ record.age:=45; …
63
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
64
Example DECLARE Pi constant NUMBER(8,7) := 3.1415926; area NUMBER(14,2); cursor rad_cursor is select * from RAD_VALS; rad_value rad_cursor%ROWTYPE; BEGIN open rad_cursor; fetch rad_cursor into rad_val; area:=pi*power(rad_val.radius,2); insert into AREAS values (rad_val.radius, area); close rad_cursor; END; / DECLARE Pi constant NUMBER(8,7) := 3.1415926; area NUMBER(14,2); cursor rad_cursor is select * from RAD_VALS; rad_value rad_cursor%ROWTYPE; BEGIN open rad_cursor; fetch rad_cursor into rad_val; area:=pi*power(rad_val.radius,2); insert into AREAS values (rad_val.radius, area); close rad_cursor; END; / radius 3 6 8 Rad_curs or fetchfetch Rad_val Radiu s Area AREAS 328.27 RAD_VA LS
65
DECLARE … cursor rad_cursor is select * from RAD_VALS; rad_value rad_cursor%ROWTYPE; BEGIN open rad_cursor; fetch rad_cursor into rad_val; area:=pi*power(rad_val.radius,2); insert into AREAS values (rad_val.radius, area); … DECLARE … cursor rad_cursor is select * from RAD_VALS; rad_value rad_cursor%ROWTYPE; BEGIN open rad_cursor; fetch rad_cursor into rad_val; area:=pi*power(rad_val.radius,2); insert into AREAS values (rad_val.radius, area); … DECLARE … cursor rad_cursor is select * from RAD_VALS; rad_value RAD_VALS%ROWTYPE; BEGIN open rad_cursor; fetch rad_cursor into rad_val; area:=pi*power(rad_val.radius,2); insert into AREAS values (rad_val.radius, area); … DECLARE … cursor rad_cursor is select * from RAD_VALS; rad_value RAD_VALS%ROWTYPE; BEGIN open rad_cursor; fetch rad_cursor into rad_val; area:=pi*power(rad_val.radius,2); insert into AREAS values (rad_val.radius, area); … DECLARE … cursor rad_cursor is select radius from RAD_VALS; rad_value RAD_VALS.radius%TYPE; BEGIN open rad_cursor; fetch rad_cursor into rad_val; area:=pi*power(rad_val,2); insert into AREAS values (rad_val, area); … DECLARE … cursor rad_cursor is select radius from RAD_VALS; rad_value RAD_VALS.radius%TYPE; BEGIN open rad_cursor; fetch rad_cursor into rad_val; area:=pi*power(rad_val,2); insert into AREAS values (rad_val, area); … DECLARE … cursor rad_cursor is select * from RAD_VALS; rad_value RAD_VALS.radius%TYPE; BEGIN open rad_cursor; fetch rad_cursor into rad_val; area:=pi*power(rad_val,2); insert into AREAS values (rad_val, area); … DECLARE … cursor rad_cursor is select * from RAD_VALS; rad_value RAD_VALS.radius%TYPE; BEGIN open rad_cursor; fetch rad_cursor into rad_val; area:=pi*power(rad_val,2); insert into AREAS values (rad_val, area); …
66
Explicit Cursor Attributes Obtain status information about a cursor. Attribute Type Description %ISOPEN Boolean Evaluates to TRUE if the cursor is open. %NOTFOUND Boolean Evaluates to TRUE if the most recent fetch does not return a row. %FOUND Boolean Evaluates to TRUE if the most recent fetch returns a row; complement of %NOTFOUND %ROWCOUNT Number Evaluates to the total number of rows returned so far.
67
SELECT Statements INTO clause is required. Query must return exactly one row. Otherwise, a NO_DATA_FOUND or TOO_MANY_ROWS exception is thrown DECLARE v_sname VARCHAR2(10); v_rating NUMBER(3); BEGIN SELECTsname, rating INTOv_sname, v_rating FROMSailors WHEREsid = '112'; END; /
68
Conditional logic If then elsif then else end if; If then if then end if; else end if; Condition:Nested conditions:
69
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;...
70
Suppose we have the following table: 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 create table mylog( who varchar2(30), logon_num number ); logon_num who 3Peter 4John 2Moshe mylog
71
Solution DECLARE cnt NUMBER; BEGIN select count(*) into cnt from mylog where who = user; 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; /
72
SQL%ROWCOUNTNumber of rows affected by the most recent SQL statement (an integervalue). SQL%FOUNDBoolean attribute that evaluates to TRUE if the most recent SQL statement affects oneor more rows. SQL%NOTFOUNDBoolean attribute that evaluates to TRUE if the most recent SQL statement does not affect any rows. SQL%ISOPENAlways evaluates to FALSE because PL/SQL closes implicit cursors immediately after they are executed. SQL Cursor SQL cursor is automatically created after each SQL query. It has 4 useful attributes:
73
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; /
74
Loops: Simple Loop 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; create table number_table( num NUMBER(10) );
75
Loops: Simple Cursor Loop 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 doubles values(cVal.num*2); END LOOP; END; create table number_table( num NUMBER(10) );
76
Loops: FOR Loop DECLARE inumber_table.num%TYPE; BEGIN FOR i IN 1..10 LOOP INSERT INTO number_table VALUES(i); END LOOP; END; Notice that i is incremented automatically
77
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; / Notice that a lot is being done implicitly: declaration of num_row, open cursor, fetch cursor, the exit condition
78
Loops: WHILE Loop DECLARE TEN number:=10; inumber_table.num%TYPE:=1; BEGIN WHILE i <= TEN LOOP INSERT INTO number_table VALUES(i); i := i + 1; END LOOP; END;
79
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 1000000 Then print using dbms_output. put_line(your_string); dbms_output.put(your_string);
80
Input and output example set serveroutput on format wrap size 1000000 ACCEPT high PROMPT 'Enter a number: ' DECLARE inumber_table.num%TYPE:=1; BEGIN dbms_output.put_line('Look Ma, I can print from PL/SQL!!!'); WHILE i <= &high LOOP INSERT INTO number_table VALUES(i); i := i + 1; END LOOP; END;
81
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) /
82
Trapping Exceptions Here we define the actions that should happen when an exception is thrown. Example Exceptions: NO_DATA_FOUND TOO_MANY_ROWS ZERO_DIVIDE When handling an exception, consider performing a rollback
83
DECLARE num_row number_table%ROWTYPE; BEGIN select * into num_row from number_table; dbms_output.put_line(1/num_row.num); EXCEPTION WHEN NO_DATA_FOUND THEN dbms_output.put_line('No data!'); WHEN TOO_MANY_ROWS THEN dbms_output.put_line('Too many!'); WHEN OTHERS THEN dbms_output.put_line( ‘ Error ’ ); end;
84
User-Defined Exception DECLARE e_number1 EXCEPTION; cnt NUMBER; BEGIN select count(*) into cnt from number_table; IF cnt = 1 THEN RAISE e_number1; ELSE dbms_output.put_line(cnt); END IF; EXCEPTION WHEN e_number1 THEN dbms_output.put_line('Count = 1'); end;
85
Functions and Procedures Up until now, our code was in an anonymous block It was run immediately 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).
86
CREATE [OR REPLACE] PROCEDURE procedure_name [(parameter1 [mode1] datatype1, parameter2 [mode2] datatype2,...)] IS|AS PL/SQL Block; CREATE [OR REPLACE] PROCEDURE procedure_name [(parameter1 [mode1] datatype1, parameter2 [mode2] datatype2,...)] IS|AS PL/SQL Block; Creating Procedures 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
87
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; / 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; / Example- what does this do? logon_ num who 3Pete 4John 2Joe Table mylog
88
declare howmany mylog.logon_num%TYPE; begin num_logged( ‘ John',howmany); dbms_output.put_line(howmany); end; / declare howmany mylog.logon_num%TYPE; begin num_logged( ‘ John',howmany); dbms_output.put_line(howmany); end; / Calling the Procedure
89
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
90
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; CREATE [OR REPLACE] FUNCTION function_name [(parameter1 [mode1] datatype1, parameter2 [mode2] datatype2,...)] RETURN datatype IS|AS PL/SQL Block;
91
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; / 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; / A Function NOTE THAT YOU DON'T SPECIFY THE SIZE
92
declare paulRate:=9; Begin dbms_output.put_line(ratingMessage(paulRate)); end; / declare paulRate:=9; Begin dbms_output.put_line(ratingMessage(paulRate)); end; / Calling the function
93
create or replace function squareFunc(num in number) return number is BEGIN return num*num; End; / BEGIN dbms_output.put_line(squareFunc(3.5)); END; / Creating a function: Using the function:
94
Packages Functions, Procedures, Variables can be put together in a package 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 Won't discuss packages in this course
95
Triggers Triggers are special procedures which we want activated when someone has performed some action on the DB. For example, we might define a trigger that is executed when someone attempts to insert a row into a table, and the trigger checks that the inserted data is valid. To be continued…
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.