BREAK statement in PL/pgSQL - postgresql

How to have the break statement in PostgreSQL? I have the structure like this:
for()
{
for()
{
if(somecondition)
break;
}
}
As per my understanding it should only break the inner for loop?

There is no BREAK in PL/pgSQL.
EXIT terminates the loop.
CONTINUE continues at the next iteration of the loop.
You can attach a <<label>> to loops and add it as parameter to each of these commands. Then you terminate / continue the labeled loop. Else, it concerns the inner loop.
RETURN exits from the function (so not applicable in a DO statement).
All of this applies to procedural elements of PL/pgSQL, not SQL.
Code example using all three:
Loop in function does not work as expected

Note, that: Yes! you need the "WHEN", even if you end up (like me ;-)) with something like
LOOP
...
IF l_my_var = 'some condition' THEN
-- this is ok, bla
IF l_debug_level >= 2 THEN
RAISE NOTICE 'debug 2: skipping a duplicate %, l_my_var;
END IF;
-- do something
CONTINUE WHEN TRUE; -- https://stackoverflow.com/questions/15173194/break-statement-in-pl-pgsql
ELSE
-- do something
END IF;
...
which looks somewhat twisted with both IF and WHEN.
Remark to the editor:
One could make the link behind "CONTINUE" more precise: https://www.postgresql.org/docs/9.6/plpgsql-control-structures.html#AEN66440

Related

Questions on structuring T-SQL

I'm learning T-SQL and trying to get my head around how to approach it/best practices. Working through some examples, there are three questions I have:
1) Coming from Python, is there a generally agreed upon style guide (something like PEP 8) or approach for laying out T-SQL or is it more like JavaScript where anything goes?
2) When creating stored procedures and functions I see some authors always use a main BEGIN/END block and others don't. At first I thought you need BEGIN/END if you have more than one statement. However, this doesn't seem to be true because I have seen lengthy stored procedures with no main BEGIN/END. Any thoughts on this?
3) Within stored procedures, some authors seem to like to enclose parts of their code in BEGIN/END blocks. I can't see why you'd do this and wonder if I'm missing something. For example:
CREATE PROCEDURE <NAME> (
<Parameter List...>
)
AS
BEGIN
-- Setup:
-- Declare/initialize variables...
BEGIN TRY
BEGIN TRANSACTION
-- Validity check 1:
IF #Param1 ...
BEGIN
-- Do stuff...
END
-- Validity check 2
IF #Param2 ...
BEGIN
-- Do stuff...
END
-- Update - added BEGIN/END after if blocks for clarity
-- Why wrap these statements in a BEGIN/END Block???
BEGIN
--Add the entry
INSERT dbo.JournalClientFamilyChanges (
HouseholdMembersID,
PreviousClientsID,
NewClientsID,
ActionTaken,
Notes,
ModifiedBy,
ModifiedDate
)
VALUES (
#HouseholdMembersID,
#PreviousClientsID,
#NewClientsID,
#ActionTaken,
#Notes,
#ModifiedBy,
SYSDATETIME()
)
SET #success =1;
SET #ErrorStatus ='';
COMMIT TRANSACTION;
END
END TRY
BEGIN CATCH
-- Error handling...
END CATCH
END
Any thoughts appreciated,
--Jim
To answer your question at your own example
IF #Param1 ...
-- Validity check 2
IF #Param2 ...
-- Why wrap these statements in a BEGIN/END Block???
BEGIN
--Add the entry
INSERT dbo.JournalClientFamilyChanges (
HouseholdMembersID,
...
)
VALUES (
#HouseholdMembersID,
#PreviousClientsID,
...
)
SET #success =1;
SET #ErrorStatus ='';
COMMIT TRANSACTION;
END
There is an IF which will call the code below just under certain circumstances. Without the BEGIN ... END this will be valid for the very next statement only. Using BEGIN ... END will see the whole code block covered by the IF condition (the lines with SET and COMMIT).
Try this out:
DECLARE #SomeInt INT=0;
IF #SomeInt=1
PRINT 'Example 1: hello, this is the first line';
PRINT 'Example 1: hello, the next line';
IF #SomeInt=1
BEGIN
PRINT 'Example 2: hello, this is the first line';
PRINT 'Example 2: hello, the next line';
END
For better readability one would use indents. But this is not relevant for the engine. There are some languages using indents as block marker though, others use paranthesis or any kind of brackets. T-SQL uses BEGIN ... END. Sometimes people use this in larger procedures just to allow collapsing (like the #region in C#)
IF #SomeInt=1
PRINT 'Example 1: hello, this is the first line';
PRINT 'Example 1: hello, the next line';
IF #SomeInt=1
BEGIN
PRINT 'Example 2: hello, this is the first line';
PRINT 'Example 2: hello, the next line';
END
update
Just to reflect the comments below: The OP changed the initial question in a way, that the BEGIN ... END is no longer connected to the IF. So the question shoudl be: Why would one use BEGIN ... END without any functional reason?.
The answer for this is
To mark some lines of code as a "block"
... thus emphasising the functional unit
Collapsing is a nice side-effect

How to Simulate While Loops in Scratch?

In most programming languages, there is a "while" loop that runs code while a condition is true. However, in Scratch, there is only a "repeat until" loop that repeats until a condition is true. How do I simulate a "while" loop in Scratch?
Say you wanted to use a "while" loop to run while "ConditionA" is true.
WHILE ConditionA
Say "hello"
In Scratch, you can use a "repeat until" loop in this way:
REPEAT UNTIL NOT ConditionA
Say "hello"
This is easy. Just loop an "if" operator.
forever
if <...>
code goes here
else
end
end

How to break a loop if "break" is inside fork-join?

I need to break a repeat loop, whose break decision is made inside a fork-join block, but my simulator doesn't compile the code that has the following structure.
repeat (10) begin
fork
begin
// do something
end
begin
#(100ms);
break; // compile error
end
join_any
disable fork;
end
I also tried the disable command. I was able to compile, but it didn't break the loop.
repeat (10)
begin : repeat10_loop
fork
begin
// do something
end
begin
#(100ms);
disable repeat10_loop; // try
end
join_any
disable fork;
end : repeat10_loop
Is there a way to use break or disable inside fork-join?
The break and continue statements must be within the same process as the loop statement. The problem with your disable is you incorrectly labeled your loop. Try:
repeat10_loop: repeat (10)
begin

How do I exit this function?

Essentially its built like so:
.If
..other stuff
.Else
..For
...For
....If (this is where I need to be able to break out of the whole thing)
I've tried using return, and break, but they just are not working for whatever reason. I added in a ticker and it appears that the break command isn't working?
The code just continues going on and repeating the for loop even AFTER it is 'broken' in the If statement.
My function is only about 150 lines long, so I've been able to study it closely, and this seems to be where the problem is.
If you have
for (...)
for (...)
if (true)
break;
end
end
you'll only break out of the inner loop. But, of course, the outer loop will continue as normal!
Breaking out of nested-loops is one of the very few reasonable use cases for a goto. However, MATLAB does not have a goto, so you'll have to repeat yourself in some way or another:
for (...)
for (...)
if (condition)
break;
end
if (condition)
break;
end
An equally ugly yet common and less verbose way:
try
for (...)
for (...)
if (condition)
error(' ');
end
end
catch %#ok
(code you want to be executed after the nested loop)
end
or, to be pedantic,
breakout_ID = 'fcn:breakout_condition';
try
for (...)
for (...)
if (condition)
error(breakout_ID, ' ');
end
end
catch ME
% graceful breakout
if strcmp(ME.Identifier, breakout_ID)
(code you want to be executed after the nested loop)
% something else went wrong; throw that error
else
rethrow(ME);
end
end
Or you build a (nested) function containing just that nested loop, and use return to break out. But that may not always give the most "obvious" code structure, as well as cause you to have to write lots of boilerplate code (subfunction) and/or have unforeseen side effects (nested functions), so...
Personally, I favor the try/catch above.

New control transfer statements (labels) for Swift 2.0

What would be the best practices for the new control transfer statements (labels) in Swift 2?
Since I hear about it I can't stop compare it with the goto command from the good and old Basic language, what never was well accepted from experient programmers at the time.
Some uses of the control flow transfer looks ok, like in example below:
outer: for i in 1...100{
for j in 1...100{
print("\(i), \(j)")
if j == 10 {
break outer
}
}
}
But what are the limitations for the control flow transfer use?
When start to be bad practice to use it?
If its use was such a bad practice why it is back?
You can prefix a loop statement, an if statement, or a switch statement with a statement label followed by a colon (:) ,break and continue statements are used to change control flow in a loop statement or a switch statement.
break statement breaks the current loop execution where as continue just breaks current iteration.
consider:
firstLoop :for j in 0...1{
secondLoop: for i in 0...10{
if (i % 2) == 0{
if (i == 4){
break firstLoop
}
print(i)
}
}
}
Output will be : 0,2
If we replace break firstloop by break secondLoop o/p Will be: 0,2,0,2
If we replace break firstloop by continue o/p Will be: 0,2,6,8,10,0,2,6,8,10
If we replace break firstloop by continue firstloop continue o/p Will be again : 0,2,0,2
If continue is followed by a statement label then it will stop the current iteration of that statement label not the loop pointed by statement label.
goto VS statement label
. goto is a kind of unconditional branching ,where you can branch anywhere in the program,The goto statement is discouraged , because it alters the sequential flow of logic .
Why statement Label is used and what is it's Limitation?
. where as continue and break can make use of statement label if and only if it is written inside the loop which has same statement label which it is using so the code will be more safer. It makes programers life easy , off course you can't directly branch out to any part of program using continue,break and statement Label it can be considered as a limitation.
I think you are asking about using labels for break and continue statements. That is a much more limited, safer use than the horrible goto statements from basic. It simply lets you tell the compiler the scope you need to break out of/continue when you have nested looping constructs.
As far as I know break and continue is the only use of labels in Swift, and for that it seems useful and appropriate.