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
200,61 KB
Nội dung
● Anchor declarations of variables back to the database tables and columns they represent.
Whenever you declare a variable which has anything to do with a database element, use the %
TYPE or %ROWTYPE declaration attributes to define the datatype of those structures. If
those database elements change, your compiled code is discarded. When recompiled, the
changes are automatically applied to your code.
● Always fetch from an explicit cursor into a record declared with %ROWTYPE, as opposed to
individual variables. Assuming that you followed my last piece of advice, that cursor is
declared in a package. That cursor may, therefore, be changed without your knowledge.
Suppose that another expression is added to the SELECT list. Your compiled code is then
marked as being invalid. If you fetched into a record, however, upon recompiliation that
record will take on the new structure of the cursor.
● Encapsulate access to your data structures within packages. I recommend, for example, that
you never repeat a line of SQL in your application; that all SQL statements be hidden behind a
package interface; and that most developers never write any SQL at all. They can simply call
the appropriate package procedure or function, or open the appropriate package cursor. If they
don't find what they need, they ask the owner of the package (who is intimate with the
complex details of the data structure) to add or change an element.
This last suggestion will have the greatest impact on your applications, but it is also among the most
difficult to implement. To accomplish this goal (always execute SQL statements through a procedural
interface), you will want to generate packages automatically for a table or view. This is the only way
to obtain the consistency and code quality required for this segment of your application code. By the
time this second edition is published, you should be able to choose from several different package
generators. You can also build your own.
1.7.3 Center All Development Around Packages
Little did I know when I wrote the first edition of this book how much more I was to learn about PL/
SQL and most of it was about packages. You should center all your PL/SQL development effort
around packages. Don't build standalone procedures or functions unless you absolutely have to (some
frontend tools cannot yet recognize the package syntax of dot notation: package.program). Expect
that you will eventually construct groups of related functionality and start from the beginning with a
package.
The more you use packages, the more you will discover you can do with them. The more you use
packages, the better you will become at constructing clean, easy-to-understand interfaces (or APIs) to
your data and your functionality. The more you use packages, the more effectively you will
encapsulate acquired knowledge and then be able to reapply that knowledge at a later time and
share it with others.
My second book, Advanced Oracle PL/SQL Programming with Packages, offers a detailed set of
"best practices" for package design and usage; highlights follow:
● Don't declare data in your package specification. Instead, "hide" it in the package body and
build "get and set" programs to retrieve the data and change it. This way, you retain control
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
over the data and also retain the flexibility to change your implementation without affecting
the programs which rely on that data.
● Build toggles into your packages, such as a "local" debug mechanisms, which you can easily
turn on and off. This way, a user of your package can modify the behavior of programs inside
the package without having to change his or her own code.
● Avoid writing repetitive code inside your package bodies. This is a particular danger when
you overload multiple programs with the same name. Often the implementation of each of
these programs is very similar. You will be tempted to simply cut and paste and then make the
necessary changes. However, you will be much better off if you take the time to create a
private program in the package which incorporates all common elements, and then have each
overloaded program call that program.
● Spend as much time as you can in your package specifications. Hold off on building your
bodies until you have tested your interfaces (as defined by the specifications) by building
compilable programs which touch on as many different packages as possible.
● Be prepared to work in and enhance multiple packages simultaneously. Suppose that you are
building a package to maintain orders and that you run into a need for a function to parse a
string. If your string package does not yet have this functionality, stop your work in the orders
package and enhance the string package. Unit-test your generic function there. When you've
got it working, deploy it in the orders package. Follow this disciplined approach to
modularization and you will continually build up your toolbox of reusable utilities.
● Always keep your package specifications in separate files from your package bodies. If you
change your body but not your specification, then a recompile only of the body will not
invalidate any programs referencing the package.
● Compile all of the package specifications for your application before any of your bodies. That
way, you will have minimized the chance that you will run into any unresolved or (seemingly)
circular references.
1.7.4 Standardize Your PL/SQL Development Environment
When you get right down to it, programming consists of one long series of decisions punctuated by
occasional taps on the keyboard. Your productivity is determined to a large extent by what you spend
your time making decisions on. Take some time before you start your programming effort to set up
standards among a wide variety of aspects. Here are some of my favorite standards, in no particular
order:
● Set as a rule that individual developers never write their own exception-handling code, never
use the pragma EXCEPTION_INIT to assign names to error numbers, and never call
RAISE_APPLICATION_ERROR with hardcoded numbers and text. Instead, consolidate
exception handling programs into a single package, and predefine all application-specific
exceptions in their appropriate packages. Build generic handler programs that, most
importantly, hide the way you record exceptions in a log. Individual handler sections of code
should never expose the particular implementation, such as an INSERT into a table.
● Never write implicit cursors (in other words, never use the SELECT INTO syntax). Instead,
always declare explicit cursors. If you follow this advice, you will no longer spend time
debating with yourself and others which course is the best. ("Well, if I use ROWNUM < 2 I
never get the TOO_MANY_ROWS exception. So there!") This will improve your
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
productivity. And you will have SQL which is more likely (and able) to be reused.
● Pick a coding style and stick to it. If you ever find yourself thinking things like "Should I
indent three spaces or four?" or "How should I do the line breaks on this long procedure call?"
or "Should I do everything in lowercase or uppercase or what?" then you are wasting time and
doing an injustice to yourself. If you don't have a coding style, use mine it is offered in
detail in Chapter 3, Effective Coding Style.
1.7.5 Structured Code and Other Best Practices
Once you get beyond the "big ticket" best practices, there are many very concrete recommendations
for how to write specific lines of code and constructs. Many of these suggestions have been around
for years and apply to all programming languages. So if you took a good programming class in
college, for example, don't throw away those books! The specific syntax may change, but the
fundamental common sense motivation for what you have learned in the past will certainly work with
PL/SQL as well.
Without a doubt, if you can follow these guidelines, you are sure to end up with programs which are
easier to maintain and enhance:
● Never exit from a FOR loop (numeric or cursor) with an EXIT or RETURN statement. A FOR
loop is a promise: my code will iterate from the starting to the ending value and will then stop
execution.
● Never exit from a WHILE loop with an EXIT or RETURN statement. Rely solely on the
WHILE loop condition to terminate the loop.
● Ensure that a function has a single successful RETURN statement as the last line of the
executable section. Normally, each exception handler in a function would also return a value.
● Don't let functions have OUT or IN OUT parameters. The function should only return values
through the RETURN clause.
● Make sure that the name of a function describes the value being returned (noun structure, as in
"total_compensation"). The name of a procedure should describe the actions taken (verb-noun
structure, as in "calculate_totals").
● Never declare the FOR loop index (either an integer or a record). This is done for you
implicitly by the PL/SQL runtime engine.
● Do not use exceptions to perform branching logic. When you define your own exceptions,
these should describe error situations only.
● When you use the ELSIF statement, make sure that each of the clauses is mutually exclusive.
Watch out especially for logic like "sal BETWEEN 1 and 10000" and "sal BETWEEN 10000
and 20000."
● Remove all hardcoded "magic values" from your programs and replace them with named
constants or functions defined in packages.
● Do not "SELECT COUNT(*)" from a table unless you really need to know the total number
of "hits." If you only need to know whether there is more than one match, simply fetch twice
with an explicit cursor.
● Do not use the names of tables or columns for variable names. This can cause compile errors.
It can also result in unpredictable behavior inside SQL statements in your PL/SQL code. I
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
once did a global search and replace of :GLOBAL.regcd to regcd (a local variable declared as
VARCHAR2(10) but also, unfortunately, the name of a column). Our Q&A procedures were
very weak and we ended up rolling out into production a program with a DELETE statement
containing a WHERE clause that looked like this:
WHERE regcd = regcd
Needless to say, this caused many headaches. If I had simply changed the global reference to
v_regcd, I would have avoided all such problems.
There is lots more I could say about best practices for PL/SQL development, especially concerning
the application of new Oracle8, object-oriented features. But if you follow the ideas I offer in this
section, you will be writing code that is superior to just about everyone else's on this strange planet.
So read on!
Previous: 1.6 A Few of My
Favorite (PL/SQL) Things
Oracle PL/SQL
Programming, 2nd Edition
Next: 2. PL/SQL Language
Fundamentals
1.6 A Few of My Favorite
(PL/SQL) Things
Book Index
2. PL/SQL Language
Fundamentals
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: 1.5 Advice for
Oracle Programmers
Chapter 1
Introduction to PL/SQL
Next: 1.7 Best Practices for
PL/SQL Excellence
1.6 A Few of My Favorite (PL/SQL) Things
PL/SQL is a powerful, many-featured product. This is a lengthy book. I have gone to great lengths to
make all the information within the covers highly accessible. Still, I thought it would be helpful to
offer a quick review of some of my favorite aspects of the PL/SQL language.
It's all wonderful, of course, and I wouldn't trade PL/SQL for any other programming language in the
world. Yet certain features and techniques have stood out for me as ways to improve the efficiency of
my code and the productivity of my development effort.
The topics in the following sections offer just enough information to give you a sense of what is
possible. Go to the appropriate chapter for detailed information.
1.6.1 Anchored declarations
You can use the %TYPE and %ROWTYPE declaration attributes to anchor the datatype of one
variable to that of a previously existing variable or data structure. The anchoring data structure can be
a column in a database table, the entire table itself, a programmer-defined record, or a local PL/SQL
variable. In the following example, I declare a local variable with the same structure as the company
name:
my_company company.name%TYPE;
See
Chapter 4 for details.
1.6.2 Built-in functions
PL/SQL offers dozens of built-in functions to help you get your job done with the minimum amount
of code and fuss possible. Some of them are straightforward, such as the LENGTH function, which
returns the length of the specified string. Others offer subtle variations which will aid you greatly
but only when you are aware of those variations.
Two of my favorites in this category of hidden talents are SUBSTR and INSTR, both character
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
functions. SUBSTR returns a subportion of a string. INSTR returns the position in a string where a
substring is found. Most developers only use these functions to search forward through the strings.
By passing a negative starting location, however, SUBSTR will count from the end of the string. And
INSTR will actually scan in reverse through the string for the nth occurrence of a substring.
See the chapters in
Part 3 for details.
1.6.3 Built-in packages
In addition to the many built-in functions provided by PL/SQL, Oracle Corporation also offers many
built-in packages. These packages of functions, procedures, and data structures greatly expand the
scope of the PL/SQL language. With each new release of the Oracle Server, we get new packages to
improve our own programs.
It is no longer sufficient for a developer to become familiar simply with the basic PL/SQL functions
like TO_CHAR, ROUND, and so on. Those functions have now become only the innermost layer of
useful functionality. Oracle Corporation has built upon those functions, and you should do the same
thing.
See
Appendix C for a summary of the Application Programming Interfaces (APIs) of the built-in
packages.
1.6.4 The cursor FOR loop
The cursor FOR loop is one of my favorite PL/SQL constructs. It leverages fully the tight and
effective integration of the Ada-like programming language with the power of the SQL database
language. It reduces the volume of code you need to write to fetch data from a cursor. It greatly
lessens the chance of introducing loop errors in your programming and loops are one of the more
error-prone parts of a program. Does this loop sound too good to be true? Well, it isn't it's all true!
See
Chapter 7, Loops, for more information.
1.6.5 Scoping with nested blocks
The general advantage of and motivation for a nested block is that you create a scope for all the
declared objects and executable statements in that block. You can use this scope to improve your
control over activity in your program, particularly in the area of exception handling.
In the following procedure, I have placed BEGIN and END keywords around a sequence of DELETE
statements. This way, if any DELETE statement fails, I trap the exception, ignore the problem, and
move on to the next DELETE:
PROCEDURE delete_details
IS
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
BEGIN
BEGIN
DELETE FROM child1 WHERE ;
EXCEPTION
WHEN OTHERS THEN NULL;
END;
BEGIN
DELETE FROM child2 WHERE ;
EXCEPTION
WHEN OTHERS THEN NULL;
END;
END;
I can in this way use my nested blocks to allow my PL/SQL program to continue past exceptions.
See
Chapter 15, Procedures and Functions, for details.
1.6.6 Module overloading
Within a package and within the declaration section of a PL/SQL block, you can define more than
one module with the same name! The name is, in other words, overloaded. In the following example,
I have overloaded the value_ok function in the body of the check package:
PACKAGE BODY check
IS
/* First version takes a DATE parameter. */
FUNCTION value_ok (date_in IN DATE) RETURN BOOLEAN
IS
BEGIN
RETURN date_in <= SYSDATE;
END;
/* Second version takes a NUMBER parameter. */
FUNCTION value_ok (number_in IN NUMBER) RETURN BOOLEAN
IS
BEGIN
RETURN number_in > 0;
END;
END;
Overloading can greatly simplify your life and the lives of other developers. This technique
consolidates the call interfaces for many similar programs into a single module name. It transfers the
burden of knowledge from the developer to the software. You do not have to try to remember, for
example, the six different names for programs which all add values (dates, strings, Booleans,
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
numbers, etc.) to various PL/SQL tables.
Instead, you simply tell the compiler that you want to "add" and pass it the value you want added. PL/
SQL and your overloaded programs figure out what you want to do and they do it for you.
See
Chapter 15 for details.
1.6.7 Local modules
A local module is a procedure or function defined in the declaration section of a PL/SQL block
(anonymous or named). This module is considered local because it is only defined within the parent
PL/SQL block. It cannot be called by any other PL/SQL blocks defined outside of that enclosing
block.
See
Chapter 15 for details.
1.6.8 Packages
A package is a collection of related elements, including modules, variables, table and record TYPEs,
cursors, and exceptions. Packages are among the least understood and most underutilized features of
PL/SQL. That is a shame, because the package structure is also one of the most useful constructs for
building well-designed PL/SQL-based applications. Packages provide a structure in which you can
organize your modules and other PL/SQL elements. They encourage proper programming techniques
in an environment that often befuddles the implementation of good design.
With packages, you can:
● Create abstract datatypes and employ object-oriented design principles in your Oracle-based
applications.
● Use top-down design techniques comprehensively. You can build package specifications
devoid of any code and actually compile programs that call the modules in these "stub"
packages.
● Create and manipulate data that persist throughout a database session. You can use variables
that are declared in a package to create global data structures.
See
Chapter 16, Packages, for details. The disk that accompanies this book contains many examples
of packages. The frontend software gives you an easy-to-use interface to the code and explanations
for using it.
Previous: 1.5 Advice for
Oracle Programmers
Oracle PL/SQL
Programming, 2nd Edition
Next: 1.7 Best Practices for
PL/SQL Excellence
1.5 Advice for Oracle
Programmers
Book Index
1.7 Best Practices for PL/
SQL Excellence
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
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: 1.4 PL/SQL
Versions
Chapter 1
Introduction to PL/SQL
Next: 1.6 A Few of My
Favorite (PL/SQL) Things
1.5 Advice for Oracle Programmers
This whole book is full of advice about PL/SQL programming, but in this section I offer a few basic
principles. These principles guide my own use of PL/SQL and I'd like to encourage you to adopt
them as well.
1.5.1 Take a Creative, Even Radical Approach
We all tend to fall into ruts, in almost every aspect of our lives. People are creatures of habit: you
learn to write code in one way; you come to assume certain limitations about a product; you turn
aside possible solutions without serious examination because you just know it can't be done.
Developers become downright prejudiced about their own tools, and often not in positive ways. "It
can't run any faster than that; it's a pig." "I can't make it work the way the user wants; that'll have to
wait for the next version." "If I were using X or Y or Z product, it would be a breeze. But with this
stuff, everything is a struggle."
Sadly (or is it happily?), the reality is that your program could almost always run a little faster. The
screen could function just the way the user wants it to. Although each product has its limitations,
strengths, and weaknesses, you should never have to wait for the next version. Isn't it so much more
satisfying to be able to tell your therapist that you tackled the problem head-on, accepted no excuses,
and created a solution?
How do you do this? Break out of the confines of your hardened views and take a fresh look at the
world (or maybe just your cubicle). Reassess the programming habits you've developed, particularly
regarding fourth-generation language (4GL) development with the Oracle tools. Be creative step
away from the traditional methods, from the often limited and mechanical approaches constantly
reinforced in our places of business.
Try something new: experiment with what may seem to be a radical departure from the norm. You
will be surprised at how much you will learn, how you will grow as a programmer and problem-
solver. Over the years, I have surprised myself over and over with what is really achievable when I
stopped saying "You can't do that!" and instead simply nodded quietly and murmured "Now, if I do it
this way "
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
[...]... details 1.4.7.2 Oracle/ AQ, the Advanced Queueing Facility Oracle8 offers an "advanced queuing" facility which implements deferred execution of work Oracle is positioning Oracle/ AQ (Oracle/ Advanced Queuing) as an alternative to the queuing mechanisms of teleprocessing monitors and messaging interfaces Oracle/ AQ will also serve as a foundation technology for workflow management applications Oracle/ AQ is... enhancements of Oracle8 , including large objects (LOBs), object-oriented design and development, collections (VARRAYs and nested tables), and Oracle/ AQ (the Oracle/ Advanced Queueing facility) 1.4.1 Working with Multiple Versions of PL/SQL All of the releases of PL/SQL Version 2 are linked directly to the release of the Oracle Server on which they run PL/SQL Release 1.1 is available only with the Oracle Developer/2000... mainstream vendor like Oracle Corporation ventures into new technology waters, it is virtually certain that the change will be evolutionary rather than revolutionary True to form, Oracle8 's relational capabilities are still the mainstay of Oracle Corporation's flagship database server, and they satisfy the need for compatibility with older Oracle versions But with the objects option, Oracle8 allows programmers... your Oracle User Group, even the worldwide Oracle community through the International Oracle User's Group and User's Week convention Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Previous: 1.4 PL/SQL Versions 1.4 PL/SQL Versions Oracle PL/SQL Programming, 2nd Edition Book Index Next: 1.6 A Few of My Favorite (PL/SQL) Things 1.6 A Few of My Favorite (PL/SQL) Things The Oracle. .. modules from your client application Oracle PL/SQL Programming, 2nd Edition Book Index Next: 1.5 Advice for Oracle Programmers 1.5 Advice for Oracle Programmers 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: 1.2 The Concept of Programming in Oracle Applications Chapter 1 Introduction... with Oracle 8.0, the "objectrelational" version of the Oracle database PL/SQL8 incorporates numerous significant new features and many incremental improvements PL/SQL8 features are summarized in the following sections and are covered in this book primarily in Part 5 The following overview is not intended to be a comprehensive description of new Oracle8 features; it covers only those aspects of Oracle8 ... and Miscellaneous Functions, provide additional details 1.4.8 PL/SQL Release 1.1 PL/SQL Release 1.1 is only used by the tools in the Oracle Developer/2000 suite: Oracle Forms, Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Oracle Reports, and Oracle Graphics Table 1.3 reviews PL/SQL Version 2.0 functionality and indicates any restrictions or special information you will need... batch-processing script Oracle Version 6.0 was released at approximately the same time PL/SQL was then implemented within SQL*Forms Version 3, the predecessor of Oracle Forms Release 1.1 Available only in the Oracle Developer/2000 Release 1 tools This upgrade supports client-side packages and allows client-side programs to execute stored code transparently Version 2.0 Available with Release 7.0 (Oracle Server)... life cycle of Oracle' s database and tools, Oracle Corporation had recognized two key weaknesses in their architecture: lack of portability and problems with execution authority 1.3.1 Improved Application Portability with PL/SQL The concern about portability might seem odd to those of us familiar with Oracle Corporation's marketing and technical strategies One of the hallmarks of the Oracle solution... linker will generate the appropriate shared library format that is callable from C In Oracle 8.0, however, C will be the most common language for external procedures, since all of Oracle' s support libraries are written in C See Chapter 21, External Procedures, for further details and examples 1.4.7.6 Large object support Oracle8 and PL/SQL8 support several variations of LOB or Large OBject datatypes LOBs . 1.5 Advice for
Oracle Programmers
Oracle PL/SQL
Programming, 2nd Edition
Next: 1.7 Best Practices for
PL/SQL Excellence
1.5 Advice for Oracle
Programmers
Book. with others in your company, your Oracle User Group, even the worldwide Oracle
community through the International Oracle User's Group and User's