Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Mo.

Asked: September 06, 2002 - 10:56 pm UTC

Last updated: May 10, 2011 - 9:17 am UTC

Version: 8.1.7

Viewed 1000+ times

You Asked

Tom:

1. When I run "host cmd" in SQL*PLUS I get a smal dos window that display the results fast that I can not see anything . Is there anyway to keep that window open at the same time SQL*PLUS is open? otherwise what is the benefit of it.

2. Why I do not see PL/SQL code that uses

goto label

<<label>>

IT seems everyone uses exceptions. But is not this useful especially when you have a business logic in an if statement that does not raise an oracle defined excpetion and you have to define your own exceptin using init_pragma?

3. If I have one transaction that enters data in 5 tables based on some logic and I want to commit after entering data successfully into 5 tables or rollback the whole transaction.

DO you add IF (SQL%rowcount > 0 and (x>5 or z<6) ) before each insert to the 4 tables or do you basically create a boolean variable to track that each step was executed and then at the end before you commit you do:

If (step1 and step2 and step3 and step4) then
commit;
else
rolback;
end if;

Thank you,


and Tom said...

1)

SQL> host erase c:\temp\file_i_dont_want.anymore

that would be a "use" for it. But anyway -- you would have to use the windows setup that says "don't automatically close the little dos windows". I don't remember exactly where you do this -- but this is a windows thing, not a sqlplus issue really (goto your start menu, Run.... put in the same command. Then ask yourself "what is the use of that" -- cause the same exact thing will happen!)

Me, when made to use windows, I always use sqlplus.exe in a DOS window. I never use that "GUI" version, I see no advantages to it, only downsides.

2) goto's are considered to be a fairly poor programming practice. This school of thought (that goto's are not a desirable thing) goes back for as many years as I can remember. Languages like Basic, that in the beginning didn't have alot of control structures, forced the use of GOTO but not since then really.

I don't understand your comment about exceptions at all. I don't have any idea really why you say they are "not useful".

3) I would code:

begin
insert
insert
insert
insert
insert
commit;
exception
when others then
rollback;
raise;
end;

That is all.


Rating

  (4 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

host

mo, September 07, 2002 - 12:10 pm UTC

Tom:

1. You mean that you from windows go to dos prompt (without exiting windows completely) and then run sqlplus.exe? Why is this better than using GUI sqlplus?

2. I know that goto is a poor prgramming practice even though I never understood "why" it is? and how it is different than using exceptions?

what i meant is that I see goto useful in things like this:

if (a>5 and z>6) then
goto program1;
else goto program2;
end if;

<<program1>>
...
<<program2>>
..

instead of:

declare
program1 exception;
program2 exception;

begin
if (a>5 and z>6) then
raise program1;
else raise program2;
end if;

Exception
WHEN program1 then
....
WHEN program2 then
...

3. Great technique. This way if any insert fails it will raise an exception and stop. Correct?

Tom Kyte
September 07, 2002 - 6:47 pm UTC

1) yes. I run a cmd.exe shell and run it from there.

why is this "better"? I can easily change the colors, the font size, the scrollback buffer, etc.

Host output doesn't "disappear"

I can Cd to where I want to be before starting sqlplus.

It works *just* like sqlplus on every single other platform.

sqlplusw.exe is sort of a aberration -- it is a unique sqlplus, different from sqlplus on all other platforms. I don't like different -- I like homogenous.


2) a goto results in what is known as spaghetti code. hard to read, sometimes impossible to understand.

exceptions make it IMPOSSIBLE to ignore errors and many programming errors are directly caused by ignoring errors. When an exception comes up one of two things will happen

a) you will catch it and deal with it.
b) you will ignore it and maybe someone else will catch and deal with it OR the program will just fail outright which is infinitely prefered to CONTINUEING the faulty program allowing it to do even more damage.

well-- maybe there is three.

c) you will code a when others that is not followed by RAISE to re-raise the error. Now you have just disabled exceptions and you are back to the "bad programmer".


It looks like you are trying to use gotos as an error mechanism. Or, even worse, you are trying to use exceptions as something other then error handling (eg: you are trying to use exceptions as a control structure like IF/THEN/ELSE or LOOP). They are a very poor choice for that.


Exceptions are superior in every way to goto for error handling. I mean -- suppose you have a procedure P that can have two distinct errors -- how would P be able to use a goto to notify the caller? (it cannot). If you are trying to use exceptions as a program flow control structure STOP -- that would be a really bad idea.


3) correct. If you have my book "expert one on one oracle" - i cover this in great detail.



Business logic requires use of goto.....

mb.sharma, May 29, 2007 - 7:12 am UTC

I would like to know if business logic needs use of goto...e.g.

If a =1 THEN
-- do somthing...
ELSE
--lookup in some table...
--Here if no data found then goto abc
END IF;
<abc> look up in another table...

From aboue discussion i understand better to write exeception as follows..
IF a =1 THEN
-- do somthing...
ELSE
BEGIN
--- lookup in some table...
EXCEPTION
WHEN NO_DATA_FOUND THEN
look up in another table....
END;
END IF;


Plz comment is it a correct programming practice or any other solution...
Tom Kyte
May 30, 2007 - 10:45 am UTC

well, the first block of code is nonsense since we ALWAYS get to <abc>, the goto is redundant.

I've never used goto in my life, well, not since I programmed basic on a calculator anyway.

help

venkata, May 10, 2011 - 7:43 am UTC

Hi Tom,

Note : The examples i mention here are not intended to execute when you do copy, paste and execute. and please don't say my code is full of bugs and don't label my code as i hate...

now coming to my requirement.

assume there is a package with 10K lines of source code( procedures, functions).

package p1; inside this package there are some set of procedures a1,a2,a3.

this package is executed as part of a cron job.

the business logic is like this...now please don't ask why is it like this, why can't it be like some other way.

procedure a1

insert data into a table

commit

deletes some data from a table

commit

creates partitions on a table

call procedure a2,

which truncates some table(s) and

then calls procedure a3.

now, in procedure a1, while creating partitions on some table, if there is error due to non availability of space, the cron job fails throwing oracle error.

now my requirement(client requirement) is,

+> can i start from the point of failure, from the point of creating partitions

+> without executing the insert and delete statements which are prior

in procedure a1 where the job has failed.

i thought of using goto statement, after going through your reviews thought its a pretty bad idea. is there any way to achieve this

Tom Kyte
May 10, 2011 - 9:17 am UTC

Note : The examples i mention here are not intended to execute when you do copy, paste and execute. and please don't say my code is full of bugs and don't label my code as i hate...

If you don't have

when others then null;

or its equivalent, I won't hate on your code. If your pseudo code logic above includes that construct I'll ABSOLUTELY be hating on your code.


assume there is a package with 10K lines of source code( procedures, functions).


I've got a problem with that already.

the business logic is like this...now please don't ask why is it like this, why can't it be like some other way.


Again, I refuse that request. If you are doing something obviously wrong, I'm going to point it out. It is what I do. It is what I am. I will not change in that respect.


now, in procedure a1, while creating partitions on some table, if there is error due to non availability of space, the cron job fails throwing oracle error.

now my requirement(client requirement) is,

+> can i start from the point of failure, from the point of creating partitions

+> without executing the insert and delete statements which are prior

in procedure a1 where the job has failed.


Why the heck would you need to use a goto? Think about this.


If you need to be restartable, you are going to have to change the code. It will require an extra table so it can restart itself automagically.

create table cron_job_log( step number );

create function new_function return number
as
   rec cron_job_log%rowtype;
begin
   select * into rec from cron_job_log;
   return rec.step;
exception
   when no_data_found then return 0;
end;





procedure a1
   if (new_function < 1)
   then
      insert data into a table
      insert (1) into cron_job_log;
      commit;
   end if;
   if (new_function < 2)
   then
      delete from a table;
      delete from cron_job_log;
      insert (2) into cron_job_log;
      commit;
   end if;

   run query to look at dictionary to see if partitions are ALREADY created

   if (partitions are not created)
   then
       do the ddl to create said partition;
   end if;

   A2;
end A1;

procedure A2
   
   if (new_function < 3) 
   then 
        delete from cron_job_log;
        insert into cron_job_lob (3);
        truncate some table -- this will commit the insert
   end if;

   A3;
   delete from cron_job_log;
   commit;   -- we are done
end A2;





Now, I just banged that out on the fly, do a code review with your team after you flesh it out. It is standard "coding 101" sort of stuff - requires no 'gotos', just good old fashioned linear procedural logic to see if you've already done something - and if you have, don't do it again.

And now you see why committing often is a really bad idea in general, you have to write a lot more code to make yourself restartable.

A reader, May 11, 2011 - 6:37 am UTC


More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library