You are on page 1of 35

Ten Things You Should NEVER Do With PL/SQL

Steven Feuerstein
PL/SQL Evangelist Quest Software steven.feuerstein@quest.com
Copyright 2006 Steven Feuerstein - Page 1

And Oracle says....


ANYTHING STEVEN SAYS ABOUT Oracle 11g "is intended to outline Oracle's general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracle's products remains at the sole discretion of Oracle.
Copyright 2006 Steven Feuerstein - Page 2

Eleven Years Writing Ten Books on the Oracle PL/SQL Language

Copyright 2006 Steven Feuerstein - Page 3

How to benefit most from this presentation

Watch, listen, ask questions. Download the training materials and supporting scripts: http://oracleplsqlprogramming.com/resources.html "Demo zip": all the scripts I run in my class available at http://oracleplsqlprogramming.com/downloads/demo.zip
filename_from_demo_zip.sql

Use these materials as an accelerator as you venture into new territory and need to apply new techniques.
Copyright 2006 Steven Feuerstein - Page 4

Ten things you should never do with PL/SQL 1. Never ask for help 2. Never skip the coffee. 3. Never share what you learn. 4. Never doubt the gurus. 5. Never hide the details in your code. 6a. Never let anyone else read your code. 6b. Never read someone else's code. 7. Never worry about tomorrow. Code for today. 8. Never fix bugs that users haven't found. 9. Never assume an Oracle bug will be fixed. 10. Never say never.

Copyright 2006 Steven Feuerstein - Page 5

1. Never ask for help.


Software programmers are highly educated and very smart people. We are expected to have all the answers and maintain total control over The Machine. If we ask for help, we show weakness. If we ask for help, we lose the respect of our peers. Oh, all right.
Copyright 2006 Steven Feuerstein - Page 6

ALWAYS ask for help!


By asking others for help, you make them feel good, strengthening the team. By asking for help, you solve your problems sooner. Leave ego out of programming! I suggest that you follow the 30 Minute Rule:

If you cannot fix the problem in 30 minutes, ask for help.


Copyright 2006 Steven Feuerstein - Page 7

2. Never skip the coffee.


Without coffee (and its close cousins, Diet Coke and Red Bull), the world of programming would crumble.
Gone is our creativity, discipline and motivation.

Coffee helps us focus, improves our productivity, and gives us an excuse to get up from our desks.
And actually talk to other human beings.

Oh, all right.


Copyright 2006 Steven Feuerstein - Page 8

ALWAYS skip the coffee.


Wait, don't leave! OK, don't go cold turkey on caffeine. But drink lots (and lots more) water.
Coffee dehydrates you and a dehydrated brain just doesnt work as effectively.

Generally, we need to take care of our host body, so that our brain can keep on earning that big fat paycheck!
Stretch, exercise, take frequent breaks, and so on.
Copyright 2006 Steven Feuerstein - Page 9

3. Never share what you learn.


Knowledge is power and leads to higher consulting rates. If someone takes your code and tries to use it, they will probably just mess it up. Who has the time to let anyone else know about the great stuff you've been doing? What's in it for me? Oh, all right.
Copyright 2006 Steven Feuerstein - Page 10

ALWAYS share what you learn.


Give and ye shall receive. No human is an island. Don't repeat history. Etc. OUGs are a great sharing mechanism, but we need to instill sharing in our every day perspective on our work. Set up mechanisms for sharing within your team and your company. And only share what is legally yours to share.
Copyright 2006 Steven Feuerstein - Page 11

Free resources for PL/SQL developers


Oracle Technology Network PL/SQL page
http://www.oracle.com/technology/tech/pl_sql/index.html

OTN Best Practice PL/SQL


http://www.oracle.com/technology/pub/columns/plsql/index.html

Oracle documentation
http://tahiti.oracle.com/

OraclePLSQLProgramming.com my PL/SQL portal


http://oracleplsqlprogramming.com/

Quest Pipelines
http://quest-pipelines.com/

Quest Code Tester for Oracle


http://www.unit-test.com or http://unittest.inside.quest.com/index.jspa

PL/Vision
http://quest-pipelines.com/pipelines/dba/PLVision/plvision.htm
Copyright 2006 Steven Feuerstein - Page 12

4. Never doubt the gurus.


Surely if a person has written a book on a subject, they should not be challenged. If everyone questions the gurus and experts, then the common, everyday programmer will be lost.
How can you write code without someone telling you what is right and what is wrong?

Oh, all right.


Copyright 2006 Steven Feuerstein - Page 13

ALWAYS challenge the gurus.


Not here, not now , but otherwise. You need to take the advice of experts with a grain of salt.
What worked for him or her, may not work for you in your environment, version, operating system, etc. Especially when they appear in books that may be out of date.

Yet another motivation to encapsulate. And if a "guru" is not ready to learn from others or admit that they made a mistake, you are best off ignoring them in the future. show_memory.sp
Copyright 2006 Steven Feuerstein - Page 14
plvtmr.pkg tmr.ot emplu.pkg

5. Never hide the details in your code.


Hiding isn't very friendly and aren't we supposed to share? If you hide details of your implementation, then people who debug your code have more trouble finding the lines causing the problem. Hiding details means taking time away from the critical task of implementing business requirements. Oh, all right.
Copyright 2006 Steven Feuerstein - Page 15

ALWAYS hide the details in your code.


Humans can only handle so much complexity at once. Information hiding encourages reuse. Aim for a Single Point of Definition (SPOD).
Avoid hard-coded declarations and literal values. Hide business rules and formulas in functions.

Can you go overboard with "hiding"?


I suppose so, but it isn't exactly the biggest problem we face.
Copyright 2006 Steven Feuerstein - Page 16

Nicely exposed code?


The following block of code is easy to understand.
But what price is paid?
CREATE OR REPLACE PROCEDURE process_employee ( employee_id_in IN number) IS l_name VARCHAR2(100); BEGIN SELECT last_name || ',' || first_name INTO l_name FROM employee WHERE employee_id = employee_id_in; ... END;
Copyright 2006 Steven Feuerstein - Page 17

Lets SPODify some code...


CREATE OR REPLACE PROCEDURE process_employee ( employee_id_in IN number) IS l_name VARCHAR2(100); BEGIN SELECT last_name || ',' || first_name INTO l_name FROM employee WHERE employee_id = employee_id_in; ... END; CREATE OR REPLACE PACKAGE employee_rp AS SUBTYPE fullname_t IS VARCHAR2 (200); -- The formula FUNCTION fullname ( l employee.last_name%TYPE, f employee.first_name%TYPE ) RETURN fullname_t; -- Retrieval function FUNCTION fullname ( employee_id_in IN employee.employee_id%TYPE ) RETURN fullname_t; END;

l_name employee_rp.fullname_t; BEGIN l_name := employee_rp.fullname ( employee_id_in); ... END; Copyright 2006 Steven Feuerstein - Page 18

And more spodification: error handling


WHEN NO_DATA_FOUND THEN INSERT INTO errlog VALUES ( SQLCODE , 'No company for id ' || TO_CHAR ( v_id ) , 'fixdebt', SYSDATE, USER ); WHEN OTHERS THEN INSERT INTO errlog VALUES (SQLCODE, SQLERRM, 'fixdebt', SYSDATE, USER ); RAISE; END;

Hard-coded, exposed, clunky, redundant.

or...
EXCEPTION WHEN NO_DATA_FOUND THEN errpkg.record_and_continue (SQLCODE, ' No company for id ' || TO_CHAR (v_id)); WHEN OTHERS THEN errpkg.record_and_stop; END; Quest CodeGen Utility's error management framework www.qcgu.net Copyright 2006 Steven Feuerstein - Page 19

Declarative, hidden, flexible, productive.

Always use the highest level construct available.

Another variation on this theme. Stay as far away from the "physical" details as possible. A great example of this is the cursor FOR loop.
Write less code, simply describing the action desired ("Fetch every row in this cursor."). And Oracle can then automatically optimize the code!
Oracle Database 10g_optimize_cfl.sql

Copyright 2006 Steven Feuerstein - Page 20

6a. Never let anyone else read your code.

You spent a lot of time learning in depth the requirements. You expended major effort getting everything just right. You're the expert, and you like being the expert. Let your co-workers go find their own area of expertise.
There are no free lunches nor free rides in programming. So there.
Copyright 2006 Steven Feuerstein - Page 21

6b. Never read someone else's code.


That's just plain rude. Your co-workers already know the best way to do everything.
What could they possibly learn from you?

You already know the best way to do everything.


What could you possibly learn from a co-worker's code?

Oh, all right.


Copyright 2006 Steven Feuerstein - Page 22

ALWAYS look at others' code and ask others to look at yours. Code review is a proven method of improving code quality and reducing bugs. If you think you can't learn from others, then you are arrogant, probably quite hard to work with, and eagerly left out of code reviews. Go extreme? XP pair programming... Automate code review.
Toad's CodeXpert Other IDEs do lint checking Oracle PL/SQL built-in compile-time warnings framework
Copyright 2006 Steven Feuerstein - Page 23

7. Never worry about tomorrow. Code for today!

Who's got time to think about tomorrow, anyway?


I am too busy dealing with the bugs in front of my nose.

I am just building a throw-away prototype.


They're never going to actually use this stuff in production.

Version 1 is going to be completely rewritten for Version 2.


Lets just knock this together and get it out the door.

Oh, all right.


Copyright 2006 Steven Feuerstein - Page 24

ALWAYS code for tomorrow.


Our programs will be around for years.
Critical to make our code readable, maintainable and testable.

Set clear standards before starting.


How and where will SQL statements be written? Provide a standard error mgt API to all developers. Build instrumentation (tracing) into you code.

But don't build programs that you think maybe someday another person may need.
That just leads to code bloat.
Copyright 2006 Steven Feuerstein - Page 25

High level checklist for "coding for tomorrow"

Don't write SQL in the application layer.


Generate table APIs and other elements. Make sure there are no repetitions of the same logical statement.

Use a standard error mgt package. Add tracing calls to critical, complex parts of your application. Standardize block structure and headers. Build strong regression tests.
Copyright 2006 Steven Feuerstein - Page 26
Quest CodeGen Utility www.qcgu.net Quest Code Tester www.quest.com/code-tester-for-oracle

8. Never fix bugs that users haven't found.

Doing things "just because" can be a real time waster.


Why spend lots of time and effort fixing bugs that the users may never even find?

Just in time bug fixing the way to go!


Get applications in users' hands rapidly. Stand ready to fix bugs really, really fast. And everyone is happy.

Oh, all right.


Copyright 2006 Steven Feuerstein - Page 27

ALWAYS test proactively and thoroughly.

Yeah, yeah, yeah. Big news. Of course! The question is how to do it.
We need a test repository, automated run and results verification

You need better toolsand the choices are limited but getting very, very exciting!
utPLSQL - http://utplsql.sourceforge.net/ PLUnit - http://www.apollo-pro.com/help/pl_unit.htm Quest Code Tester for Oracle www.ToadWorld.com or http://unittest.inside.quest.com/index.jspa
Copyright 2006 Steven Feuerstein - Page 28

9. Never assume an Oracle bug will be fixed.

A bug today is a bug tomorrow.


Everything else is wishful thinking.

I don't have time to do anything but find a solution and keep on moving. I will leave it to my descendents to sort it all out. Oh, all right.

Copyright 2006 Steven Feuerstein - Page 29

ALWAYS assume a bug will be fixed.


Let's be positive, shall we? Avoid mythological code whenever possible.
"Once upon a time, there was a bug."

When you need a workaround


Encapsulate the workaround; Document the workaround; Include explanation of how to remove the workaround when the bug is fixed.

Let's look at an example: "Does a file exist?"


Copyright 2006 Steven Feuerstein - Page 30

Does a file exist?


The UTL_FILE.FGETATTR program does the trick. Or does it?
DECLARE TYPE fgetattr_t IS RECORD ( fexists BOOLEAN , file_length PLS_INTEGER , block_size PLS_INTEGER ); fgetattr_rec fgetattr_t; BEGIN UTL_FILE.fgetattr (LOCATION , filename , fexists , file_length , block_size ); IF fgetattr_rec.fexists THEN ... END; Copyright 2006 Steven Feuerstein - Page 31

Unfortunately, there is/was a bug: In Oracle 9iR2, the fexists parameter is always set to TRUE, whether or not the file exists.

=> => => => =>

'TEMP' 'trace.log' fgetattr_rec.fexists fgetattr_rec.file_length fgetattr_rec.block_size

Quick! Share that knowledge!


I could send an email to our entire team, explaining the problem and providing the code they should use instead. But if everyone puts the fix/workaround in their code, how can we ever go back and back out the workaround when the problem is fixed? Plusmany times, workarounds no longer work in patched versions of software.
Copyright 2006 Steven Feuerstein - Page 32

A workaround for fgetattr


Here is an alternative: provide the workaround to everyone in the form of a function.
... /* Document the workaround, including the bug number. WORKAROUND START 2174036 fexists is always returned TRUE, but non-existent file has ZERO file_length and block_size */ IF fgetattr_rec.file_length = 0 AND fgetattr_rec.block_size = 0 THEN RETURN FALSE; ELSE RETURN TRUE; END IF; /* WORKAROUND END 2174036 */

Include the code to be used when the workaround is no longer necessary.

/*

WORKAROUND FIX 2174036 When the bug is fixed, remove the IF statement and uncomment this: RETURN fgetattr_rec.fexists; */ END fexists; Copyright 2006 Steven Feuerstein - Page 33

10. Never say never.


The only sentences in which the words "never" and "always" should be mentioned in regards to code are:

Things will never stay the same.


Things will always be changing.
Anything else is a bug in the making!
Copyright 2006 Steven Feuerstein - Page 34

ODTUG Kaleidoscope
June 18 21, 2007 Hilton Daytona Beach Oceanfront Resort Daytona, Florida

Featuring the world's SECOND PL/SQL Test a Thon! The ODTUG Seriously Practical Oracle PL/SQL Programming Conference The Second OPP 2007 of the year will be held in NYC this Fall.
And we will hold a test-a-thon there as well. For more information visit www.odtug.com, www.odtugopp.com or call 910-452-7444
Copyright 2006 Steven Feuerstein - Page 35

You might also like