Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 50 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
50
Dung lượng
139,48 KB
Nội dung
a cursor parameter, whose value is set when the cursor opens, only during the cursor's declared SQL query.
Flexibility within cursor parameters enables the developer to pass different numbers of parameters to a cursor by using
the parameter default mechanism. This is illustrated in the following example:
CURSOR c_line_item
(order_num INTEGER DEFAULT 100,
line_num INTEGER DEFAULT 1) IS
By using the INTEGER DEFAULT declaration, you can pass all, one, or none of the parameters to this cursor depending
on the logic flow of your code.
Creating Cursor Packages
A cursor package is similar to a procedure package in that you specify the cursor and its return attribute, %TYPE or %
ROWTYPE, in the package specification area. You then specify the cursor "body" in the package body specification
area. Packaging a cursor in this manner gives you the flexibility of changing the cursor body without having to recompile
applications that reference the packaged procedure. The following is a cursor package example:
CREATE OR REPLACE PACKAGE order_total
AS
CURSOR c_line_item RETURN line_item.merch_gross%TYPE;
END order_total;
CREATE OR REPLACE PACKAGE BODY order_total
AS
CURSOR c_line_item RETURN line_item.merch_gross%TYPE
SELECT merch_gross
FROM line_item
WHERE order_num = g_order_num;
END order_total;
In this example, the RETURN variable is the same as the line_item.item_merch_gross column. You can use the %
ROWTYPE attribute to specify a RETURN record that mirrors a row in a database table.
Procedure Variables
The most important feature of any language is how to define variables. Once you've defined the variables, PL/SQL
enables you to use them in SQL statements as well as language statements. Definition of constants within PL/SQL
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
follow the same rules. Also, you can define variables and constants as local to one subprogram or global to the entire
package you are creating.
You must declare variables and constants before referencing them in any other statement.
Variable Declaration and Assignment
Any PL/SQL or SQL data type is valid for variable definitions. The most commonly used data types are VARCHAR2,
DATE, NUMBER (SQL data types), BOOLEAN, and BINARY_INTEGER (PL/SQL data types). PL/SQL scalar and
composite data types are discussed in more detail later in this chapter.
Local Variables
Assume you want to declare two local variables named merch_gross and recip_count. The first, merch_gross, is to hold a
ten-digit, floating-point number rounded to two decimal places; recip_count will hold an integer counter. Declare these
variables as follows:
merch_gross NUMBER;
recip_count BINARY_INTEGER;
You can also declare merch_gross in this example as NUMBER(10,2) to explicitly show total digits and
rounding. However, if it's related to a database field, a declaration of this type must change if the database definition
changes.
You can use two methods to assign values to variables. The first is using an assignment operator as follows:
merch_gross := 10.50;
The second method is to use a SQL SELECT or FETCH statement that assigns a database value as follows:
SELECT merch_gross
INTO merch_gross
FROM line_item
WHERE order_num = g_order_num;
Local Constants
Constant declaration is similar to variable declaration except that the CONSTANT keyword must follow the variable
name. You must immediately assign a value to the CONSTANT.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
tax_rate CONSTANT NUMBER := 0.03;
Global Variables
Global variables are defined in the same manner as local variables, but they are defined outside of all procedure
definitions. Suppose you want to define variables g_order_num and g_recip_counter to be available to all package
subprograms. The following is an example of the syntax:
CREATE OR REPLACE PACKAGE BODY
order_total
AS
g_order_num NUMBER;
g_recip_counter BINARY_INTEGER;
PROCEDURE
Notice that these global variables are defined in the package body specification area so as not to be "seen" by
applications that call the order_total packaged procedure.
If you use variable names that are the same as database column names, results are unpredictable when
performing any database operations such as SELECT or UPDATE with the variables.
DEFAULT Keyword
The DEFAULT keyword enables you to initialize variables without using the assignment operator as in the following
example:
merch_gross NUMBER DEFAULT 10.50;
You can also use the DEFAULT keyword to initialize a subprogram's cursor parameters and fields in user-defined
records.
Variable and Constant Attributes
The two attributes of PL/SQL variables and constants are %TYPE and %ROWTYPE. The %TYPE attribute enables you
to declare variables similar to database columns without knowing the data type of the column. You can define
merch_gross from the previous example as follows:
merch_gross line_item.merch_gross%TYPE;
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Defining a variable in this manner enables you to put database changes in effect on the next compilation of a PL/SQL
procedure without changing the code.
The %ROWTYPE attribute enables you to represent a row in a table with a record type that masks the database columns.
Consider the sample database information in Table 5.1.
Table 5.1. Sample of data in table LINE_ITEM.
Column Name Data
order_num 100
line_num 1
merch_gross 10.50
recipient_num
1000
You can define a cursor inside your procedure (see "Declaring Cursors" earlier in the chapter) to pull information from
the LINE_ITEM table. Along with the cursor, define a ROWTYPE variable to store the fields in this row as follows:
CURSOR c_line_item IS
SELECT merch_gross, recipient_num
FROM line_item
WHERE order_num = g_ordnum;
li_info c_line_item%ROWTYPE;
To retrieve the data, issue a FETCH.
FETCH c_line_item
INTO li_info;
After the FETCH, use dot notation to access the information pulled from the database.
g_order_merch_total := g_order_merch_total + li_info.merch_gross;
Scalar Data Types
PL/SQL supports a wide range of scalar data types for defining variables and constants. Unlike composite data types,
scalar data types have no accessible components. These data types fall into one of the following categories:
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
● Boolean
● Date/time
● Character
● Number
Now, take a closer look at the data types in each category.
Boolean
The BOOLEAN data type, which takes no parameters, is used to store a binary value, TRUE or FALSE. This data type
can also store the non-value NULL. You cannot insert or retrieve data from an Oracle database using this data type.
Date/Time
The data type DATE, which takes no parameters, is used to store date values. These DATE values include time when
stored in a database column. Dates can range from 1/1/4712 B.C. to 12/31/4712 A.D. Defaults for the DATE data type
are as follows:
● Date: first day of current month
● Time: midnight
Character
Character data types include CHAR, VARCHAR2, LONG, RAW, and LONG RAW. CHAR is for fixed-length
character data, and VARCHAR2 stores variable-length character data. LONG stores variable-length character strings;
RAW and LONG RAW store binary data or byte strings. The CHAR, VARCHAR2, and RAW data types take an
optional parameter for specifying length.
datatype(max_len)
This length parameter, max_len, must be an integer literal, not a constant or variable. Table 5.2 shows maximum lengths
and database column widths of character data types.
Table 5.2. Character data type maximum lengths and database column widths.
Data Type Maximum Length Maximum Database Column Width
CHAR 32767 255
VARCHAR2 32767 2000
LONG 32760 2147483647
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
RAW 32767 255
LONG RAW 32760
2147483647
From this table, you can see the constraint on inserting CHAR, VARCHAR2, and RAW data into database columns of
the same type. The limit is the column width. However, you can insert LONG and LONG RAW data of any length into
similar columns because the column width is much greater.
Number
There are two data types in the number data type category: BINARY_INTEGER and NUMBER. BINARY_INTEGER
stores signed integers with a range of -2
31
to 2
31
-1. The most common use for this data type is an index for PL/SQL
tables.
Storage for fixed or floating-point numbers of any size is available using the NUMBER data type. For floating-point
numbers, you can specify precision and scale in the following format:
NUMBER(10,2)
A variable declared in this manner has a maximum of ten digits, and rounding occurs to two decimal places. The
precision default is the maximum integer supported by your system, and 0 is the default for scale. The range for
precision is 1 to 38 whereas the scale range is -84 to 127.
Composite Data Types
The two composite data types in PL/SQL are TABLE and RECORD. The TABLE data type enables the user to define a
PL/SQL table to be used for array processing. The RECORD data type enables the user to go beyond the %ROWTYPE
variable attribute; with it, you specify user-defined fields and field data types.
Array Processing
The TABLE composite data type provides the developer a mechanism for array processing. Although it's limited to one
column of information per PL/SQL table, you can store any number of rows for that column. The word from Oracle is
that future versions of PL/SQL will provide more flexibility in the use of tables.
In the order_total example, define a PL/SQL table named g_recip_list (the information will be used globally). The
following is an illustration of this concept:
TYPE RecipientTabTyp IS TABLE OF NUMBER(22)
INDEX BY BINARY_INTEGER;
g_recip_list RecipientTabTyp;
To initialize an array, you must first define an array name or TYPE, which in this example is RecipientTabTyp. This
TABLE column is defined as NUMBER with a maximum of 22 digits. You can define the column as any valid PL/SQL
data type; however, the primary key, or INDEX, must be of type BINARY_INTEGER. After defining the array
structure, you can make reference for variable definition as shown with g_recip_list defined as an array of TYPE
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
RecipientTabTyp.
Building Arrays
Arrays are available as information stores subsequent to initialization of the array. To store information in the array
g_recip_list that was defined in the last example, you simply reference the array with a numeric value. This is shown in
the following example:
g_recip_list(j) := g_recipient_num(i)
In this example, i and j are counters with values 1. . .n. Once information is stored in an array, you can access it, also
with numeric values, as shown in the example. In this case, rows of g_recipient_num are referenced for storage in
g_recip_list.
Referencing an uninitialized row in a PL/SQL array causes a NO_DATA_FOUND error (see the section
"Exception Handling" later in this chapter).
Record Processing
The RECORD composite data type provides the developer a mechanism for record processing as described previously.
Although you cannot initialize TABLEs at the time of declaration, you can with RECORDs, as illustrated in the
following example:
TYPE LineRecTyp IS RECORD
(merch_gross NUMBER := 0,
recip_num NUMBER := 0 );
li_info LineRecTyp;
Defining a RECORD of TYPE LineRecTyp allows declarations such as li_info of that TYPE as shown. You can use this
method of RECORD declaration in place of the li_info declaration in the previous %ROWTYPE example. As with %
ROWTYPE, references to RECORD information is accomplished with dot notation.
g_order_merch_total := g_order_merch_total + li_info.merch_gross;
You can use one of three methods to assign values to records. First, you can assign a value to a record field as you would
assign any variable.
li_info.merch_gross := 10.50;
A second method is to assign all fields at once by using two records that are declared with the same data type. Assume a
second LineRecTyp is defined as new_li_info.
new_li_info := li_info;
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
This statement assigns all fields of new_li_info the values from the same fields of li_info.
You cannot assign records of different types to each other.
A third method of assigning values to fields of a record is through SQL SELECT or FETCH statements.
OPEN c_line_item;
FETCH c_line_item
INTO li_info;
In this case, all fields of li_info are assigned values from the information retrieved by the FETCH of cursor c_line_item.
Processing Control
Every procedural language has control structures that provide processing of information in a logical manner by
controlling the flow of information. Available structures within PL/SQL include IF-THEN-ELSE, LOOP, and EXIT-
WHEN. These structures provide flexibility in manipulating database information.
Loop Control
Use of the LOOP statement provides iterative processing based on logical choices. The basic construct for PL/SQL
LOOPs is shown in the following example:
<<loop_name>>
LOOP
(repetitive processing)
END LOOP loop_name;
To break out of a loop such as this, you must issue an EXIT or GOTO statement based on some processing condition. If
you raise a user-defined exception, the LOOP also terminates. Now, examine three types of PL/SQL loops that expressly
define LOOP termination conditions.
You can name a loop as shown in the example by using a label such as <<loop_name>> just before the
LOOP statement. Although it's not required, labeling does enable you to keep better track of nested loops.
WHILE Loops
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
The WHILE loop checks the status of any PL/SQL expression that evaluates to TRUE, FALSE, or NULL at the start of
each processing cycle. The following is an example of the use of WHILE loops:
WHILE (expression) LOOP
(loop processing)
END LOOP;
As stated, the program evaluates the expression at the start of each loop cycle. The program performs the loop
processing if the expression evaluates to TRUE. A FALSE or NULL evaluation terminates the loop. Iterations through
the loop are exclusively determined by the evaluation of the expression.
Numeric FOR Loops
You can control loop iterations with the use of numeric FOR loops. This mechanism enables the developer to establish a
range of integers for which the loop will cycle. The following example from the order_total package illustrates numeric
FOR loops:
<<recip_list>>
FOR i in 1 g_line_counter LOOP
(loop processing)
END LOOP recip_list;
In this example, loop processing cycles over the range of integers 1 through the value of g_line_counter. The value of
the loop index i is checked at the start of the loop and incremented at the end of the loop. When i is one greater than
g_line_counter, the loop terminates.
Cursor FOR Loops
Cursor FOR loops combine cursor control and conditional control for manipulation of database information. The loop
index, cursor OPEN, cursor FETCH, and cursor CLOSE are all implicit when using cursor FOR loops. Consider the
following example:
CURSOR c_line_item IS
(sql statement)
BEGIN
FOR li_info IN c_line_item LOOP
(retrieved record processing)
END LOOP;
END;
As shown, the program explicitly declares the c_line_item cursor before its reference in the FOR loop. When the
program enters the FOR loop, the code implicitly opens c_line_item and implicitly creates the li_info record as if the
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
following declaration were made:
li_info c_line_item%ROWTYPE;
Once inside the loop, the program can reference the fields of the li_info record that are assigned values by the implicit
FETCH inside the FOR loop. Fields of li_info mirror the row retrieved by the c_line_item cursor.
When data is exhausted for the FETCH, c_line_item is implicitly closed.
You cannot reference the information contained in li_info outside of the cursor FOR loop.
Iterative Control
The IF-THEN-ELSE structure provides alternative processing paths that depend on certain conditions. For example,
consider merchandise orders with multiple-line items where a list of recipients is built. Using conditional and iterative
control to build the recipient list, the code is as follows:
PROCEDURE
init_recip_list
IS
recipient_num NUMBER;
i BINARY_INTEGER;
j BINARY_INTEGER := 1;
k BINARY_INTEGER;
BEGIN
g_out_msg := 'init_recip_list';
<<recip_list>>
FOR i in 1 g_line_counter LOOP
IF i = 1 THEN
g_recip_list(j) := g_recipient_num(i);
j := j + 1;
g_recip_list(j) := 0;
ELSE
FOR k in 1 j LOOP
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
[...]... that is invalid causes Oracle to recompile any and all objects called by the referenced procedure If the recompilation does not succeed, Oracle returns a run-time error to the caller, and the procedure remains in an invalid state Otherwise, Oracle recompiles the referenced procedure, and if the recompilation is successful, execution continues Stored procedures are located in the Oracle SGA after compilation... specific command language programs History of SQL*Plus SQL*Plus originated from the beginning of the Oracle RDBMS days as a product called User Friendly Interface (UFI) Before Version 4 of Oracle RDBMS, UFI was used primarily to administer the Oracle environment UFI was later renamed to SQL*Plus with the advent of Oracle Version 5 There have been some improvements to SQL*Plus from the Please purchase PDF Split-Merge... of the command capabilities, additional ways of starting SQL*Plus, and a changed role for SQL*Plus through the major releases of the Oracle RDBMS kernel For example, before Oracle Version 6, using UFI or SQL*Plus was the only way to administrate the Oracle database With Oracle Version 6 came a new tool called SQL*DBA that took over many of the database responsibilities such as backup and recovery and... highly recommend using SQL*DBA to create and maintain the individual Oracle databases I would restrict SQL*Plus through the use of Oracle' s PRODUCT_USER_PROFILE Table or Oracle PROFILES to prohibit end users from performing any administrative task Usage and Limitations SQL*Plus is the main ad hoc, character-mode interface to the Oracle RDBMS SQL*Plus can easily be used to produce a variety of types... Procedures Another big advantage to using stored procedures is the capability to reference the procedure from many different Oracle applications You can make reference to stored procedures with other stored procedures, database triggers, applications built with Oracle Precompilers, or Oracle tools such as SQL*Forms The following example calls the order_total procedure from another procedure: order_total.get_order_total... type GREATEST_LB label [, label] MLSLABEL GREATEST_LB is a Trusted Oracle function MLSLABEL LEAST Returns least value from list of exprn All expressions expr1, expr2, expr3 must be data-type compatible with expr1 LEAST_UB Returns least upper bound from list of of labels Each label must be of type MLSLABEL LEAST_UB is a Trusted Oracle function NVL Returns value of not null arg1 or value of arg2... arg2 and arg2 must be of the same data type Data type of arg1 and arg2 UID Returns unique ID number of No arguments current Oracle user NUMBER label [, label] Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark MLSLABEL USER Returns username of current Oracle user No arguments VARCHAR2 USERENV Returns current session information based on str, which can be one of the following:... returns a valid message when called inside an exception handler unless an argument is passed to the function that is a valid SQL error number The Oracle error code is the first part of the message returned from SQLERRM Next is the text associated with that Oracle error code In this manner, all errors encountered during procedure execution are trapped and passed back to the application for debug purposes... following example shows the same order_total procedure referenced from PRO*C, an Oracle Precompiler application EXEC SQL BEGIN order_total.get_order_total ( :order_num, :status_code, :message, :merch_gross, :shipping, :taxes, :grand_total); END; END-EXEC; All parameters in this example to the order_total procedure are Oracle bind variables that you must declare before the reference to the package The... multiple-line comments in any portion of PL/SQL code PL/SQL blocks that are dynamically compiled in Oracle Precompiler applications do not support use of singleline comments Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Stored Procedures You can store PL/SQL code in the Oracle database with the RDBMS Procedural Database Extension Advantages of using stored procedures include . SQL error number. The Oracle error code is the first part of the message returned from
SQLERRM. Next is the text associated with that Oracle error code different Oracle
applications. You can make reference to stored procedures with other stored procedures, database triggers, applications
built with Oracle