Instructions For PL SQL CS4513 F17
User Manual:
Open the PDF directly: View PDF .
Page Count: 43
Download | |
Open PDF In Browser | View PDF |
CS 4513 – Fall 2017 Instructions for PL/SQL - Anonymous Blocks Declaration Statements, Data types and Variables Executable Statements (Some operators, Conditional Logic, Looping) More operators Cursors Procedures Functions Packages Exceptions How to edit and execute PL/SQL programs in Oracle SQL Developer A Complete Example How to call a PL/SQL procedure in a Java program Reference 1. Anonymous Blocks You have to put your PL/SQL code in blocks. The simplest type of blocks is Anonymous Blocks. /*General Structure of an Anonymous Block*/ [DECLARE declaration statements] BEGIN executable statement(s) [EXCEPTION exception handlers] END; Legend: The square brackets [] mark off sections that are optional, i.e. declare and exception sections are optional. UPPERCASE words are keywords. Let’s start with a simple example – an anonymous block that prints out ‘hello, world!’ on the screen. To enable printing on screen you have to type the following command in the worksheet of Oracle SQL Developer 3.2: Page 1 of 43 SET SERVEROUTPUT ON; /*only once per session, that is until you disconnect from the connection*/ And here is the PL/SQL code: BEGIN DBMS_OUTPUT.PUT_LINE('Hello, world!'); END; 2. Declaration Statements In PL/SQL before you can work with any kind of variable, you must first declare it; that is you must give it a name and specify its data type. The most common data types in PL/SQL are String, Number, Data and Boolean. Here are some examples of declaration statements for every kind of data type. Note that each declaration ends with semicolon. 2.1 String Declaration: variable_name VARCHAR2(n); where n is the maximum length of the string content (up to 32767) Example: small_string VARCHAR2(4); 2.2 Number Declaration: variable_name NUMBER[(precision [,scale] ) ]; where precision and scale are integers Example: bean_counter NUMBER(10, 3); /*can hold values with up to 10 digits of precision, 3 of which are to the right of the decimal point*/ Page 2 of 43 2.3 Date Declaration: variable_name DATE; Example: birth_date DATE; 2.4 Boolean Declaration: variable_name BOOLEAN; Example: too_young_to_vote BOOLEAN; Note that in PL/SQL a BOOLEAN variable can be TRUE, FALSE or NULL. 3. Executable Statements An executable statement can be any SQL statement (except data definition statements such as CREATE TABLE), a procedure/function call (see sections 6 and 7), or any of the statements below, ending with semicolon. 3.1 Assignment statement – to assign a value to an already declared variable. The assignment operator to do this is := (a colon followed by an equal sign). For DATE the format is ‘DD-MON-YYYY’. For example: 22-APR-2012. Example: let’s expand the example from section 1 – declare string and date variables, assign values to them and print their content on the screen. DECLARE myMessage VARCHAR2(20); /*declaration*/ myDate DATE; /*declaration*/ BEGIN myMessage := 'hello, world!'; /*assignment*/ myDate := '20-SEP-2012'; /*assignment*/ DBMS_OUTPUT.PUT_LINE(myMessage); DBMS_OUTPUT.PUT_LINE(myDate); END; Page 3 of 43 3.2 Output statement – to print on the screen. PL/SQL has limited ability to print out. To do this you have to put what you want to print in the DBMS_OUTPUT buffer. You have already seen the command for this: DBMS_OUTPUT.PUT_LINE(X); where x can be the name of a variable (as in the example in section 3.1) or a literal value (as in the example in section 1). Note that all the lines put in the buffer are printed on the screen after the program completes its execution. 3.3 Input statement – to read from keyboard The operator to do this is & (ampersand) followed by the name of the variable you want to read a value for. To automatically cast the input from keyboard to string or date you enclose the whole thing in ‘ ’ (single quotes). In this way the user of your program does not need to enter them enclosed in single quotes. Numbers and Booleans do not require casting. Note that the & operator is not part of PL/SQL, it is Oracle SQL Developer operator. In the Oracle SQL Developer environment, Oracle SQL Developer substitution variables allow portions of command syntax to be stored and edited into the command before it is run. Substitution variables are variables that you can use to pass runtime values, number or character, into a PL/SQL block. You can reference them within a PL/SQL with a preceding ampersand in the same manner as you reference Oracle SQL Developer substitution variables in a SQL statement. The text values are substituted into the PL/SQL block before PL/SQL block is executed. Therefore you cannot substitute different values for the substitution variables by using a loop. Only one value will replace the substitution variable. Example: Read a string, a number, a date, and a boolean from keyboard and print them on the screen. /*Example of input statements*/ DECLARE myMessage VARCHAR2(20); /*declaration*/ myNumber NUMBER; /*declaration*/ myDate DATE; /*declaration*/ printOut BOOLEAN; /*declaration*/ BEGIN myMessage := '&myMessage'; /*reading from keyboard and assignment*/ myNumber := &myNumber; /*reading from keyboard and assignment*/ myDate := '&myDate'; /*reading from keyboard and assignment*/ printOut := &youSure; /*reading from keyboard and assignment*/ Page 4 of 43 DBMS_OUTPUT.PUT_LINE(myMessage); DBMS_OUTPUT.PUT_LINE(myNumber); DBMS_OUTPUT.PUT_LINE(myDate); END; 3.4 IF statement (Conditional Logic) The general format of the IF statement is as follows. /*General format of IF statement*/ IF condition 1 THEN executable statements [ELSIF condition 2 THEN executable statements] [ELSIF condition n THEN executable statements] [ELSE THEN executable last statements] END IF; Note that the keyword is ELSIF, not ELSEIF. Example: let’s modify the example in section 3.3 so that it prints the contents of myMessage, myNumber and myDate only if the Boolean printOut is TRUE, else print a message ‘No print on screen’. /*Example of IF statement*/ DECLARE myMessage VARCHAR2(20); /*declaration*/ myNumber NUMBER; /*declaration*/ myDate DATE; /*declaration*/ printOut BOOLEAN; /*declaration*/ BEGIN myMessage := '&myMessage'; /*reading from keyboard and assignment*/ myNumber := &myNumber; /*reading from keyboard and assignment*/ myDate := '&myDate'; /*reading from keyboard and assignment*/ printOut := &youSure; /*reading from keyboard and assignment*/ IF printOut Page 5 of 43 THEN DBMS_OUTPUT.PUT_LINE(myMessage); DBMS_OUTPUT.PUT_LINE(myNumber); DBMS_OUTPUT.PUT_LINE(myDate); ELSE DBMS_OUTPUT.PUT_LINE('No print on screen'); END IF; END; Also, there are CASE statements for conditional logic (check the references). 3.5 Looping 3.5.1 FOR Loop – you know how many times you want to execute the statements inside the loop. The general format of the FOR loop is as follows. /*General format of FOR loop*/ FOR loop_counter IN [REVERSE] lower_bound .. upper_bound LOOP statements END LOOP; Example: Print out the value stored in the counter variable. /*Example of FOR loop*/ DECLARE counter NUMBER; BEGIN FOR counter IN 1 .. 6 LOOP DBMS_OUTPUT.PUT_LINE(counter); END LOOP; END; The counter will get values 1, 2, 3, 4, 5, 6 and they will be printed on the screen. If you want to assign values to the counter in reverse order, use the REVERSE option. Example: the same loop, but the counter will get values in reverse order. /*Example of FOR loop in reverse order*/ DECLARE counter NUMBER; BEGIN FOR counter IN REVERSE 1 .. 6 Page 6 of 43 LOOP DBMS_OUTPUT.PUT_LINE(counter); END LOOP; END; The counter will get values 6, 5, 4, 3, 2, 1. 3.5.2 Simple (Infinite) Loop – you don’t know the exact number of repetitions, but it will execute at least once. To get out of the loop, you specify a condition, when it becomes true, the program gets out of the loop. The general format of the simple loop is as follows. /*General format of simple loop*/ LOOP statements EXIT WHEN condition END LOOP; Example: same as the example in section 3.5.1, but will stop when counter becomes equal to 4. /*Example of simple loop*/ DECLARE counter NUMBER; BEGIN counter := 1; LOOP DBMS_OUTPUT.PUT_LINE(counter); counter := counter + 1; EXIT WHEN counter >= 4; END LOOP; END; There is also a WHILE loop (check the references). Page 7 of 43 4. More operators Here are some more PL/SQL operators. Notation Meaning +,-,/,*,** Addition, subtraction, division, multiplication, exponentiation AND, OR, NOT Boolean operators = Equality (of non-nulls) != Inequality <,>,<=,>= Less than, greater than, less than or equal, greater than or equal IN Equality disjunction BETWEEN Range test IS NULL Nullity test IS NOT NULL Non-nullity test LIKE Wildcard matching (for strings) || Concatenation (for strings) -A line starting with – is a comment line /*block*/ A block insider /* and */ is treated as comment – multiline comment 5. Cursors A cursor is a named space in memory where the program can get selected data out of the database. For every cursor you should associate a corresponding SELECT statement. To retrieve data you OPEN the cursor, FETCH from it and CLOSE it. Example: Suppose we have a table “students” in which we have stored student_id and student_gpa. Now we want to count how many students who have gpa greater than or equal to 3.0. Here is the PL/SQL code: /*Example of using the cursor*/ DECLARE number_of_students NUMBER; /*the following four rows is the declaration of the cursor*/ CURSOR ns_cur IS SELECT COUNT(*) FROM students WHERE student_gpa >= 3.0; BEGIN number_of_students := 0; OPEN ns_cur; --open the cursor FETCH ns_cur INTO number_of_students; --fetch from it Page 8 of 43 CLOSE ns_cur; --close the cursor --print out the number of students with gpa >=3.0 DBMS_OUTPUT.PUT_LINE(number_of_students); END; 6. Procedures A procedure is a named program that executes some predefined statements and then returns control to whatever calls it. After defining a procedure you can invoke it by calling its name and providing any needed parameters. There are 2 different types of procedures. The first type is a “run time” procedure, that is, they exist only when you execute a program that contains them – much like methods in other languages as C++, Java, etc. The general structure of a “run time” procedure is as follows. /*General Structure of a Run Time Procedure*/ PROCEDURE procedure_name (parameter1 MODE DATATYPE [DEFAULT expression], parameter2 MODE DATATYPE [DEFAULT expression], …) AS [variable1 DATATYPE; Variable2 DATATYPE; …] BEGIN statements; [EXCEPTION WHEN exception_name THEN exception handlers] END; MODE: can be IN, OUT or IN OUT. - IN means calling program supplies the values of the parameters and you cannot change it inside the procedure. OUT means the procedure sets the value of the parameter and the calling program can read it. IN OUT – the calling program supplies a value, the procedure can read it and change it, and the calling program can read the updated value. Page 9 of 43 [DEFAULT expression] – you can initialize the parameters to some default value. This is optional. You should define a run time procedure in the declaration section. Example: A procedure that inserts a tupleinto the table “students” which has attributes student_id and student_gpa. PROCEDURE insertStudent (id IN VARCHAR2, gpa IN NUMBER) AS BEGIN --the next two lines are pure SQL DML statements INSERT INTO students(student_id, student_gpa) VALUES(id, gpa); END; The call to this procedure can be done in the anonymous block that contains this procedure, or from another procedure or function in the same anonymous block. For example, consider the following anonymous block. /*Example of calling a run time procedure*/ DECLARE … id VARCHAR2(20); gpa NUMBER; … PROCEDURE insertStudent (id IN VARCHAR2, pga IN NUMBER) AS BEGIN --the next two lines are pure SQL DML statements INSERT INTO student(student_id, student_gpa) VALUES(id, gpa); END; BEGIN … id := ‘111-111-1111’; gpa := 3.5; … /*call the run time procedure insertStudent*/ insertStudent(id,gpa); … END; Page 10 of 43 The second type is a “stored” procedure. When you define a stored procedure, it is stored in the database and you can invoke it from different anonymous blocks, procedures and functions, and from various environments that can access the database. This feature in PL/SQL is very attractive as it allows for sharing of PL/SQL code by different applications running at different places. The general structure of a stored procedure is as follows. /*General Structure of a Stored Procedure*/ CREATE [OR REPLACE] PROCEDURE procedure_name (parameter1 MODE DATATYPE [DEFAULT expression], parameter2 MODE DATATYPE [DEFAULT expression], …) AS [variable1 DATATYPE; Variable2 DATATYPE; …] BEGIN statements; [EXCEPTION WHEN exception_name THEN Exception handlers] END; The code is almost the same as the run time procedure, except the CREATE [OR REPLACE] keywords. MODE: same as in run time procedures. Example: A stored procedure that inserts a tuple into the table “students” which has attributes student_id and student_gpa. CREATE OR REPLACE PROCEDURE insertStudent (id IN VARCHAR2, gpa IN NUMBER) AS BEGIN --the next two lines are pure SQL DML statements INSERT INTO students(student_id, student_gpa) VALUES(id, gpa); END; Page 11 of 43 The call to a stored procedure can be done from any anonymous block, another procedure or a function, or directly from the Oracle SQL Developer Worksheet. In case of an anonymous block, here is an example. /*Example of calling a stored procedure*/ DECLARE … id VARCHAR2(20); gpa NUMBER; … /*note that here we did not declare the procedure It already exists*/ BEGIN … id := ‘111-111-1111’; gpa := 3.5; … /*call the run time procedure insertStudent*/ insertStudent(id,gpa); … END; 7. Functions A function is similar to a procedure, except that it returns one single value to the program that calls it. The data returned by a function is always of a specific, predefined data type. There are also “run time” and “stored” functions. Run time functions are defined as follows. /*General Structure of a Run Time Function*/ FUNCTION function_name (parameter1 MODE DATATYPE [DEFAULT expression], parameter2 MODE DATATYPE [DEFAULT expression], …) RETURN DATATYPE AS [variable1 DATATYPE; Variable2 DATATYPE; …] BEGIN statements; Page 12 of 43 RETURN expression [EXCEPTION WHEN exception_name THEN exception handlers] END; Example: A run time function that returns the number of students with GPA greater than some value from the table “students”. /*Example of a run time function*/ FUNCTION getNumStudents (gpa IN NUMBER) /*note that we declare the type of data to be returned*/ RETURN NUMBER AS number_of_students NUMBER; /*the following four rows is the declaration of the cursor*/ CURSOR ns_cur IS SELECT COUNT(*) FROM students WHERE student_gpa >= gpa; BEGIN number_of_students := 0; OPEN ns_cur; --open the cursor FETCH ns_cur INTO number_of_students; --fetch from it CLOSE ns_cur; --close the cursor RETURN number_of_students; END; Same as the run time procedures, a run time function should be defined in the declaration section. The call to this function should be done in the anonymous block that contains the function, or from another function or procedure in the same anonymous block. For example, consider the following anonymous block: Page 13 of 43 /*Example of calling a run time function*/ DECLARE … countStudents NUMBER; … FUNCTION getNumStudents (gpa IN NUMBER) /*note that we declare the type of data to be returned*/ RETURN NUMBER AS number_of_students NUMBER; /*the following four rows is the declaration of the cursor*/ CURSOR ns_cur IS SELECT COUNT(*) FROM students WHERE student_gpa >= gpa; BEGIN number_of_students := 0; OPEN ns_cur; --open the cursor FETCH ns_cur INTO number_of_students; --fetch from it CLOSE ns_cur; --close the cursor RETURN number_of_students; END; BEGIN … countStudents := getNumStudents(3.5); … END; On the other hand, stored functions are defined as follows. /*General Structure of a Stored Function*/ CREATE [OR REPLACE] FUNCTION function_name (parameter1 MODE DATATYPE [DEFAULT expression], parameter2 MODE DATATYPE [DEFAULT expression], …) RETURN DATATYPE AS [variable1 DATATYPE; Variable2 DATATYPE; …] Page 14 of 43 BEGIN statements; RETURN expression [EXCEPTION WHEN exception_name THEN exception handlers] END; Example: A stored function that returns the number of students with GPA greater than some value from table “students”. /*Example of a stored function*/ CREATE [OR REPLACE] FUNCTION getNumStudents (gpa IN NUMBER) /*note that we declare the type of data to be returned*/ RETURN NUMBER AS number_of_students NUMBER; /*the following four rows is the declaration of the cursor*/ CURSOR ns_cur IS SELECT COUNT(*) FROM students WHERE student_gpa >= gpa; BEGIN number_of_students := 0; OPEN ns_cur; --open the cursor FETCH ns_cur INTO number_of_students; --fetch from it CLOSE ns_cur; --close the cursor RETURN number_of_students; END; The call to a stored function can be done from any anonymous block, another function or a procedure, or directly from the Oracle SQL Developer Worksheet. For example, consider the following anonymous block: /*Example of calling a stored function*/ DECLARE … Page 15 of 43 countStudents NUMBER; … /*note that here we did not declare the function, it already exists*/ BEGIN … /*call the stored function*/ countStudents := getNumStudents(3.5); … END; 8. Packages You can use packages to organize your code. When you have several related stored procedures and/or functions you should combine them in a package. The package is stored in the database, as well as the procedures and functions it contains, and can be shared. Every package consists of: 8.1 Package specification – describes what can be done using this package (lists the headers of all procedures/functions). A template looks like: CREATE OR REPLACE PACKAGE package_name AS Program1 header; Program2 header; … END package_name; 8.2 Package body – describes how to do it (implementing procedures/functions). CREATE OR REPLACE PACKAGE BODY package_name AS Private_programs /*optional, you cannot invoke these programs from outside*/ Program1 body; Program2 body; … END package_name; An example of package using the examples in sections 6 and 7: Page 16 of 43 /*An example of package*/ --package specification-CREATE OR REPLACE PACKAGE student_pack AS PROCEDURE insertStudent(id IN VARCHAR2, gpa IN NUMBER); FUNCTION getNumStudents(gpa IN NUMBER); END student_pack; --package body— CREATE OR REPLACE PACKAGE BODY student_pack AS /*the procedure*/ CREATE OR REPLACE PROCEDURE insertStudent (id IN VARCHAR2, gpa IN NUMBER) AS BEGIN --the next two lines are pure SQL DML statements INSERT INTO students(student_id, student_gpa) VALUES(id, gpa); END insertStudent; /*the function*/ CREATE OR REPLACE FUNCTION getNumStudents (gpa IN NUMBER) /*note that we declare the type of data to be returned*/ RETURN NUMBER AS number_of_students NUMBER; CURSOR ns_cur IS SELECT COUNT(*) FROM students WHERE student_gpa >= gpa; BEGIN number_of_students := 0; OPEN ns_cur; --open the cursor FETCH ns_cur INTO number_of_students; --fetch from it CLOSE ns_cur; --close the cursor RETURN number_of_students; END getNumStudents; END student_pack; Now, if you want to call the procedure or the function, you use the syntax: Page 17 of 43 package_name.function_name/procedure_name(parameters) For example, to call them from an anonymous block (also you can do this from another function or procedure or from the Oracle SQL Developer Worksheet): /*Example of calling a packet*/ DECLARE … numStudents NUMBER; … BEGIN … student_pack.insertStudent(‘111-234’,3.5); numStudents := student_pack.getNumStudents(3.6); … END; You will see another example of this (as well as calling a procedure/function directly from Oracle SQL Worksheet) in section 11. 9. Exceptions PL/SQL implements run-time error handling via exceptions and exception handlers. When an error occurs during the execution of a PL/SQL program, an exception is raised. Immediately, program control is transferred to the exception section of the block in which the exception was raised. For more information about exceptions and exception handling refer to the materials listed in Reference. 10. How to edit and execute PL/SQL programs in Oracle SQL Developer? Please refer to the following example and the materials listed in the Reference. An example: In the following example, we first create a table “student” with two attributes “student_id” and “name” via SQL, then we insert two rows into the table and print out the rows. Page 18 of 43 Step 1. Create the table “student” using SQL statements. /*SQL code to create table student*/ create table student ( student_ID NUMBER, Name VARCHAR(30), PRIMARY KEY (student_ID)); Step 2. Create a PL/SQL procedure to insert two rows into table student and print all the student records. 2.1 Click File -> New -> Database Tier -> Database Objects -> Procedure -> OK. 2.2 Select a connection if prompted. Enter you login name and password if you didn’t save. 2.3 Give a name for the procedure. Page 19 of 43 2.4 Once you clicked the “OK” button, a procedure under that name with a null body will be displayed. Page 20 of 43 Step 3. Fill the procedure body with the procedure code. Here is an example to insert two rows into the table “student” and print out all the student records. /*Sample procedure Insert two rows in the table student Print out the table */ create or replace PROCEDURE SAMPLE AS /* the next are DECLARE section */ student_id_1 NUMBER; student_id_2 NUMBER; student_name_1 VARCHAR2(30); student_name_2 VARCHAR2(30); /* nested procedure to insert into the table */ PROCEDURE insert_Student (student_id in NUMBER, student_name in VARCHAR2) AS BEGIN /*the next two lines are pure SQL statements*/ INSERT INTO STUDENT(student_id, name) VALUES (student_id, student_name); END; /* begin of procedure SAMPLE */ BEGIN /*assign values to the variables declared above*/ student_id_1 := 100; student_name_1 := 'Alice'; student_id_2 := 200; student_name_2 := 'Bob'; /*call the predefined procedure to insert*/ insert_Student(student_id_1, student_name_1); insert_Student(student_id_2, student_name_2); /*Print out the table*/ DBMS_OUTPUT.PUT_LINE('Student_id' || ' ' || 'Student.name'); FOR someone IN (select * from student) LOOP DBMS_OUTPUT.PUT_LINE(someone.student_id || ' || someone.name); END LOOP; END SAMPLE; Page 21 of 43 ' Step 4. Compile and debug the procedure by clicking the star button pointed to by the arrow in the figure below. Step 5. Run the procedure by clicking the triangle button pointed to by the arrow below. Page 22 of 43 Page 23 of 43 11. A Complete Example Write a set of SQL and PL/SQL programs that will help a library to store the information about books and book copies. A book has an isbn code (primary key) and title, and a book copy has a barcode id (primary key). E-R diagram Book Book_copies has isbn title barcode_id 1 m isbn Step 1. Create tables. Create a file “createTables.sql” with the following code: /*SQL code to create table books and book_copies*/ CREATE TABLE books( isbn VARCHAR2(13) NOT NULL PRIMARY KEY, title VARCHAR2(200) ); CREATE TABLE book_copies( Barcode_id VARCHAR2(100) NOT NULL PRIMARY KEY, isbn VARCHAR2(13), FOREIGN KEY (isbn) REFERENCES books (isbn) ); Now assume that we want to write a set of PL/SQL programs to do the following tasks: - Add book and book copy if barcode_id is provided Add a book copy given an isbn of a book and the barcode_id of the copy List all books Remove a book and all of its copies given the isbn of the book Display the title of a book given its isbn The best way to organize the code is to use packages. Page 24 of 43 Step 2 Create a package “book”. Step 2.1 Click File -> New -> Database Tier -> Database Objects -> Package -> OK. Step 2.2 Select a connection and enter your login name and password if necessary. Step 2.3 Give a name for the package and click “OK”. Page 25 of 43 Step 2.4 Once you clicked the “OK” button, a package specification under that name with a null body will be displayed. Page 26 of 43 Step 3. Fill the package specification with the code. /*Package specification*/ CREATE OR REPLACE PACKAGE book AS /*procedure to add book and copy if barcode_id_in is provided*/ PROCEDURE add(isbn_in IN VARCHAR2, title_in IN VARCHAR2, barcode_id_in IN VARCHAR2 DEFAULT NULL); /*procedure to add a copy*/ PROCEDURE add_copy(isbn_in IN VARCHAR2, barcode_id_in IN VARCHAR2); /*procedure to list all the books*/ PROCEDURE list_books; /*procedure to remove a book and all of its copies*/ PROCEDURE weed(isbn_in IN VARCHAR2); /*procedure to display the title of a book given its isbn*/ PROCEDURE getTitle(isbn_in IN VARCHAR2); END book; Step 4. Click the “save” button pointed to by the arrow in the figure below to save the specification. Step 5. Create the body of the package. In the navigator, find the package “book”, right click it and select “Create Body”. Page 27 of 43 After that, a null body for the package will be displayed. Step 6. Fill the package body with the code. Page 28 of 43 /*Package body*/ CREATE OR REPLACE PACKAGE BODY BOOK AS /*private procedure to be used in this package body only*/ PROCEDURE assert_notnull(tested_variable IN VARCHAR2) IS BEGIN IF tested_variable IS NULL THEN RAISE VALUE_ERROR; END IF; END assert_notnull; /*procedure to add book and copy if barcode_id_in is provided*/ PROCEDURE add(isbn_in IN VARCHAR2, title_in IN VARCHAR2, barcode_id_in IN VARCHAR2 DEFAULT NULL) AS BEGIN /* TODO implementation required */ assert_notnull(isbn_in); INSERT INTO books(isbn, title) VALUES(isbn_in,title_in); IF barcode_id_in IS NOT NULL THEN add_copy(isbn_in,barcode_id_in); END IF; END add; /*procedure to add a copy*/ PROCEDURE add_copy(isbn_in IN VARCHAR2, barcode_id_in IN VARCHAR2) AS BEGIN assert_notnull(isbn_in); assert_notnull(barcode_id_in); INSERT INTO book_copies(isbn,barcode_id) VALUES(isbn_in, barcode_id_in); END add_copy; /*procedure to list all books*/ PROCEDURE list_books Page 29 of 43 AS isbn_out VARCHAR2(50); title_out VARCHAR2(50); CURSOR lb_cur is SELECT isbn, titl FROM books; BEGIN /*open the cursor*/ OPEN lb_cur; /*start the loop*/ LOOP FETCH lb_cur INTO isbn_out, title_out; /*exit the loop when there is no more rows*/ EXIT WHEN lb_cur%NOTFOUND; /*print one row at a time*/ DBMS_OUTPUT.PUT_LINE(isbn_out||’ ‘||title_out); END LOOP; /*close the cursor*/ CLOSE lb_cur; END list_books; /*procedure to remove a book and all of its copies*/ PROCEDURE weed(isbn_in IN VARCHAR2) AS BEGIN assert_notnull(isbn_in); /*note the order of delete stataments*/ DELETE book_copies WHERE isbn=isbn_in; DELETE books WHERE isbn=isbn_in; END weed; /*procedure to display the title of a book given its isbn*/ PROCEDURE getTitle(isbn_in IN VARCHAR2) AS title_out VARCHAR2(50); CURSOR gt_cur IS SELECT title FROM books WHERE isbn=isbn_in; BEGIN Page 30 of 43 /*open the cursor*/ OPEN gt_cur; /*start the loop*/ LOOP FETCH gt_cur INTO title_out; /*exit when there is no more rows*/ EXIT WHEN gt_cur%NOTFOUND; /*print one row at a time*/ DBMS_OUTPUT.PUT_LINE(‘The title of a book with isbn= ’||isbn_in||’ is ‘||title_out); END LOOP; /*close the cursor*/ CLOSE gt_cur; END getTitle; END BOOK; Step 7. Compile the package body by clicking the button pointed to by the arrow in the figure below. Step 8. The last thing that remains to be done is to write different anonymous blocks that will call the procedures stored in the “book” package. We will invoke the procedure getTitle(isbn_in) directly from the Oracle SQL Developer Worksheet, so there is no need to write an anonymous block that will make the call. Step 8.1 To add a book and a copy. Right click the connection name in the navigator and select “Open SQL Worksheet”. Page 31 of 43 Write the following code in the worksheet: BEGIN book.add(‘&isbn_in’,’&title_in’,’&barcode_id_in’); END; Save the code by clicking the SAVE button pointed to by the arrow in the figure below, give it a name “call_add” and select the file type “.pls”. Page 32 of 43 Step 8.2 To add a copy. Follow the same way as Step 8.1, open another worksheet and write the following code in the worksheet: BEGIN book.add_copy(‘&isbn_in’,’&barcode_id_in’); END; Save it in the file with the name “call_add_copy” and type “.pls”. Step 8.3 To list all books. Follow the same way as Step 8.1, open another worksheet and write the following code in the worksheet: BEGIN Book.list_books; END; Save it in the file with the name “call_list_books” and type “.pls”. Step 8.4 To remove a book and all its copies. Follow the same way as Step 8.1, open another worksheet and write the following code in the worksheet: Page 33 of 43 BEGIN book.weed(‘&isbn_in’); END; Save it in the file with the name “call_weed” and type “.pls”. Step 9. Run the programs. Step 9.1 Create tables by running the file “createTables.sql”. Step 9.2 Add a book and a copy. Click File -> Open -> select “call_add.pls”. Run the file “call_add.pls” by clicking the “RUN Script” button pointed to by the arrow in the figure below and enter input information. Enter value for ISBN_IN: 1 Enter value for TITLE_IN: Oracle Enter value for BARCODE_ID_IN: 11 The result is shown in the “Script Output”. Page 34 of 43 Step 9.3 Add another book and a copy. Run the file “call_add.pls” again and enter the following information: Enter value for ISBN_IN: 2 Enter value for TITLE_IN: Java Enter value for BARCODE_ID_IN: 21 The result is shown in the “Script Output”. Step 9.4 Add a copy. Click File -> Open -> select “call_add_copy.pls”. Run the file “call_add_copy.pls” by clicking the “Run Script” button and enter the information. Page 35 of 43 Enter value for isbn_in: 1 Enter value for barcode_id_in: 12 The result is shown in the “Script Output”. Step 9.5 Add another copy. Run the file “call_add_copy.pls” again and enter the following information: Enter value for isbn_in: 2 Page 36 of 43 Enter value for barcode_id_in: 22 The result is shown in the “Script Output”. Step 9.6 List the books. Note that you need to run the following command in the worksheet once per session to display the result on the screen. set serveroutput on; Click File -> Open -> select “call_list_books.pls”. Run the file “call_list_books.pls” by clicking the “Run Script” button. The result is shown in the “Script Output”. Step 9.7 Call the procedure “book.getTitle” in the worksheet directly. Enter the code as follows in the worksheet and click the “Run Script” button. Page 37 of 43 The result is shown in the “Script Output”. Step 9.8 Remove a book and all its copies. Click File -> Open -> select “call_weed.pls”. Run the file “call_weed.pls” by clicking the “Run Script” button. Page 38 of 43 Enter value for isbn_in: 2 The result is shown in the “Script Output”. Step 9.9 List all the books. Click File -> Open -> select “call_list_books.pls”. Run the file “call_list_books.pls” by clicking the “Run Script” button. Page 39 of 43 The result is shown in the “Script Output”. Note that there is only one book now. 12. How to call a PL/SQL procedure in a Java program Please refer to the following example to call a PL/SQL procedure in a Java program. Step 1. Create the table “REGION” with two attributes and insert some data. // create table “REGION” CREATE TABLE REGION ( R_REGIONKEY NUMBER(2,0) NOT NULL PRIMARY KEY, R_NAME VARCHAR2 (25) NOT NULL ); INSERT INTO REGION VALUES (1, 'Alice'); INSERT INTO REGION VALUES (2, 'Bob'); Step 2. Create a PL/SQL procedure named “find_region” in Oracle SQL Developer that returns the region’s name (“regionname”) corresponding to the input of the region’s key (“regionkey”). The procedure has two parameters: the first one is input parameter and the second one is output parameter. Note that when you create the procedure “find_region” you need to specify the parameters (name, type and mode) by clicking the “+” symbol pointed to by the arrow in the Page 40 of 43 figure below. In this example, the mode of the parameter “regionkey” is “IN” and the mode of the parameter “regionname” is “OUT”. The content of the procedure is as follows: // create the procedure “find_region” CREATE OR REPLACE PROCEDURE FIND_REGION ( REGIONKEY IN NUMBER , REGIONNAME OUT VARCHAR2 ) AS v_name VARCHAR2(25); BEGIN SELECT r_name INTO v_name FROM REGION WHERE r_regionkey = regionkey; regionname := v_name; END FIND_REGION; Page 41 of 43 Step 3. Write the Java program to call the procedure “find_region”. An example of a Java program using JDBC connection to call a procedure in Oracle 11g // a sample example of using java to call PL/SQL procedure find_region // return the value of “r_regionname” corresponding to r_regionkey=1 package callProc; import java.io.*;// java package for i/o import java.sql.*;// java package for sql statements class callProc { public static void main(String[] args) throws SQLException, IOException { // Step 1. Load a database driver try { Class.forName("oracle.jdbc.OracleDriver"); } catch(Exception x){ System.out.println( "Unable to load the driver class!" ); } // Step 2. Creating an Oracle JDBC Connection. The following example assumes // that the login name is smith1234 and the password is johnsmith Connection conn = DriverManager.getConnection ("jdbc:oracle:thin:@//oracle.cs.ou.edu:1521/pdborcl.cs.ou.edu",”smith1234”, “johnsmith”); // Step 3. Call the procedure "find_region" try { int i_rkey = 1;//input parameter of the procedure //call procedure FIND_REGION(pram1,pram2) CallableStatement pstmt = conn.prepareCall("{call find_region(?,?)}");//call the procedure pstmt.setInt(1, i_rkey);/*the first parameter (input parameter) to procedure find_region*/ pstmt.registerOutParameter(2, Types.CHAR);/*the second parameter (output parameter) from procedure find_region*/ pstmt.executeUpdate();//execute procedure String o_rname = pstmt.getString(2); System.out.println("region " + i_rkey + " is: " + o_rname);/*print out the output*/ pstmt.close();//close the pstmt } catch (SQLException e) { System.err.println(e.getMessage()); Page 42 of 43 } conn.close(); } } Step 3. To compile and run the program in eclipse, press the RUN button pointed to by the arrow in the figure below. References 1. Oracle Database PL/SQL Language Reference 12c Release 1(12.1) http://docs.oracle.com/database/121/LNPLS/toc.htm 2. “Oracle PL/SQL by Example” (fourth edition), Benjamin Rosenzweig and Elena Silvestrova Rakhimov, 2009 published by Addison-Wesley. 3. Developing and Debugging PL/SQL using Oracle SQL Developer 4. http://www.oracle.com/webfolder/technetwork/tutorials/obe/db/11g/r2/prod/appdev/sqldev/ plsql_debug/plsql_debug_otn.htm 5. Working with PL/SQL by Sue Harper http://www.oracle.com/technetwork/issue-archive/2007/07-nov/o67sql-101793.html Page 43 of 43
Source Exif Data:
File Type : PDF File Type Extension : pdf MIME Type : application/pdf PDF Version : 1.5 Linearized : No Page Count : 43 Language : en-US Tagged PDF : Yes Author : Jincheng Creator : Microsoft® Word 2010 Create Date : 2017:10:03 21:38:25-05:00 Modify Date : 2017:10:03 21:38:25-05:00 Producer : Microsoft® Word 2010EXIF Metadata provided by EXIF.tools