1. Trang chủ
  2. » Công Nghệ Thông Tin

Tài liệu Teach Yourself PL/SQL in 21 Days- P9 doc

50 349 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Debugging Your Code and Preventing Errors
Trường học University of Science and Technology of Vietnam
Chuyên ngành Computer Science / Programming
Thể loại Giáo trình
Năm xuất bản 2023
Thành phố Hanoi
Định dạng
Số trang 50
Dung lượng 2,63 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

You can see from the number of iterations that we went through with this one piece ofcode that you can save a lot of time by catching syntax errors as you write code.. I’vefound that the

Trang 1

1: DECLARE 2: v_MyChar VARCHAR2(20) := ‘test’;

3: v_NUMBER NUMBER;

4: v_Date DATE := SYSDATE;

5: v_counter INTEGER;

6: BEGIN 7: DBMS_OUTPUT.PUT_LINE(‘This is a Test’);

8: DBMS_OUTPUT.PUT_LINE(‘Of Syntax Error Debugging’);

9: For v_COUNTER IN 1 5 LOOP 10: DBMS_OUTPUT.PUT_LINE(‘You are in loop: ‘ 11: || v_counter);

12: END LOOP;

13: END;

14: / This is a Test

Of Syntax Error Debugging You are in loop: 1 You are in loop: 2 You are in loop: 3 You are in loop: 4 You are in loop: 5

PL/SQL procedure successfully completed.

Finally, you get some good results The purpose of this example is to demonstrate thefollowing:

• One syntax error sometimes masks others Fixing that one will bring the others tolight

• The line number that Oracle flags as containing the error might not necessarily bethe location of the true error

• Taking the time to type in your code carefully saves a lot of time during programtesting

You can see from the number of iterations that we went through with this one piece ofcode that you can save a lot of time by catching syntax errors as you write code Thenext section gives you some tips to help you do just that

Preventing Syntax Errors

It would be nice if it were possible to somehow prevent all syntax errors from occurring

Unfortunately, you are a human being, humans do make mistakes, and nothing you dowill ever change that There are, however, some things that you can do to reduce yourchances of ever writing syntax errors into your code

INPUT

OUTPUT

Trang 2

One thing you can do is become familiar with the most common types of errors I’vefound that the list of common syntax errors includes

• Using=where:=belongs

• Leaving off the semicolon at the end of a statement

• UsingELSEIFwhenELSIFis correct

• Using double quotes (“) for strings instead of single quotes (‘)Keep these common errors in mind as you write code Also, determine what your person-

al list of common mistakes is, and keep that in mind as well Just the act of being sciously aware of these potential mistakes will lessen the chance that you will make one

con-of them

The following are some other things you can do that you might find helpful:

• Format your code Indent constructs such as loops and IFstatements so that youcan easily follow the logic flow, and so that you can easily spot missing END IFs,

ENDs,LOOPstatements, and so forth

• Double-check expressions containing parentheses immediately after you writethem The number of left parentheses should match the number of right parenthe-ses

• If you are coding an IFstatement, start by writing the IFandENDIFlines Thatway, you know that you have the beginning and ending of the statement writtencorrectly Then back up and insert the needed code between those two lines

• Do the same thing when coding loops as when coding IFstatements Write thebeginning and ending lines first

You can also use an editor that recognizes PL/SQL syntax, or that at least can check formismatched parentheses and quotation marks

One programmer’s editor that I find very helpful in this regard is MultiEdit MultiEdit matches parentheses for you, highlights quoted strings, and bold- faces many SQL and PL/SQL keywords You can find out more about MultiEdit by visiting http://www.multiedit.com

Note

Handling Logic Errors

Unlike syntax errors, logic errors do not stop a program from compiling Logic errors are those that are caused when you misunderstand the problem at hand, or

N EW T ERM

Trang 3

when you misunderstand the solution They are mistakes that you make in the logicalflow of a program, not in the syntax of the code that you write After a program is com-piled and tested, logic errors can still occur Possible logic errors include the following:

• Not using proper order of operations

• Using the wrong calculation

• Using loops that never terminateLogic errors are the hardest errors to debug, primarily because the compiler can’t evenbegin to tell you where such an error occurs You are totally on your own when it comes

to finding and fixing logic bugs The main steps in debugging logic errors are to identifythe problem, narrow down the location of the problem, and then fix the problem

The next few sections talk about problems that can occur because the order of operations

is not understood, or because of loops that aren’t coded correctly Following that, you’llfind a section talking about things you can do to help debug logic errors

Order of Operations

Remember when students would ask if there are any real-world applications ofmath? Well, understanding the order of operations is critical, not only in algebra,but in PL/SQL and every programming language, database, and spreadsheet package you

might use The order of operations states the order of precedence each operator is given.

Table 13.1 covers just a few of these levels, with the top level being the highest-priorityorder Day 3, “Writing PL/SQL Expressions” covers this topic in detail

T ABLE 13.1 Simple Order of Operations, from Highest to Lowest

5 + 3 * 9Whenever I ask this question in the classroom, at least one quarter of the class tells methe answer is 72 However, the order of operations tells you that multiplication should

N EW T ERM

Trang 4

come first In this case, 3 * 9 = 27, and when you add 5, you get the correct answer, 32.What if you wanted to arrive at 72? You would use parentheses around the expressionyou want to evaluate first:

(5 + 3) * 9 = 72Misunderstanding the order of operations is a very common problem in areas of busi-ness, finance, statistics, and scientific application programming On Day 3, you learned agreat deal about this issue of operator precedence

Nonterminating Loops

Another common logic problem is loops that never terminate As an example, take a look

at the code in Listing 13.2

1: DECLARE 2: v_MyNumber NUMBER := 0;

3: BEGIN 4: LOOP 5: IF v_MyNumber = 7 THEN 6: EXIT;

As you can see, this loop will never exit because v_MyNumberwill never evaluate

to 7 Since it starts at zero, and is incremented by two each time, it will go from

6 to 8 skipping 7 To fix this, you could rewrite line 5 so that it looks like this:

IF v_MyNumber >= 7 THEN

This is a much safer way to terminate a loop, because it doesn’t matter whether the

v_MyNumbervalue is an exact match or not It won’t matter if the increment in line 8 is a

2 or a 3 or a 1 Whenever the value becomes greater than or equal to 7, the loop will minate

ter-Debugging Approaches for Logic Errors

When you find that you have a logic error somewhere in your code, there are severalthings you can do to find it:

INPUT

ANALYSIS

Trang 5

• Set up a test environment

• Set up some realistic test data

• Narrow down the scope of the problem until you find itThe first two items are things you should do before you even begin development As forthe third item, finding the exact location of a bug is often easier said than done However,there are some techniques that you can use to better enable yourself to do that The fol-lowing sections describe these three items in more detail

Setting Up a Test Environment

Although testing might seem like common sense, you would not believe how manymajor corporations either don’t have test environments for all their applications or simplyput code into production without thoroughly testing the code in a test environment Thisproblem occurred at one firm that used a program to calculate the raises for employees

The managers would enter a percentage such as 05 Unfortunately, the code took thecurrent pay rate multiplied by the percentage of the raise and assigned this to the newvalue of the hourly rate So people with a 5% raise on $10.00 per hour now were making

50 cents per hour! The formula should have been pay_rate * (1+raise) Imaginebeing the IT manager trying to explain this “glitch” to your coworkers

Unfortunately, this problem is more common than it might seem Another case concernscode that that works fine when initially placed in production, but it affects code in laterproduction processes Whenever possible, you should set up a test environment and testextensively It’s best to have someone else actually do the testing Programmers oftenprefer to test by themselves due to an often unspoken fear that a third party will findmore bugs Well, that’s often true! Take advantage of it

Setting Up Test Data

After you have set up your test environment, you need to test the code with sample data

One method to determine test data is to come up with a spreadsheet with a list of all sible values, or ranges of values, and then manually calculate the output The whole pur-

pos-pose of programming is to work with the inputs, and output the desired results Use test

data that might not be used currently in the system, but that could possibly be entered bythe user, and so on For example, if a program uses only positive numbers, enter a nega-tive number as test data In addition to testing the unusual cases, your test environmentshould also include a reasonable volume of typical production data

Setting up test data and testing all possible outcomes is critical in debugging any tion A major advantage of having a predefined test environment is that it allows you todocument a series of tests and repeat them each time you modify your code Taking a lit-tle extra time to do thorough testing will benefit you greatly down the road

Trang 6

applica-Narrowing Down the Location of a Bug

Suppose you encounter a case in which outputs do not match the desired output Whatsteps do you take next? No matter what, you need to narrow down the search area, espe-cially because large-scale applications have millions of lines of code The steps I wouldtake to troubleshoot for a logic error bug are as follows:

1 Determine the overall process

2 Determine where, when, and how frequently the error occurs

3 Determine what outputs are invalid

4 Determine what inputs and calculations make up those outputs

5 Determine what does work (This question can help in determining the cause.)

6 Define the problem

7 Trace inputs, intermediate computations, and outputs

8 Step away from the problem

9 Ask for help Software bugs have been discovered this way!

10 Document the solution

The next few sections talk briefly about each of these steps

Determining the Overall Process

Before you can troubleshoot, you should have some idea of the overall process and how

it relates to the business If you have no reinsurance knowledge, it will make shooting a reinsurance application much more difficult If you have been called in totroubleshoot someone else’s problem, take time to learn the nature of the processesinvolved Often that can help you more quickly focus on the specific module of code that

trouble-is causing the trouble

Determining Where, When, and How Frequently the Error Occurs

You should know where in the system the problem is occurring What forms areinvolved? What data is involved? When does the problem occur and how frequently?Every time a user clicks the Send button? Every time a form is saved and the data isinserted into the table? Only when uniform #23 is inserted into the basketball database?Finding the answers to all these questions will help to determine the root problem

Determining What Outputs Are Invalid

When attempting to define the problem, if it is not a systems crash but an error on put, attempt to define all outputs that are invalid Such questions for a banking industrycould be: Which accounts get a service fee when they are not supposed to? How much is

Trang 7

the service fee? (You can use this information to see which variable references this value

in a table.) How often does the error occur? What was the last transaction that occurredbefore the service fee? (Perhaps a trigger is causing the problem when updating thetable.) What date does the error occur? (If the date is fixed, this will help to narrow downthe problem area.) In reality, there should be no random problems, even though the prob-lems might initially seem random You should eventually see a pattern evolve, which willlead you to the problem

Determining What Inputs and Calculations Make Up Those Outputs

If you know a bank fee is accessed, for example, you should begin researching the ules, programs, triggers, procedures, and so on that are involved with processing that fee

mod-What tables do your inputs come from? Knowing the specific program elements involvedcan help you trace the problem more effectively

Determining What Does Work

Asking the question “What does work?” might seem like an odd idea, but believe it ornot, it is very effective If you suspect that a procedure is bad, because the data you pass

to the procedure is not processing properly, check the other modules that access this cedure If they all have the same problem, it is the module If all of them process proper-

pro-ly, and you pass the same number of parameters, maybe it is something in your module

If the range of values you pass is different than that of the other modules accessing theprocedure, it could be an out-of-range error in the procedure

Defining the Problem

Usually, defining the problem is the most difficult part If you have worked your waythrough proper troubleshooting and the asking of questions, you should now be able todetermine the root cause of the problem, and where to start your search to fix the prob-lem Many people try to define the problem first, and take away the symptoms with

“workaround” coding rather than find the true root cause, which could resurface at anytime

Tracing Inputs, Intermediate Computations, and Outputs

To help narrow down a problem to a specific module, and then to specific lines of codewithin that module, you can use the DBMS_OUTPUTpackage to output the values of keyvariables as the code executes You can also write a debugging package—as you’ll seelater in this lesson—to log this information to a text file or a database table Writingdebug output to a file eliminates the problem of having it scroll off the screen too quick-

ly, and also prevents display forms from being overwritten

Trang 8

Stepping Away from the Problem

Have you ever had the solution to the problem stare you in the face but you did not seeit? All too often, we get so involved in trying to find and eliminate the bug that we gettoo frustrated and start to repeat steps that we have already eliminated

When faced with a situation like this, it often helps to take a break and get away from theproblem If whatever you’re doing now isn’t working, your whole approach to the prob-lem may be flawed You may need to give your subconscious mind some time to come

up with a fresh approach So instead of working late, beating your head against the wall,and frustrating yourself, go home In the morning, you may find that you’ve thought up afresh approach, or you may even “see” the solution that you missed the night before

Asking for Help

If after you examine the code, it appears that you have followed all punctuation and tax rules, and you have a complete understanding of the function package, procedure,and so on, don’t be afraid to ask another consultant or programmer for help Sometimes

syn-an extra set of eyes csyn-an pinpoint the problem In addition, you might learn some new tipsand tricks to speed up development or troubleshooting the next time around

Documenting the Solution

You should document the solution, on paper, in the program (if possible), and ideally in

an Oracle database of troubleshooting solutions This will help you if the problem reoccurs and you can’t remember what you did to fix it Also, if you do this, you are onyour way to building an expert system that might be of some value to other clients or endusers This is probably one of the most important processes you should complete afteryou have solved the problem If you’re too busy to document right after solving the prob-lem, you might live to regret the decision if a similar error occurs and you have to spendmore time trying to solve the problem again Make the time!

Using Tools to Help in Debugging a Program

Tools can be an invaluable debugging aid, especially if you have access to a source codedebugger Historically, this has not been one of PL/SQL’s strong points Oracle doesn’tsupply a debugger at all for server-level stored procedures and triggers Developer 2000,

a client-side development tool, does include debugging capabilities There are also somethird-party tools on the market, many of which are mentioned on Day 1, “Learning theBasics of PL/SQL.”

A good debugging tool will allow you to step through the execution of a procedure or afunction one line at a time, examining variables as you go This enables you to quicklypinpoint most problems If you don’t have a debugging tool available, there are still a

Trang 9

couple things you can do The DBMS_OUTPUTpackage can often be used to good effect

You can use it to display the values of key variables as a procedure executes If you want

to get a bit more involved, you can create a simple debugging package to log debuggingmessages to a disk file

TheDBMS_OUTPUTpackage is described in great detail on Day 17, “Writing to Files andthe Display.” This package will either pass information to a buffer that can be retrieved,

or it can display information to the screen (When debugging a process, if I use

DBMS_OUTPUT, I almost always output to the screen.)The primary use for DBMS_OUTPUTwhen debugging is to display the values of key vari-ables as a procedure or function executes This is a time-honored approach to debugging

The key is to display information that will allow you to narrow down the focus of yoursearch For example, if you display a critical variable before and after a function call, andthe value was correct before the call but incorrect afterward, you should focus yourfuture efforts on the code that you called

If you are using SQL*Plus to compile procedures in the database, you must issue the lowing command in order to see any output:

fol-SET SERVEROUTPUT ON

To disable sending output to the screen, you would turn off SERVEROUTPUT, like this:

SET SERVEROUTPUT OFF

If you use DBMS_OUTPUTas a debugging tool, and you are debugging server code by usingSQL*Plus, don’t forget to turn on SERVEROUTPUT

DBMS_OUTPUTis nice if you are debugging a procedure or function that you can invokefrom SQL*Plus However, if you need to run a client-side program in order to debug theinteraction between that program and the stored procedure, you won’t be able to useSQL*Plus to view the output In such a case, you might want to consider creating a sim-ple debugging package to log debug messages to a file One such implementation isshown in Listings 13.3 and 13.4 This DEBUGpackage allows you to do just two things:

• Take the system date and time, comments, and the contents of a variable, and writethese to a file while the program executes

• Reset the file (erase the file) to start a new debugging run

INPUT

INPUT

Trang 10

The statement in Listing 13.3 creates the package header, which defines the proceduresavailable within the package.

1: CREATE OR REPLACE PACKAGE DEBUG AS 2: /* Procedure OUT is used to output a comment of your 3: choice, along with the contents of the variable The 4: Procedure OUT statement defines the format of the function */

5: PROCEDURE OUT(p_Comments IN VARCHAR2, p_Variable IN VARCHAR2);

6:

7: /* Procedure Erase is used to erase the contents of the file.

8: Used to start a new debugging process Good idea to call 9: this function first */

initializa-UTL_FILE package.

Note

1: CREATE OR REPLACE PACKAGE BODY DEBUG AS 2: PROCEDURE OUT(p_Comments IN VARCHAR2,p_Variable IN VARCHAR2) IS 3: v_MyFHOUT UTL_FILE.FILE_TYPE; Declare File Handle 4: BEGIN

5: /* Use A to append all output being sent to the file */

13:

INPUT

Trang 11

15: TO_CHAR(SYSDATE,’mm-dd-yy HH:MM:SS AM’) 16: || ‘“,”Comment: ‘ || p_Comments ||

24: WHEN OTHERS THEN 25: DBMS_OUTPUT.PUT_LINE 26: (‘ERROR ‘ || to_char(SQLCODE) || SQLERRM);

27: NULL; Do Nothing 28: END OUT; End Execution of Procedure OUT 29:

30:

31: PROCEDURE Erase IS 32: v_MyFH UTL_FILE.FILE_TYPE; Create File Handle 33: BEGIN

34: /* Open file to overwrite current file contents Doing this 35: erases the contents of the original file completely */

45: DBMS_OUTPUT.PUT_LINE 46: (‘ERROR ‘ || to_char(SQLCODE) || SQLERRM);

47: NULL;

48: END Erase; End Procedure Erase 49:

50: BEGIN 51: Erase; Erase contents of the file 52:

53: END DEBUG; End procedure DEBUG 54:/

Package body created.

You can now examine the components of the newly created DEBUGpackage

TheDEBUG.OUT Procedure

TheDEBUG.OUTprocedure enables you to log debugging messages to a file called

debug.txt The procedure automatically includes the system date and time with each

OUTPUT

Trang 12

message The procedure accepts two parameters: a debug message and the variable youare tracking Each time you call it,DEBUG_OUTappends the message and the value of thevariable to the file named debug.txt.

TheDEBUG.ERASE Procedure

TheDEBUG.ERASEprocedure erases the contents of the debug.txtfile by opening a dle to the file in replace mode (‘W’) and then closing the file This process creates anempty file You should make at least one call to DEBUG_ERASEat the start of each debug-ging run to ensure that you start with a clean file

One possible use for the DEBUGpackage is to log the inputs and outputs from a functionthat you are testing Listing 13.5 shows a function representing a variation on Oracle’sbuilt-in ADD_MONTHSfunction This function is named ADD_MON, and includes calls to

DEBUG.OUTto log both the input date and the date that it returns

1: CREATE OR REPLACE FUNCTION add_mon (date_in DATE, 2: months_to_add NUMBER) 3: RETURN DATE AS

4: /*Similar to the built-in ADD_MONTHS, but this function 5: leaves the date alone as much as possible The day is only 6: adjusted if it is out of range for the new month.*/

28: IF day_in = day_work THEN

INPUT

Trang 13

34: END IF;

35:

36: Return the new date to the caller.

37: debug.out (‘DATE_OUT = ‘, 38: TO_CHAR(date_out,’yyyy mm dd hh mi ss’));

in the log to verify that the results are what you expect

Listing 13.6 shows a test run being made on the ADD_MONfunction

11: 4 FROM dual;

12:

13: TO_CHAR(ADD 14: - 15: 31-MAR-2000 16:

ANALYSIS

I NPUT /

O UTPUT

continues

Trang 14

23: 4 FROM dual;

24:

25: TO_CHAR(ADD 26: - 27: 29-MAR-2000 28:

29: SQL>

30: SQL> SELECT TO_CHAR(

31: 2 ADD_MON(TO_DATE(‘15-FEB-2000’,’DD-MON-YYYY’),1), 32: 3 ‘DD-MON-YYYY’)

33: 4 FROM dual;

34:

35: TO_CHAR(ADD 36: - 37: 15-MAR-2000 38:

39: SQL>

40: SQL> SELECT TO_CHAR(

41: 2 ADD_MON(TO_DATE(‘31-JAN-2000’,’DD-MON-YYYY’),1), 42: 3 ‘DD-MON-YYYY’)

43: 4 FROM dual;

44:

45: TO_CHAR(ADD 46: - 47: 29-FEB-2000

Line 1 contains a crucial call to DEBUG.ERASE This call creates an empty

debug.txtfile for use by subsequent calls to DEBUG.OUT Lines 6–15 demonstratehow the built-in ADD_MONTHSfunction operates Because the input date 29-Febrepresent-

ed the last day of the month, the output date was adjusted so that it also represented thelast day of the month Instead of returning 29-Mar,ADD_MONTHSreturned31-Mar Lines18–27 demonstrate how ADD_MON’s behavior is different ADD_MONadds one month, butpreserves the day, resulting in the value 29-Mar The remaining lines test some othercases that ADD_MONmust handle correctly

Having executed these tests, you’ll find that the debug.txtfile contains these entries:

Trang 15

to reduce the amount of code to sort through when a problem occurs, but to be able toreuse those modules in the future.

Defining Requirements and Planning Projects

When you develop a new application, you should spend a significant amount of timedefining the requirements of the users Not only does this require some knowledge of thebusiness, but it should cover all possible input and desired output scenarios Someoneknowledgeable in the industry should verify all calculations What do you gain by sittingwith the end users and verifying the application? You begin to understand the businessand its needs, and you might be able to make suggestions that could aid in decision-making processes, reduce work time for manual processing, improve productivity, and so

on Not only that, it is easier to troubleshoot the system and identify problems before theapplication is placed in production I can’t stress enough how important it is to under-stand and plan for the application in the beginning: Doing so will save you a lot of timeand aggravation at the tail end of the project

Always verify your understanding of the requirements with the business users of the system Tell them what you think you heard them say in the first place Make sure that they agree that you have a correct understanding of the problem at hand.

Trang 16

Using a Modular Approach to Coding

When developing your applications, you should take a modular approach to make ging easier This also gives you the added benefit of creating reusable code For instance,

debug-in a payroll application, you could design modules to do the followdebug-ing:

• Calculate gross wage

• Calculate FICA

• Calculate federal withholdings

• Calculate state withholdings

• Withhold for benefits such as flexible spending or insurance

If a problem occurs that is related to gross wages, you can easily narrow down whichprocedure(s) is broken and then fix the bug In addition, modules have another importantaspect: You can test the modules independently of one another

Commenting Code

One of the greatest benefits you can provide for yourself and other Oracle developers is

to liberally comment your code Although you could provide documentation manuals, inpractice these manuals tend to get “misplaced” in almost every environment Addingcomments to your code will help, whether you are trying to debug the application or sim-ply modifying the application to meet new requirements

Proper labeling of variables is also important Poorly worded variables confuse the oper and waste valuable time for people who are trying to follow the logic of the pro-gram Listing 13.7 reflects code that can be very confusing at first glance

1: CREATE OR REPLACE FUNCTION RAISE(

2: p1 INTEGER, 3: p2 NUMBER) 4: RETURN NUMBER IS 5: p3 NUMBER;

6: BEGIN 7: IF p1 = 1 THEN 8: p3 := p2 * 1.10;

9: ELSIF p1 = 2 THEN 10: p3 := p2 * 1.05;

11: ELSIF p1 = 3 THEN 12: p3 := p2 * 1.04;

13: ELSIF p1 = 4 THEN 14: p3 := p2 * 1.03;

15: ELSIF p1 = 5 THEN 16: p3 := p2 ;

INPUT

Trang 17

17: ELSE 18: p3 := p2 * 1.02;

19: END IF;

20: RETURN p3; 21: END RAISE;

22: /

A quick glance at this code shows that there are no comments, and that the able names are not mnemonic In order to follow the code, you would have tofirst determine what p1,p2, and p3are You also do not know what the function raises:

vari-An hourly pay rate? The cost of benefits? Someone’s GPA? The elevation of a buildingunder construction?

Raise can mean many things, so a clarification is very important The same code is

pro-vided again in Listing 13.8, with comments that easily clarify the function

1: CREATE OR REPLACE FUNCTION RAISE(

2: p_paylevel INTEGER, parameter for input of raise level 3: p_payrate NUMBER) parameter for input of pay rate 4: /* The purpose of this function is to calculate ANNUAL raises 5: for all of the hourly employees, based upon their raise level 6: values 1-4 and all others */

14: IF p_paylevel = 1 THEN 15: v_newrate := p_payrate * 1.10; Promotion Raise 16: ELSIF p_paylevel = 2 THEN

17: v_newrate := p_payrate * 1.05; Exceeds Rate 18: ELSIF p_paylevel = 3 THEN

19: v_newrate := p_payrate * 1.04; Hi Meets Rate 20: ELSIF p_paylevel = 4 THEN

21: v_newrate := p_payrate * 1.03; Meets Rate 22: ELSIF p_paylevel = 5 THEN

23: v_newrate := p_payrate ; Consultants who get no raise 24: ELSE

25: v_newrate := p_payrate * 1.02; All Others 26: END IF;

27: RETURN v_newrate; Returns new paylevel rate to procedure 28: END RAISE;

29: /

ANALYSIS

INPUT

Trang 18

You can now follow the function, its purpose, what the variables are, and anymodifications made at a later date What a difference commenting and propernaming of variables makes!

Writing Assertions into Code

An assertion, in programming terms, is a test for a fact that should be true.

Assertions serve several functions Their primary function is to prevent errorsfrom propagating further downstream in a process Say you had a function that was neversupposed to return a negative value You could actually place a check in your function to

be sure that a negative value is never accidentally returned Listing 13.9 shows oneapproach that you might take to this problem

1: CREATE OR REPLACE FUNCTION do_calc 2: RETURN NUMBER AS

3: return_value NUMBER;

4: BEGIN 5:

6:

7: IF return_value < 0 THEN 8: RAISE_APPLICATION_ERROR ( 9: -20000,’DO_CALC: Negative value returned.’);

A test like the one shown in Listing 13.9 is an assertion Should you make a mistakecoding the DO_CALCfunction, or should some future maintenance programmer induce anerror, the assertion would fire, and you would immediately be alerted to the problem.Assertions also, in a manner of speaking, serve as a form of documentation to futuremaintenance programmers They are like a comment, but with a loaded gun

Coding assertions as shown in Listing 13.9 isn’t too practical You don’t have any centralcontrol over whether they fire, and you can’t make global changes to their behavior Amore robust approach is to create a procedure such as the one shown in listing 13.10

ANALYSIS

N EW T ERM

INPUT

ANALYSIS

Trang 19

1: CREATE OR REPLACE PROCEDURE ASSERT ( 2: condition IN BOOLEAN,

3: message IN VARCHAR2) AS 4: BEGIN

5: IF NOT condition THEN 6: RAISE_APPLICATION_ERROR (-20000,message);

DO_CALCfunction in Listing 13.9

1: CREATE OR REPLACE FUNCTION do_calc 2: RETURN NUMBER AS

3: return_value NUMBER;

4: BEGIN 5:

for-• For each new block of code, indent two to five spaces

• Use uppercase for keywords

• Use mixed case for variable names

• Precede variable names with a v_for variable,p_for parameters, and so on

• Use one statement per line

INPUT

INPUT

ANALYSIS

ANALYSIS

Trang 20

Using Proper Indentation

Every time you start a new block of code, such as a loop, an IFstatement, or a nestedblock, you should indent to make the code more readable Listing 13.12 shows an exam-ple of poorly indented code

1: DECLARE 2: v_MyNumber NUMBER := 0;

3: BEGIN 4: LOOP 5: IF v_MyNumber > 7 THEN 6: EXIT;

If you reformat the code as shown in Listing 13.13, you can follow the program moreeasily

1: DECLARE 2: v_MyNumber NUMBER := 0;

3: BEGIN 4: LOOP 5: IF v_MyNumber > 7 THEN 6: EXIT;

7: v_MyNumber := v_MyNumber + 2;

8: END LOOP;

9: END;

10: /

Not only is the code now easier to read, but the indentation makes it obvious that

anENDIFstatement is missing after line 6

INPUT

ANALYSIS

INPUT

ANALYSIS

Trang 21

Using Uppercase for Keywords

Using uppercase for reserved words or functions helps to distinguish between regularcode and Oracle-provided code If a keyword is misspelled, you can easily spot the prob-lem All the listings that you have seen in this book have capitalized SQL and PL/SQLkeywords The code in Listing 13.14 shows how less readable code can become if youdon’t do this

1: declare 2: v_mynumber number := 0;

3: begin 4: loop 5: if v_mynumber > 7 then 6: exit;

dif-Using Mixed Case for Variable Names

To identify code, output, keywords, or variable names, you can easily distinguish able names by using mixed case By using MyVariable, for example, you can pick thevariable name out faster than you could pick out myvariableorMYVARIABLE

By preceding variables with a first letter and an underscore, you can quickly identifyvariables and their type One possible scheme is to use v_for regular variables,p_forparameters, and so forth That way, you know at glance whether you are dealing with aregular variable, a parameter, or another specific kind of variable

Using One Statement per Line

Because the semicolon (;) is used to terminate a statement, you could easily have ple statements on one line For instance, you could code something like this:

multi-y := ‘’; x :=1;

LOOP x := x+1; y := y+’ ‘; if x=10 THEN EXIT; END IF; END LOOP;

INPUT

ANALYSIS

Trang 22

Although this code is syntactically correct and will execute, you’ll run into trouble if youtry to troubleshoot it or comment out a statement that might be causing the error Thecode would be much easier to follow if you formatted it like this:

Q What can I use to debug applications?

A UsingDBMS_OUTPUTto display the values of key variables is one method of ging You can also create your own debugging package to log debugging messages

debug-to a file

Trang 23

Q If all operations are on the same level, how does Oracle know which tions to process first?

calcula-A If all calculations are at the same level, the order of evaluation is from left to right.

Q What simple punctuation can easily override the natural order of operations?

A Parentheses () Operations in parentheses are evaluated first, and the results areused in the rest of the expression

Q Are comments needed in an application if you have sufficient separate documentation?

A Yes, absolutely Documentation tends to get misplaced or never gets updated when

a coding change is made You should document not only what each procedure,function, and trigger does, but also document changes and updates as they occur

Q Must we really document solutions to problems?

A Documenting solutions to problems helps you troubleshoot similar problems that

occur in the future

Q Why does proper formatting help in debugging code?

A Proper formatting allows you to view code quickly and assess what the code is

doing If you do not line up END IFstatements when you are nesting IF THEN

clauses, it is difficult to see when the first statement ends, the second ends, and soforth

1 True or False: Logic errors are easier to debug than syntax errors

2 Missing a semicolon is what type of an error?

3 Provide the answer to the calculation 6 + 4 / 2 = ?

4 True or False: Commenting code is a waste of time

5 True or False: Formatting code is not necessary

Trang 24

TheDEBUGpackage in this lesson always writes debugging messages to the file named

debug.txt That will cause problems if multiple developers use the package at once.Modify the DEBUGpackage as follows:

• Modify the ERASEprocedure to accept a filename This filename will be used bysubsequent calls to the OUTprocedure

• Modify both the OUTandERASEprocedures so that if no filename is passed, or if

ERASEis never called, no file is created and no messages get written

For extra credit, add an ASSERTprocedure to the DEBUGpackage, and build in a flag sothat you can enable and disable assertions at will

Trang 25

les-DBMS_LOBpackage Today’s lesson focuses on the following topics:

• Defining large objects

• Using the DBMS_LOBpackage with external files

• Understanding locators

• Using the DBMS_LOBpackage with internal files

Ngày đăng: 15/12/2013, 05:15

TỪ KHÓA LIÊN QUAN