Skip to content

Commit 1406889

Browse files
Merge pull request #217 from Trivadis/feature/issue-213-new-rule-for-loop
add G-4387: Never use a FOR LOOP for a query that should return not more than one row.
2 parents a5a4d12 + cd28542 commit 1406889

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# G-4387: Never use a FOR LOOP for a query that should return not more than one row.
2+
3+
!!! bug "Blocker"
4+
Reliability, Efficiency, Readability
5+
6+
!!! missing "Unsupported in db\* CODECOP Validators"
7+
Without access to the Oracle Data Dictionary, we cannot determine the number of rows to be processed.
8+
9+
## Reason
10+
11+
A `for loop` can hide a `too_many_rows` exception. The more complex a query is, the higher is the risk that more than one row will be processed.
12+
This affects performance and can lead to a wrong result.
13+
14+
A `for loop` can also hide a `no_data_found` exception and the reader cannot determine whether this is intentional or not.
15+
16+
## Example (bad)
17+
18+
``` sql
19+
create or replace package body employee_api is
20+
function emp_name(in_empno in integer) return varchar2 is -- NOSONAR: non-deterministic
21+
l_ename emp.ename%type;
22+
begin
23+
<<fetch_name>>
24+
for r in (
25+
select ename
26+
from emp
27+
where empno = in_empno
28+
)
29+
loop
30+
l_ename := r.ename;
31+
end loop fetch_name;
32+
return l_ename;
33+
end emp_name;
34+
end employee_api;
35+
/
36+
```
37+
38+
## Example (good)
39+
40+
``` sql
41+
create or replace package body employee_api is
42+
function emp_name(in_empno in integer) return varchar2 is -- NOSONAR: non-deterministic
43+
l_ename emp.ename%type;
44+
begin
45+
select ename
46+
into l_ename
47+
from emp
48+
where empno >= in_empno;
49+
return l_ename;
50+
exception
51+
when no_data_found then
52+
return null;
53+
when too_many_rows then
54+
raise;
55+
end emp_name;
56+
end employee_api;
57+
/
58+
```

docs/9-appendix/appendix.md

+1
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ n/a | 4365 | Never use unconditional CONTINUE or EXIT in a loop. | Major | | |
8787
46 | 4375 | Always use EXIT WHEN instead of an IF statement to exit from a loop. | Minor | | | &#10008; | | | | |
8888
47 | 4380 | Try to label your EXIT WHEN statements. | Minor | | | &#10008; | | | | |
8989
48 | 4385 | Never use a cursor for loop to check whether a cursor returns data. | Critical | | &#10008; | | | | | |
90+
n/a | 4387 | !!!CHARACTERISTIC ERROR!!! | Blocker | | &#10008; | | | &#10008; | | |
9091
49 | 4390 | Avoid use of unreferenced FOR loop indexes. | Major | | &#10008; | | | | | |
9192
50 | 4395 | Avoid hard-coded upper or lower bound values with FOR loops. | Minor | &#10008; | | &#10008; | | | | |
9293
n/a | 5010 | Try to use a error/logging framework for your application. | Critical | | | | | &#10008; | &#10008; | | &#10008;

0 commit comments

Comments
 (0)