msgbartop
News, views, tips and tricks on Oracle and other fun stuff
msgbarbottom

SQL*Plus Timers

SQL*Plus TIMING is a handy little utility that you can use to do a performance analysis on any commands or blocks run during a period. It is different from the SET TIMING command which is used to display timing data after each SQL command or PL/SQL block you run.

Here is an example:

TIMING SHOW lists the current timer’s name and timing data:

SQL> timing show
SP2-0325: no timing elements to show

TIMING START sets up a timer and makes t1 (or whatever timer name you like) the name of the timer:

SQL> timing start t1
SQL> timing show
timing for: t1
Elapsed: 00:00:06.95

Another call to TIMING SHOW displays the elapsed time since the start of the timer:

SQL> timing show
timing for: t1
Elapsed: 00:00:16.01

You can have more than one active timer by STARTing additional timers before STOPping the first; SQL*Plus nests each new timer within the preceding one. The timer most recently STARTed becomes the current timer:

SQL> timing start t2

t2 is the current timer now:

SQL> timing show
timing for: t2
Elapsed: 00:00:02.25

TIMING STOP lists the current timer’s name and timing data, then deletes the timer. If any other timers are active, the next most recently STARTed timer becomes the current timer, in this example it’s t1:

SQL> timing stop
timing for: t2
Elapsed: 00:00:18.81
SQL> timing show
timing for: t1
Elapsed: 00:01:14.18
SQL> timing stop
timing for: t1
Elapsed: 00:01:22.09
SQL> timing show
SP2-0325: no timing elements to show

TIMING with no clauses lists the number of active timers:

SQL> timing
no timing elements in use    
SQL> timing start t1
SQL> timing
1 timing element in use
SQL> timing start t2
SQL> timing
2 timing elements in use

CLEAR TIMING deletes all timers:

SQL> clear timing
timing for: t2
Elapsed: 00:22:38.36
timing for: t1
Elapsed: 00:22:53.96

Sources and Resources:

Filed in Oracle, Tips with 0 Comments | Tags:


7 Golden Rules That Make You a Better Programmer

Steven Feuerstein published a new presentation titled: Golden Rules for Developers [PDF].

Here is a summary of his seven “golden rules” that will help you write better code:

  1. Don’t repeat anything.
  2. Hide everything.
  3. Don’t take shortcuts.
  4. Embrace standards.
  5. Build on a foundation.
  6. Never lose information.
  7. Don’t write code alone.

Agreed with all. I would also add an eighth one: Understand your data.

What would you add?

Filed in Oracle, Tips with 11 Comments | Tags:


Please Request a Reasonable Conversion

Here is something you need to be aware of when you use the EXECUTE IMMEDIATE … USING and OPEN FOR … USING statements in PL/SQL.

Let’s execute this simple anonymous PL/SQL block:

eddie@db11gr2> DECLARE
  2    l_string VARCHAR2 (4000);
  3    l_rc sys_refcursor;
  4  BEGIN
  5    l_string := RPAD (' ', 4000);
  6    OPEN l_rc FOR 'select :1 from dual' USING l_string;
  7    EXECUTE immediate 'select :1 from user_objects where rownum = 1'
  8      INTO l_string USING l_string;
  9  END;
 10  /

PL/SQL procedure successfully completed.

The EXECUTE IMMEDIATE and OPEN FOR statements are used with the USING clause. USING supplies a bind argument for the SQL string. In this example the value of the bind argument is a 4,000 character string.

Now, let’s pass a string greater than 4,000 characters to the OPEN FOR statement:

eddie@db11gr2> DECLARE
  2    l_string VARCHAR2 (4001);
  3    l_rc sys_refcursor;
  4  BEGIN
  5    l_string := RPAD (' ', 4001);
  6    OPEN l_rc FOR 'select :1 from dual' USING l_string;
  7  END;
  8  /
DECLARE
*
ERROR at line 1:
ORA-01460: unimplemented or unreasonable conversion requested
ORA-06512: at line 6

Oops, got an error. Let’s also try the EXECUTE IMMEDIATE statement with a string greater than 4,000 characters:

eddie@db11gr2> DECLARE
  2    l_string VARCHAR2 (4001);
  3  BEGIN
  4    l_string := RPAD (' ', 4001);
  5    EXECUTE immediate 'select :1 from user_objects where rownum = 1'
  6      INTO l_string USING l_string;
  7  END;
  8  /
DECLARE
*
ERROR at line 1:
ORA-01460: unimplemented or unreasonable conversion requested
ORA-06512: at line 5

Got the same error: “ORA-01460: unimplemented or unreasonable conversion requested”.

How about if we pass a NULL:

eddie@db11gr2> DECLARE
  2    l_rc sys_refcursor;
  3  BEGIN
  4    OPEN l_rc FOR 'select :1 from dual' USING NULL;
  5  END;
  6  /
  OPEN l_rc FOR 'select :1 from dual' USING NULL;
                                            *
ERROR at line 4:
ORA-06550: line 4, column 45:
PLS-00457: expressions have to be of SQL types
ORA-06550: line 4, column 3:

In this case we get “PLS-00457: expressions have to be of SQL types”.

Well, there is a restriction on what values you can bind: When binding values to dynamic SQL, only SQL datatypes are supported. You can bind strings, numbers, dates, collections, LOBs, XML documents… However, you cannot bind values having a PL/SQL specific datatype such as Booleans, associative arrays and varchar2 values greater than 4000.

Make sure you keep the above restriction in mind when you use the EXECUTE IMMEDIATE … USING and OPEN FOR … USING statements.

Source and resources:

Filed in Oracle, Tips with Comments Off | Tags: ,


What Error

I have been playing the PL/SQL Challenge quiz every day. It’s a great way to brush up on my PL/SQL skills. After many years of using PL/SQL, I am still learning about features that I have never known before or totally forgotten about. Take for example one of last week’s quiz questions:

What is the output of this PL/SQL block?

eddie@db11gr2> DECLARE
  2     aname varchar2 (5);
  3  BEGIN
  4     DECLARE
  5        aname varchar2 (5) := 'Big String';
  6     BEGIN
  7        DBMS_OUTPUT.put_line (aname);
  8     EXCEPTION
  9        WHEN VALUE_ERROR
 10        THEN
 11           DBMS_OUTPUT.put_line ('Inner block');
 12     END;
 13     DBMS_OUTPUT.put_line ('What error');
 14  EXCEPTION
 15     WHEN VALUE_ERROR
 16     THEN
 17        DBMS_OUTPUT.put_line ('Outer block');
 18  END;
 19  /

Instead of telling you what the answer is, I will point you to the documentation:

In declarations, faulty initialization expressions can raise exceptions, but exception handlers cannot handle them… Handlers in the current block cannot catch the raised exception because an exception raised in a declaration propagates immediately to the enclosing block.

Even though I selected the wrong choice when I took the quiz, adding the above fact to my PL/SQL knowledge and sharing it with you is a big win for me.

By the way, should we consider initializing variables in the declaration section a bad practice?

Filed in Oracle, Tips with 3 Comments | Tags:


Following a Few of Quality Will Give You The Quantity You Need

Great advice from Mitch Joel: Too many people are looking for too many ways to follow too many people and places. Your best bet is to do the opposite. Don't add more noise to your life. start removing the noise. It's not important to follow every Blog, and it's impossible to listen to every Podcast. If you've spent more than five minutes on Twitter, the river of tweets and the speed with which they flow makes every conversation look, feel and last a couple of seconds (at most). Become a better filter. If you're following someone and they're really not adding any value to your life (your growth, development and education), drop them. If you follow a Blog but never get to it because life happens, drop it. If you're a publisher of content (text, audio, video, images, whatever…) think about what you're publishing (noise vs. value).. More…

Filed in Links, Tips with 4 Comments | Tags: , , , , ,


6 Tips For Making Oracle APEX Run Faster

Joel Kallman lists steps to make apex.oracle.com run faster, like turning on the KeepAlive setting in Oracle HTTP Server, reducing the open window for Web crawlers in robots.txt, replacing a Database Access Descriptor with an httpd.conf rewrite rule and increasing file system caching and memory size. Read the details at Making apex.oracle.com fast (again).

Filed in Oracle, Tips with Comments Off | Tags:


This is How You Should Ask for Help

In this video interview with ZDNet.com.au, Kyte explains how many questions he receives equate to “my car won’t start”. “I’m going to do it to you — my car won’t start, why? Give me the solution. I’m not going to tell you what errors I see on the dashboard; I’m not going to tell you if I filled the car up with gas recently; I’m not going to tell you if it’s making a noise or not making a noise; but my car won’t start, why not? There’s insufficient data to even begin to answer a question like that.” Kyte also explains how the internet has changed how questions are asked, and how he doesn’t reply with RTFM.

via How developers should ask for help: Blogs – Null Pointer – ZDNet Australia (via)

Filed in Oracle, Tips with Comments Off | Tags: , ,


A Quick Oracle Metalink Tip

Oracle Metalink (now known as “My Oracle Support” ) has over 300 scripts available. Log on to Metalink and then navigiate to:

Top of page – KNOWLEDGE – TOOLS AND TRAINING – DIAGNOSTIC TOOLS

There’s a LOT of stuff available in diagnostic tools. Take advantage of it!

Filed in Oracle, Tips with 2 Comments | Tags:


10 Tips to Increase Your Blog Readership

The following are 10 blogging tips I extracted from Tim Ferriss‘s presentation (video below) originally titled “Scalable Blogging Behaviors: How to Grow from 1 to 1,000,000 Readers”, then re-titled to “How to Blog without Killing Yourself“:

  1. The best times to publish a post are 7am PST and 6pm EST.
  2. The best days to publish a post are Tuesday, Thursday and Saturday.
  3. Change the word “Category” to “Topic” to increase page views.
  4. Display the publishing date at the bottom of the post.
  5. Add the number of minutes it takes to read the post. Normally, it’s 250 words per minute.
  6. A post should be about one, and only one topic.
  7. Write about what you are passionate about.
  8. Use tools such as Evernote, slinkset.com and Twitter to gather writing material and poll for ideas.
  9. Use Google Keyword Tool to increase your Google juice.
  10. Use Flickr’s advanced search to find interesting Creative Commons photos to use in posts.

Of course the above tips worked for Tim but they may or may not work for you and me.

Here is Tim’s full 50 minute presentation:

Filed in Tips with Comments Off | Tags:


Why WHEN OTHERS THEN RAISE Can Be Harmful

Every PL/SQL developer knows, or at least should know, that WHEN OTHERS THEN NULL is a hidden bug; Ask Tom.

But, what about WHEN OTHERS THEN RAISE?

I have known PL/SQL developers who follow a “standard” of adding:

EXCEPTION
   WHEN OTHERS
   THEN
      RAISE;
END;

to every PL/SQL block. The reasoning behind this practice, as explained to me:

  • There is no harm in adding it
  • It makes maintenance easier
  • Used as a placeholder for additional error handling when needed
  • There is no overhead executing it

When asked if he was joking when he added “when others then raise;” Shoblock replied:

not joking at all. very serious. I know it’s not needed, but it helps to point out to people who might modify your code later on that you do indeed want all other exceptions to be raised. it basically prevents someone from adding “when others then null” while you’re on vacation.

Now, before rushing back and starting to sprinkle WHEN OTHERS THEN RAISE all over your code, please read Tom Kyte’s take on this seemingly harmless line of code:

why do people do this?????

EXCEPTION WHEN OTHERS THEN RAISE; END;

what is the point, other than to make the code infinitely harder to debug. You know what you did by coding that?

YOU HIDE THE LINE NUMBERS FROM US. No longer can you tell where the error came from !!!!!

Tom is right. Consider:

SQL> DECLARE
  2     l_var   varchar2 (30);
  3  BEGIN
  4     SELECT   object_name
  5       INTO   l_var
  6       FROM   all_objects
  7      WHERE   ROWNUM <= 2;
  8  END;
  9  /
DECLARE
*
ERROR at line 1:
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at line 4

Now let’s add WHEN OTHERS THEN RAISE:

SQL> DECLARE
  2     l_var   varchar2 (30);
  3  BEGIN
  4     SELECT   object_name
  5       INTO   l_var
  6       FROM   all_objects
  7      WHERE   ROWNUM <= 2;
  8  EXCEPTION
  9     WHEN OTHERS
 10     THEN
 11        RAISE;
 12  END;
 13  /
DECLARE
*
ERROR at line 1:
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at line 11

As you can see, WHEN OTHERS THEN RAISE masked the line number where the actual error occurred. In the above example, the real error occurred at line 4 not 11.

WHEN OTHERS THEN NULL is a hidden bug but WHEN OTHERS THEN RAISE hides the bug.

Filed in Oracle, Tips with 4 Comments | Tags: