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
190,43 KB
Nội dung
exception:
weensy_plus := 'Lots of room for me to type now';
When you create a subtype based on an existing variable or database column, that subtype inherits the
length (or precision and scale, in the case of a NUMBER datatype) from the original datatype. This
constraint takes effect when you declare variables based on the subtype, but only as a default. You
can always override that constraint. You will have to wait for a future version of PL/SQL, however,
to actually enforce the constraint in a programmer-defined subtype.
Finally, an anchored subtype does not carry over the NOT NULL constraint to the variables it
defines. Nor does it transfer a default value that was included in the original declaration of a variable
or column specification.
Previous: 4.5 Anchored
Declarations
Oracle PL/SQL
Programming, 2nd Edition
Next: 4.7 Tips for Creating
and Using Variables
4.5 Anchored Declarations
Book Index
4.7 Tips for Creating and
Using Variables
The Oracle Library
Navigation
Copyright (c) 2000 O'Reilly & Associates. All rights reserved.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Previous: 4.4 Variable
Declarations
Chapter 4
Variables and Program Data
Next: 4.6 Programmer-
Defined Subtypes
4.5 Anchored Declarations
This section describes the use of the %TYPE declaration attribute to anchor the datatype of one
variable to another data structure, such as a PL/SQL variable or a column in a table. When you
anchor a datatype, you tell PL/SQL to set the datatype of one variable from the datatype of another
element.
The syntax for an anchored datatype is:
<variable name> <type attribute>%TYPE [optional default
value assignment];
where <variable name> is the name of the variable you are declaring and <type attribute> is any of
the following:
● Previously declared PL/SQL variable name
● Table column in format "table.column"
Figure 4.2 shows how the datatype is drawn both from a database table and PL/SQL variable.
Figure 4.2: Anchored declarations with %TYPE
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Here are some examples of %TYPE used in declarations:
● Anchor the datatype of monthly_sales to the datatype of total_sales:
total_sales NUMBER (20,2);
monthly_sales total_sales%TYPE;
● Anchor the datatype of the company ID variable to the database column:
company_id# company.company_id%TYPE;
Anchored declarations provide an excellent illustration of the fact that PL/SQL is not just a
procedural-style programming language but was designed specifically as an extension to the Oracle
SQL language. A very thorough effort was made by Oracle Corporation to tightly integrate the
programming constructs of PL/SQL to the underlying database (accessed through SQL).
NOTE: PL/SQL also offers the %ROWTYPE declaration attribute, which allows you
to create anchored datatypes for PL/SQL record structures. %ROWTYPE is described
in Chapter 9.
4.5.1 Benefits of Anchored Declarations
All the declarations you have so far seen character, numeric, date, Boolean specify explicitly the
type of data for that variable. In each of these cases, the declaration contains a direct reference to a
datatype and, in most cases, a constraint on that datatype. You can think of this as a kind of
hardcoding in your program. While this approach to declarations is certainly valid, it can cause
problems in the following situations:
● Synchronization with database columns. The PL/SQL variable "represents" database
information in the program. If I declare explicitly and then change the structure of the
underlying table, my program may not work properly.
● Normalization of local variables. The PL/SQL variable stores calculated values used
throughout the application. What are the consequences of repeating (hardcoding) the same
datatype and constraint for each declaration in all of my programs?
Let's take a look at each of these scenarios in more detail.
4.5.1.1 Synchronization with database columns
Databases hold information that needs to be stored and manipulated. Both SQL and PL/SQL perform
these manipulations. Your PL/SQL programs often read data from a database into local program
variables, and then write information from those variables back into the database.
Suppose I have a company table with a column called NAME and a datatype of VARCHAR2(60). I
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
can therefore create a local variable to hold this data as follows:
DECLARE
cname VARCHAR2(60);
and then use this variable to represent this database information in my program. Now, consider an
application which uses the company entity. There may be a dozen different screens, procedures, and
reports which contain this same PL/SQL declaration, VARCHAR2(60), over and over again. And
everything works just fine until the business requirements change or the DBA has a change of heart.
With a very small effort, the definition of the name column in the company table changes to
VARCHAR2(100), in order to accommodate longer company names. Suddenly the database can
store names which will raise VALUE_ERROR exceptions when FETCHed into the company_name
variable.
My programs have become incompatible with the underlying data structures. All declarations of
cname (and all the variations programmers employed for this data throughout the system) must be
modified. Otherwise, my application is simply a ticking time bomb, just waiting to fail. My variable,
which is a local representation of database information, is no longer synchronized with that database
column.
4.5.1.2 Normalization of local variables
Another drawback to explicit declarations arises when working with PL/SQL variables which store
and manipulate calculated values not found in the database. Suppose my programmers built an
application to manage my company's finances. I am very bottom-line oriented, so many different
programs make use of a total_revenue variable, declared as follows:
total_revenue NUMBER (10,2);
Yes, I like to track my total revenue down to the last penny. Now, in 1992, when specifications for
the application were first written, the maximum total revenue I ever thought I could possibly obtain
from any single customer was $99 million, so we used the NUMBER (10,2) declaration, which
seemed like plenty. Then in 1995, my proposal to convert B-2 bombers to emergency transport
systems to deliver Midwestern wheat to famine regions was accepted: a $2 billion contract! I was just
about ready to pop the corks on the champagne when my lead programmer told me the bad news: I
wouldn't be able to generate reports on this newest project and customer: those darn total_revenue
variables were too small!
What a bummer I had to fire the guy.
Just kidding. Instead, we quickly searched out any and all instances of the revenue variables so that
we could change the declarations. This was a time-consuming job because we had spread equivalent
declarations throughout the entire application. I had, in effect, denormalized my local data structures,
with the usual consequences on maintenance. If only I had a way to define each of local total revenue
variables in relation to a single datatype.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
If only they had used %TYPE!
4.5.2 Anchoring at Compile Time
The %TYPE declaration attribute anchors the datatype of one variable to that of another data
structure at the time a PL/SQL block is compiled. If a change is made to the "source" datatype, then
any program which contains a declaration anchored to this datatype must be recompiled before it will
be able to use this new state of the datatype.
The consequences of this rule differ for PL/SQL modules stored in the database and those defined in
client-side tools, such as Oracle Forms.
Consider the following declaration of company_name in the procedure display_company:
PROCEDURE display_company (company_id_in IN INTEGER)
IS
company_name company.name%TYPE;
BEGIN
END;
When PL/SQL compiles this module, it looks up the structure of the company table in the data
dictionary, finds the column NAME, and obtains its datatype. It then uses this data dictionary-based
datatype to define the new variable.
What, then, is the impact on the compiled display_company procedure if the datatype for the name
column of the company table changes? There are two possibilities:
● If display_company is a stored procedure, then the compiled code will be marked as "invalid."
The next time a program tries to run display_company, it will be recompiled automatically
before it is used.
● If display_company is a client-side procedure, then the Oracle Server cannot mark the
program as invalid. The compiled client source code remains compiled using the old datatype.
The next time you execute this module, it could cause a VALUE_ERROR exception to be
raised.
Whether stored or in client-side code, you should make sure that all affected modules are recompiled
after data structure changes.
4.5.3 Nesting Usages of the %TYPE Attribute
You can nest usages of %TYPE in your declarations as well:
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
DECLARE
/* The "base" variable */
unlimited_revenue NUMBER;
/* Anchored to unlimited revenue */
total_revenue unlimited_revenue%TYPE;
/* Anchored to total revenue */
total_rev_94 total_revenue%TYPE;
total_rev_95 total_revenue%TYPE;
BEGIN
In this case total_revenue is based on unlimited_revenue and both variables for 1994 and 1995 are
based on the total_revenue variable. There is no practical limit on the number of layers of nested
usages of %TYPE.
4.5.4 Anchoring to Variables in Other PL/SQL Blocks
The declaration of the source variable for your %TYPE declarations does not need to be in the same
declaration section as the variables which use it. That variable must simply be visible in that section.
The variable could be a global PL/SQL variable (defined in a package) or be defined in an PL/SQL
block which contains the current block, as in the following example:
PROCEDURE calc_revenue
IS
unlimited_revenue NUMBER;
total_revenue unlimited_revenue%TYPE;
BEGIN
IF TO_CHAR (SYSDATE, 'YYYY') = '1994'
THEN
DECLARE
total_rev_94 total_revenue%TYPE;
BEGIN
END;
END IF;
END calc_revenue;
4.5.5 Anchoring to NOT NULL Datatypes
When you declare a variable, you can also specify the need for the variable to be NOT NULL This
NOT NULL declaration constraint is transferred to variables declared with the %TYPE attribute. If I
include a NOT NULL in my declaration of a source variable (one that is referenced afterwards in a %
TYPE declaration), I must also make sure to specify a default value for the variables which make use
of that source variable. Suppose I declare max_available_date NOT NULL in the following example:
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
DECLARE
max_available_date DATE NOT NULL :=
LAST_DAY (ADD_MONTHS (SYSDATE, 3));
last_ship_date max_available_date%TYPE;
The declaration of last_ship_date will then fail to compile, with the following message:
a variable declared NOT NULL must have an initialization
assignment.
If you use a NOT NULL variable in a %TYPE declaration, the new variable must have a default
value provided. The same is not true, however, for variables declared with %TYPE where the source
is a database column.
The NOT NULL column constraint does not apply to variables declared with the %TYPE attribute.
The following code will compile successfully:
DECLARE
Company name is a NOT NULL column in the company
table.
comp_name company.name%TYPE;
BEGIN
comp_name := NULL;
You will be able to declare the comp_name variable without specifying a default, and you will be
able to NULL out the contents of that variable.
Previous: 4.4 Variable
Declarations
Oracle PL/SQL
Programming, 2nd Edition
Next: 4.6 Programmer-
Defined Subtypes
4.4 Variable Declarations
Book Index
4.6 Programmer-Defined
Subtypes
The Oracle Library
Navigation
Copyright (c) 2000 O'Reilly & Associates. All rights reserved.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Previous: 4.3 NULLs in PL/
SQL
Chapter 4
Variables and Program Data
Next: 4.5 Anchored
Declarations
4.4 Variable Declarations
Before you can make a reference to a variable, you must declare it. (The only exception to this rule is
for the index variables of FOR loops.) All declarations must be made in the declaration section of
your anonymous block, procedure, function, or package (see Chapter 15, Procedures and Functions,
for more details on the structure of the declaration section).
When you declare a variable, PL/SQL allocates memory for the variable's value and names the
storage location so that the value can be retrieved and changed. The declaration also specifies the
datatype of the variable; this datatype is then used to validate values assigned to the variable.
The basic syntax for a declaration is:
<variable_name> <datatype> [optional default assignment];
where <variable_name> is the name of the variable to be declared and <datatype> is the datatype or
subtype which determines the type of data which can be assigned to the variable. The [optional
default assignment] clause allows you to initialize the variable with a value, a topic covered in the
next section.
4.4.1 Constrained Declarations
The datatype in a declaration can either be constrained or unconstrained. A datatype is constrained
when you specify a number which constrains or restricts the magnitude of the value which can be
assigned to that variable. A datatype is unconstrained when there are no such restrictions.
Consider the datatype NUMBER. It supports up to 38 digits of precision and uses up the memory
needed for all those digits. If your variable does not require this much memory, you could declare a
number with a constraint, such as the following:
itty_bitty_# NUMBER(1);
large_but_constrained_# NUMBER(20,5);
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Constrained variables require less memory than unconstrained number declarations like this:
no_limits_here NUMBER;
4.4.2 Declaration Examples
Here are some examples of variable declarations:
● Declaration of date variable:
hire_date DATE;
● This variable can only have one of three values: TRUE, FALSE, NULL:
enough_data BOOLEAN;
● This number rounds to the nearest hundredth (cent):
total_revenue NUMBER (15,2);
● This variable-length string will fit in a VARCHAR2 database column:
long_paragraph VARCHAR2 (2000);
● This constant date is unlikely to change:
next_tax_filing_date CONSTANT DATE := '15-APR-96';
4.4.3 Default Values
You can assign default values to a variable when it is declared. When declaring a constant, you must
include a default value in order for the declaration to compile successfully. The default value is
assigned to the variable with one of the following two formats:
<variable_name> <datatype> := <default_value>;
<variable_name> <datatype> DEFAULT <default_value>;
The <default_value> can be a literal, previously declared variable, or expression, as the following
examples demonstrate:
● Set variable to 3:
term_limit NUMBER DEFAULT 3;
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
● Default value taken from Oracle Forms bind variable:
call_topic VARCHAR2 (100) DEFAULT :call.description;
● Default value is the result of a function call:
national_debt FLOAT DEFAULT POWER (10,10);
● Default value is the result of the expression:
order_overdue CONSTANT BOOLEAN :=
ship_date > ADD_MONTHS (order_date, 3) OR
priority_level (company_id) = 'HIGH';
I like to use the assignment operator (:=) to set default values for constants, and the DEFAULT
syntax for variables. In the case of the constant, the assigned value is not really a default, but an
initial (and unchanging) value, so the DEFAULT syntax feels misleading to me.
4.4.4 NOT NULL Clause
If you do assign a default value, you can also specify that the variable must be NOT NULL. For
example, the following declaration initializes the company_name variable to PCS R US and makes
sure that the name can never be set to NULL:
company_name VARCHAR2(60) NOT NULL DEFAULT 'PCS R US';
If your code includes a line like this:
company_name := NULL;
then PL/SQL will raise the VALUE_ERROR exception. You will, in addition, receive a compilation
error with this next declaration:
company_name VARCHAR2(60) NOT NULL;
Why? Because your NOT NULL constraint conflicts instantly with the indeterminate or NULL value
of the company_name variable when it is instantiated.
Previous: 4.3 NULLs in PL/
SQL
Oracle PL/SQL
Programming, 2nd Edition
Next: 4.5 Anchored
Declarations
4.3 NULLs in PL/SQL
Book Index
4.5 Anchored Declarations
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
[...]... Prior to Oracle7 , the CHAR datatype was variable-length; Oracle did not, in fact, support a fixed-length character string datatype and prided itself on that fact To improve compatibility with IBM relational databases and to comply with ANSI standards, Oracle7 reintroduced CHAR as a fixed-length datatype and offered VARCHAR2 as the variable-length datatype When a Version 6 RDBMS is upgraded to Oracle7 ,... FETCH the rowid for a row into a ROWID variable To manipulate rowids in Oracle8 , you will want to use the built-in package, dbms_rowid (see Appendix A, What's on the Companion Disk?) In Oracle7 , you will use the rowidtochar function to convert the rowid to a fixed-length string and then perform operations against that string In Oracle7 , the format of the fixed-length rowid is as follows: BBBBBBB.RRRR.FFFFF... the first file is 1) The data block within the data file The row in the data block (where the first row is 0) Oracle8 provides functions in the dbms_rowid package to convert between the new formats of rowids Usually (and always in Oracle7 ), a rowid will uniquely identify a row of data Within Oracle8 , however, rows in different tables stored in the same cluster can have the same rowid value You are now... the internal storage structure of the Oracle RDBMS Use of this proprietary pseudo-column is akin to coding a clever trick in FORTRAN 77 which takes advantage of a loophole in the compiler to gain performance The improvements could be wiped out in a future release of the software If you are building applications which may need to work against both Oracle and non -Oracle data sources, you should avoid... remove this watermark Oracle offers a powerful new built-in package, DBMS_LOB, to help you manipulate the contents of LOBs in ways not possible with LONGs Generally, Oracle offers you random access to LOB contents, whereas with LONGs you have only sequential access For example, with DBMS_LOB you can perform SUBSTR and INSTR operations against a LOB This is not possible with LONG data Oracle recommends... known values, or use the IS NULL and IS NOT NULL operators for special case null value handling Previous: 4.2 Scalar Datatypes 4.2 Scalar Datatypes Oracle PL/SQL Programming, 2nd Edition Book Index Next: 4.4 Variable Declarations 4.4 Variable Declarations The Oracle Library Navigation Copyright (c) 2000 O'Reilly & Associates All rights reserved Please purchase PDF Split-Merge on www.verypdf.com to remove... actual name of the database file through the data dictionary In Oracle8 , rowid have been "extended" to support partitioned tables and indexes The new, extended rowids include a data object number, identifying the database segment Any schema object found in the same segment, such as a cluster of tables, will have the same object number In Oracle8 , then, a rowid contains the following information: q q... VARCHAR2 declaration is: VARCHAR2 (); as in: DECLARE small_string VARCHAR2(4); line_of_text VARCHAR2(2000); NOTE: In Version 1.1 of PL/SQL, which you use in Oracle Developer/2000 tools like Oracle Forms, the compiler does not insist that you include a maximum length for a VARCHAR2 declaration As a result, you could mistakenly leave off the length in the declaration and end... locate or retrieve a particular row in the database: faster even than a search by primary key You could make use of the rowid in an Oracle Forms application to access the row in the database corresponding to the record on the screen When you create a base-table block in Oracle Forms, it automatically includes the rowid in the block as an "invisible pseudoitem." You do not see it on your item list, but... bytes this is actually seven fewer bytes than allowed in VARCHAR2 type variables! The LONG datatype for PL/SQL variables is quite different from the LONG datatype for columns in the Oracle Server The LONG datatype in Oracle7 can store character strings of up to two gigabytes or 231-1 bytes; this large size makes the LONG column a possible repository of multimedia information, such as graphics images . was designed specifically as an extension to the Oracle
SQL language. A very thorough effort was made by Oracle Corporation to tightly integrate the
programming.
Datatypes
Oracle PL/SQL
Programming, 2nd Edition
Next: 4.4 Variable
Declarations
4.2 Scalar Datatypes
Book Index
4.4 Variable Declarations
The Oracle Library