Thursday, October 29, 2009

Lab 3.1 Exercises



[ Team LiB ]





Lab 3.1 Exercises


3.1.1 Make Use of PL/SQL Language Components


Now that you have the character types and the lexical units, it is equivalent to knowing the alphabet and how to spell out words.


a)

Why does PL/SQL have so many different types of characters? What are they used for?

b)

What would be the equivalent of a verb and a noun in English in PL/SQL? Do you speak PL/SQL?



3.1.2 Make Use of PL/SQL Variables


Variables may be used to hold a temporary value.





Syntax : <variable-name> <data type> [optional default
assignment]

Variables may also be known as identifiers. There are some restrictions that you need to be familiar with: Variables must begin with a letter and may be up to 30 characters long. Consider the following example:


FOR EXAMPLE


This example contains a list of valid identifiers:





v_student_id
v_last_name
V_LAST_NAME
apt_#

It is important to note that the identifiers v_last_name and V_LAST_NAME are considered identical because PL/SQL is not case sensitive.


Next, consider an example of illegal identifiers:


FOR EXAMPLE





X+Y
1st_year
student ID

Identifier X+Y is illegal because it contains the "+" sign. This sign is reserved by PL/SQL to denote an addition operation, and it is referred to as a mathematical symbol. Identifier, 1st_year is illegal because it starts with a number. Finally, identifier student ID is illegal because it contains a space.


Next, consider another example:


FOR EXAMPLE





SET SERVEROUTPUT ON;
DECLARE
first&last_names VARCHAR2(30);
BEGIN
first&last_names := 'TEST NAME';
DBMS_OUTPUT.PUT_LINE(first&last_names);
END;

In this example, you declare a variable called first&last_names. Next, you assign a value to this variable and display this value on the screen. When run, the example produces the following output:





Enter value for last_names: Elena
old 2: first&last_names VARCHAR2(30);
new 2: firstElena VARCHAR2(30);
Enter value for last_names: Elena
old 4: first&last_names := 'TEST NAME';
new 4: firstElena := 'TEST NAME';
Enter value for last_names: Elena
old 5: DBMS_OUTPUT.PUT_LINE(first&last_names);
new 5: DBMS_OUTPUT.PUT_LINE(firstElena);
TEST NAME
PL/SQL procedure successfully completed.

Consider the output produced. Because there is an ampersand (&) present in the name of the variable first&last_names, the portion of the variable is considered to be a substitution variable (you learned about substitution variables in Chapter 2). In other words, the portion of the variable name after the ampersand (last_names) is treated by the PL/SQL compiler as a substitution variable. As a result, you are prompted to enter the value for the last_names variable every time the compiler encounters it.


It is important to realize that while this example does not produce any syntax errors, the variable first&last_names is still an invalid identifier because the ampersand character is reserved for substitution variables. To avoid this problem, change the name of the variable from first&last_names to first_and_last_names. Therefore, you should use an ampersand sign in the name of a variable only when you use it as a substitution variable in your program.


FOR EXAMPLE





-- ch03_1a.pls
SET SERVEROUTPUT ON
DECLARE
v_name VARCHAR2(30);
v_dob DATE;
v_us_citizen BOOLEAN;
BEGIN
DBMS_OUTPUT.PUT_LINE(v_name||'born on'||v_dob);
END;

a)

If you ran the previous example in a SQL*Plus, what would be the result?

b)

Run the example and see what happens. Explain what is happening as the focus moves from one line to the next.



3.1.3 Handle PL/SQL Reserved Words


Reserved words are ones that PL/SQL saves for its own use (e.g., BEGIN, END, and SELECT). You cannot use reserved words for names of variables, literals, or user-defined exceptions.


FOR EXAMPLE





SET SERVEROUTPUT ON;
DECLARE
exception VARCHAR2(15);
BEGIN
exception := 'This is a test';
DBMS_OUTPUT.PUT_LINE(exception);
END;

a)

What would happen if you ran the preceding PL/SQL block? Would you receive an error message? If so, explain.



3.1.4 Make Use of Identifiers in PL/SQL


Take a look at the use of identifiers in the following example:


FOR EXAMPLE





SET SERVEROUTPUT ON;
DECLARE
v_var1 VARCHAR2(20);
v_var2 VARCHAR2(6);
v_var3 NUMBER(5,3);
BEGIN
v_var1 := 'string literal';
v_var2 := '12.345';
v_var3 := 12.345;
DBMS_OUTPUT.PUT_LINE('v_var1: '||v_var1);
DBMS_OUTPUT.PUT_LINE('v_var2: '||v_var2);
DBMS_OUTPUT.PUT_LINE('v_var3: '||v_var3);
END;

In this example, you declare and initialize three variables. The values that you assign to them are literals. The first two values, 'string literal' and '12.345' are string literals because they are enclosed by single quotes. The third value, 12.345, is a numeric literal. When run, the example produces the following output:





v_var1: string literal
v_var2: 12.345
v_var3: 12.345
PL/SQL procedure successfully completed.

Consider another example that uses numeric literals:


FOR EXAMPLE





SET SERVEROUTPUT ON;
DECLARE
v_var1 NUMBER(2) := 123;
v_var2 NUMBER(3) := 123;
v_var3 NUMBER(5,3) := 123456.123;
BEGIN
DBMS_OUTPUT.PUT_LINE('v_var1: '||v_var1);
DBMS_OUTPUT.PUT_LINE('v_var2: '||v_var2);
DBMS_OUTPUT.PUT_LINE('v_var3: '||v_var3);
END;

a)

What would happen if you ran the preceding PL/SQL block?



3.1.5 Make Use of Anchored Data Types


The data type that you assign to a variable can be based on a database object. This is called an anchored declaration since the variable's data type is dependent on that of the underlying object. It is wise to make use of anchored data types when possible so that you do not have to update your PL/SQL when the data types of base objects change.





Syntax: <variable_name> <type attribute>%TYPE

The type is a direct reference to a database column.


FOR EXAMPLE





-- ch03_2a.pls
SET SERVEROUTPUT ON
DECLARE
v_name student.first_name%TYPE;
v_grade grade.numeric_grade%TYPE;
BEGIN
DBMS_OUTPUT.PUT_LINE(NVL(v_name, 'No Name ')||
' has grade of '||NVL(v_grade, 0));
END;

a)

In the previous example, what has been declared? State the data type and value.



3.1.6 Declare and Initialize Variables


In PL/SQL, variables must be declared in order to be referenced. This is done in the initial declarative section of a PL/SQL block. Remember that each declaration must be terminated with a semicolon. Variables can be assigned using the assignment operator ":=". If you declare a variable to be a constant, it will retain the same value throughout the block; in order to do this, you must give it a value at declaration.


Type the following into a text file and run the script from a SQL*Plus session.





-- ch03_3a.pls
SET SERVEROUTPUT ON
DECLARE
v_cookies_amt NUMBER := 2;
v_calories_per_cookie CONSTANT NUMBER := 300;
BEGIN
DBMS_OUTPUT.PUT_LINE('I ate ' || v_cookies_amt ||
' cookies with ' || v_cookies_amt *
v_calories_per_cookie || ' calories.');
v_cookies_amt := 3;
DBMS_OUTPUT.PUT_LINE('I really ate ' ||
v_cookies_amt
|| ' cookies with ' || v_cookies_amt *
v_calories_per_cookie || ' calories.');
v_cookies_amt := v_cookies_amt + 5;
DBMS_OUTPUT.PUT_LINE('The truth is, I actually ate '
|| v_cookies_amt || ' cookies with ' ||
v_cookies_amt * v_calories_per_cookie
|| ' calories.');
END;

a)

What will the output be for the preceding script? Explain what is being declared and what the value of the variable is throughout the scope of the block.



FOR EXAMPLE





-- ch03_3a.pls
SET SERVEROUTPUT ON
DECLARE
v_lname VARCHAR2(30);
v_regdate DATE;
v_pctincr CONSTANT NUMBER(4,2) := 1.50;
v_counter NUMBER := 0;
v_new_cost course.cost%TYPE;
v_YorN BOOLEAN := TRUE;
BEGIN
DBMS_OUTPUT.PUT.PUT_LINE(V_COUNTER);
DBMS_OUTPUT.PUT_LINE(V_NEW_COST);
END;

b)

In the previous example, add the following expressions to the beginning of the procedure (immediately after the BEGIN in the previous example), then explain the values of the variables at the beginning and at the end of the script.






v_counter := NVL(v_counter, 0) + 1;
v_new_cost := 800 * v_pctincr;

PL/SQL variables are held together with expressions and operators. An expression is a sequence of variables and literals, separated by operators. These expressions are then used to manipulate data, perform calculations, and compare data.


Expressions are composed of a combination of operands and operators. An operand is an argument to the operator; it can be a variable, a constant, a function call. An operator is what specifies the action (+, **, /, OR, etc.).


You can use parentheses to control the order in which Oracle evaluates an expression. Continue to add the following to your SQL script the following:





v_counter := ((v_counter + 5)*2) / 2;
v_new_cost := (v_new_cost * v_counter)/4;

c)

What will the values of the variables be at the end of the script?



3.1.7 Understand the Scope of a Block, Nested Blocks, and Labels


Scope of a Variable


The scope, or existence, of structures defined in the declaration section are local to that block. The block also provides the scope for exceptions that are declared and raised. Exceptions will be covered in more detail in Chapters 7, 10, and 11.


The scope of a variable is the portion of the program in which the variable can be accessed, or where the variable is visible. It usually extends from the moment of declaration until the end of the block in which the variable was declared. The visibility of a variable is the part of the program where the variable can be accessed.





BEGIN -- outer block
BEGIN -- inner block
...;
END; -- end of inner block
END; -- end of outer block

Labels and Nested Blocks

Labels can be added to a block in order to improve readability and to qualify the names of elements that exist under the same name in nested blocks. The name of the block must precede the first line of executable code (either the BEGIN or DECLARE) as follows:


FOR EXAMPLE





-- ch03_4a.pls
set serveroutput on
<<find_stu_num>>
BEGIN
DBMS_OUTPUT.PUT_LINE('The procedure
find_stu_num has been executed.');
END find_stu_num;

The label optionally appears after END. In SQL*Plus, the first line of a PL/SQL block cannot be a label. For commenting purposes, you may alternatively use "- -" or /*, ending with */.


Blocks can be nested in the main section or in an exception handler. A nested block is a block that is placed fully within another block. This has an impact on the scope and visibility of variables. The scope of a variable in a nested block is the period when memory is being allocated for the variable and extends from the moment of declaration until the END of the nested block from which it was declared. The visibility of a variable is the part of the program where the variable can be accessed.


FOR EXAMPLE





-- ch03_4b.pls
SET SERVEROUTPUT ON
<< outer_block >>
DECLARE
v_test NUMBER := 123;
BEGIN
DBMS_OUTPUT.PUT_LINE
('Outer Block, v_test: '||v_test);
<< inner_block >>
DECLARE
v_test NUMBER := 456;
BEGIN
DBMS_OUTPUT.PUT_LINE
('Inner Block, v_test: '||v_test);
DBMS_OUTPUT.PUT_LINE
('Inner Block, outer_block.v_test: '||
outer_block.v_test);
END inner_block;
END outer_block;

This example produces the following output:





Outer Block, v_test: 123
Inner Block, v_test: 456
Inner Block, outer_block.v_test: 123

a)

If the following example were run in SQL*Plus, what do you think would be displayed?





-- ch03_5a.pls
SET SERVEROUTPUT ON
DECLARE
e_show_exception_scope EXCEPTION;
v_student_id NUMBER := 123;
BEGIN
DBMS_OUTPUT.PUT_LINE('outer student id is '
||v_student_id);
DECLARE
v_student_id VARCHAR2(8) := 125;
BEGIN
DBMS_OUTPUT.PUT_LINE('inner student id is '
||v_student_id);
RAISE e_show_exception_scope;
END;
EXCEPTION
WHEN e_show_exception_scope
THEN
DBMS_OUTPUT.PUT_LINE('When am I displayed?');
DBMS_OUTPUT.PUT_LINE('outer student id is '
||v_student_id);
END;
b)

Now run the example and see if it produces what you expected. Explain how the focus moves from one block to another in this example.






    [ Team LiB ]



    No comments: