PLW-06002 unreachable code when using NULL; - oracle

I occasionally do something like....
IF very-likely-condition THEN
NULL;
ELSE
<<code to deal with the unlikely condition>>
END IF;
Which gives a PLW-06002 unreachable code warning from the PL/SQL compiler on the NULL line atfer the IF.
Now whilst I can clearly ignore the warning and/or refactor the IF statement to be a NOT, I think it reads better this way.
So does anybody know is there is another way of inserting an empty statement so that I don't get the compiler warning?
EDIT:
I'm not saying I do this often... in fact I'd do it very rarely. But occasionally I do think it reads better this way.
EDIT 2:
Plus there are other scenarios where it might be valid to do this (such as ignoring a specific error in an EXCEPTION block). I only used the IF as a simple example to illustrate the point.

To Recursive And Weblog :
the following statements are NOT equivalent:
IF :x = 0 THEN
NULL;
ELSE
do_something;
END IF;
and
IF NOT :x = 0 THEN
do_something;
END IF;
If :x IS NULL the do_something procedure will be called in the first case only. This is because the expression NULL = 0 is neither TRUE nor FALSE in Oracle, it is "unknown".
The correct way to re-write the first statement would be:
IF :x != 0 OR :x IS NULL THEN
do_something;
END IF;
I can see why in some cases we could write things as the OP.

Looks like this is by design. See http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14261/controlstructures.htm#i5421
Example 4-23 Using NULL as a Placeholder When Creating a Subprogram
CREATE PROCEDURE ... AS
BEGIN
NULL; -- use NULL as placeholder, raises "unreachable code" if warnings enabled
END;
/

Why do you have an empty statement? That's a code smell. It's generally accepted that is it not easier to read with an empty if block.
Change your if condition to the opposite of what it currently is:
IF NOT very-likely-condition THEN
<<code to deal with the unlikely condition>>
END IF;
If you need to do something when the condition is true, you can always add that block back in. Empty blocks separate the condition from the block that's executed when the condition is true. It also looks like you used to have code in the if section, then removed it but were too lazy to rewrite the if condition to remove the empty statement.
Subjectively, if I were reading your code and saw the empty if block, I'd think you didn't know what you were doing.

Related

Fatal: Syntax error, ; expected but identifier TUNJANGAN found [duplicate]

It has been around 20 years since I last had to write in Pascal. I can't seem to use the structure elements of the language correctly where I am nesting if then blocks using begin and end. For example this gets me an Compiler Error "Identifier Expected".
procedure InitializeWizard;
begin
Log('Initialize Wizard');
if IsAdminLoggedOn then begin
SetupUserGroup();
SomeOtherProcedure();
else begin (*Identifier Expected*)
Log('User is not an administrator.');
msgbox('The current user is not administrator.', mbInformation, MB_OK);
end
end;
end;
Of course if I remove the if then block and the begin end blocks associated with them then everything is OK.
Sometimes I get it this kind of syntax right and it works out OK, but the problems become exasperated when nesting the if then else blocks.
Solving the problem is not enough here. I want to have a better understanding how to use these blocks. I am clearly missing a concept. Something from C++ or C# is probably creeping in from another part of my mind and messing up my understanding. I have read a few articles about it, and well I think I understand it and then I don't.
You have to match every begin with an end at the same level, like
if Condition then
begin
DoSomething;
end
else
begin
DoADifferentThing;
end;
You can shorten the number of lines used without affecting the placement, if you prefer. (The above might be easier when you're first getting used to the syntax, though.)
if Condition then begin
DoSomething
end else begin
DoADifferentThing;
end;
If you're executing a single statement, the begin..end are optional. Note that the first condition does not contain a terminating ;, as you're not yet ending the statement:
if Condition then
DoSomething
else
DoADifferentThing;
The semicolon is optional at the last statement in a block (although I typically include it even when it's optional, to avoid future issues when you add a line and forget to update the preceding line at the same time).
if Condition then
begin
DoSomething; // Semicolon required here
DoSomethingElse; // Semicolon optional here
end; // Semicolon required here unless the
// next line is another 'end'.
You can combine single and multiple statement blocks as well:
if Condition then
begin
DoSomething;
DoSomethingElse;
end
else
DoADifferentThing;
if Condition then
DoSomething
else
begin
DoADifferentThing;
DoAnotherDifferentThing;
end;
The correct use for your code would be:
procedure InitializeWizard;
begin
Log('Initialize Wizard');
if IsAdminLoggedOn then
begin
SetupUserGroup();
SomeOtherProcedure();
end
else
begin
Log('User is not an administrator.');
msgbox('The current user is not administrator.', mbInformation, MB_OK);
end;
end;

confused about Pascal syntax

I ran across this piece of pascal code. I am curious as to how this does not repeat endlessly.
repeat
if xs>(torgx+xlim)
then begin
x:=xlim;
BREAK;
end;
if xs<(torgx-xlim)
then begin
x:=0-xlim;
BREAK;
end;
x:=xs-torgx;
BREAK;
until 0<>0;
I am confused as to how zero would ever be greater than or less than zero.
A loop that continues until 0 <> 0 is supposed to be endless.
But inside the loop there are some conditions that will break the loop, hence the use of the keyword break.
In fact, the repeat..until loop will only run once. The comparison is made that if a value is larger than a condition or less than another it will break out of the loop. If none of those conditions are met, it will break anyway.

First assign and then reassign in if block as alternative to if-(else if)-else in Verilog

Is it better to first assign a value to a variable and then reassign in if block instead of using if-(else if)-else blocks where the assignment in if and else blocks are the same and the assignment in the else if block is a different assignment.
always #(*) begin
if condition1 begin
var = val1;
end
else if condition2 begin
var = val2;
end
else begin
var = val1;
end
end
vs
always #(*) begin
var = val1;
if condition2 begin
var = val2;
end
end
Given condition1 and condition2 are mutually exclusive, I am thinking that both of these blocks should synthesize the same logic and the choice of one over the other is purely aesthetic. Am I correct in thinking this or will one implementation synthesize differently from the other? If my thinking is correct, which method is preferred in the community?
Edit: Added mutually exclusive criteria after racraman's comment.
As for the general principle you're asking about: it doesn't matter which route you go. The synthesiser will be smart enough to work it out anyway. For simulation, it's possible that the option which carries out a default assignment first might execute more slowly (particularly if the assignment is a non-blocking one), but I wouldn't worry about it.
Personally, I prefer the second, because it's more obvious to the causual reader that you have covered your bases in terms of generating unwanted latches (in other words, you are always assigning to var).
Having said all that, your example is (in principle) very simple, and in this particular case it's obvious that a mux is required, and you probably don't need an always block at all, and should just use an assign with a ternary operator.
I say 'in principle' because you logic doesn't really make sense. You say your conditions are mutually exclusive, but what happens if neither condition is active? Do you actually need a latch to preserve the previous output? If not, why do you have two conditions at all?
While using always#(*) blocks you may end up inferring unintentional latches in your design.
For assignments of the type you have mentioned its better to go for ternary operators.
assign var = (cond1)?(val1):(cond2)?(val2):(val1);
//Assuming cond1 and cond2 are mutually exclusive
If cond1 and cond2 can occur at the same time then above assign can be changed as
assign var = (cond1 && cond2)?(val1):(cond1)?(val1):(cond2)?(val2):(val1);
//Assuming val1 when both cond1/2 are high

Assign a value to a variable on RETURN PL/SQPL

Is there a way to achieve this in PL/SQL oracle ?
RETURN (return_status:=1);
It gives a compilation error when I try to do this. If this is not possible please suggest a better alternative instead of doing
return_status := 1;
RETURN (return_status);
When we execute a RETURN the procedure terminates at that point and control flow passes to the calling program. So there would be no value in this construct …
RETURN (return_status:=1);
… because nothing in the program unit could act on return_status after the RETURN.
this is a function and return_status is an OUT param
That's the root of your problem: poor design. Either return a value or have it as an OUT parameter but not both. The accepted practice in PL/SQL is that a function returns a value and has no OUT parameters. Only procedures (which don't have RETURN) have OUT parameters.
So you choices are:
return 1 and don't have an OUT parameter
set OUT parameter = 1 and return something else
make it a procedure instead
I dont understand what the problem is?
If you want to return the value return_status then the second option is just fine(if you are really doing a hardcoded assignment you could just return 1.
And I thought maybe you actually have an external variable return_status you are trying to change the value of by calling this function. In which case, use a procedure and have return_status be an IN OUT variable(maybe even just OUT).
AFAIK, you cannot assign value in the Oracle FUNCTIONS RETURN Statement.
From Oracle Docs, the syntax should be
RETURN [[(] expression [)]];
For expression refer Expressions
Only solution i can think of based on your requirement(1 condition instead of 2) is using case expression. Something like below (if you have any condition)
RETURN
CASE when return_status is not null
THEN 1
Functions with OUT parameters are permitted but smell wrong.

I keep getting a comparison between number and nil when trying to sort a table by myself

taula = {};
function randomNumber()
return math.random(100);
end
function startArray()
for x=0, 10 do
taula[x]=randomNumber();
end
end
function printArray()
for i=0,#taula do
print(taula[i]);
end
end
function organizeArray()
for i=0,#taula do
for j=1,#taula do
if taula[i]>taula[j] then
tmp = taula[j];
taula[j]=taula[i];
taula[i]=taula[tmp];
end
end
end
end
startArray()
organizeArray()
printArray()
This is not working! The initial idea is to have printed the table declared as 'taula' but in the function organizeArray() there is a problem in the if, it says I compare a number with a nil value when I have both j and i variables declared. I need help.
You're referencing tala[tmp] instead of tmp (at line 27) when you're shuffling the array around. That's what's causing the bug.
A few pointers:
You're using globals for everything. This can cause headaches later on, when globals collide (i.e tmp could be set to something, and you do something with it). See: Local Variables and Blocks
Using randomNumber() makes your code kind of obscure, since randomNumber is just an alias for math.random(100).
Lua starts at 1, not 0. You can start at 0, but this is just something to keep in mind. #table will not count the index 0.
When asking questions, please give the full error message -- this'll let us look at the code without having to run it ourselves :)
You can put print(x) in your code, so you can see what's happening. This'll help you find bugs, since you know whats going on.

Resources