> ## Documentation Index
> Fetch the complete documentation index at: https://docs.codeant.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Abap

> [accordion] BREAK-POINT statement should not be used in production
>
> A `BREAK-POINT` statement is used when debugging an application with help of the ABAP Debugger. But such debugging statements could make an application vulnerable to attackers, and should not be left in the source code.
>
> ```abap Bad theme={"theme":"css-variables"}
> IF wv_parallel EQ 'X'.
> BREAK-POINT.  
> WAIT UNTIL g_nb_return EQ wv_nb_call.
> ENDIF.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> IF wv_parallel EQ 'X'.
> WAIT UNTIL g_nb_return EQ wv_nb_call.
> ENDIF.
> ```

> [accordion] Jump statements should not be redundant
>
> Jump statements, such as `CHECK and CONTINUE` let you change the default flow of program execution, but jump statements that direct the control flow to the original direction are just a waste of keystrokes.
>
> ```abap Bad theme={"theme":"css-variables"}
> LOOP AT myTable.
> PERFORM form_open USING ...
> CHECK retcode = 0.
> ...
> perform form_close.
> CHECK retcode = 0. "Noncompliant; whatever the result of the check, the loop will continue to the next iteration
> ENDLOOP.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> LOOP AT myTable.
> PERFORM form_open USING ...
> CHECK retcode = 0.
> ...
> PERFORM form_close.
> ENDLOOP.
> ```

> [accordion] An internal table should be sorted before duplicates are deleted
>
> Calling `DELETE ADJACENT DUPLICATES won’t reliably do any good if the table hasn’t first been sorted to put duplicates side by side, since the ADJACENT` part of the command looks for multiple rows side-by-side with the same content.
>
> ```abap Bad theme={"theme":"css-variables"}
> DELETE ADJACENT DUPLICATES FROM ITAB COMPARING LAND.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> SORT ITAB BY LAND.
> DELETE ADJACENT DUPLICATES FROM ITAB COMPARING LAND.
> ```

> [accordion] FORM... ENDFORM and PERFORM should not be used
>
> Procedural development in general, and `FORM... ENDFORM, and PERFORM` specifically, have been been classified as obsolete by SAP and should be avoided. Classes and methods should be used for all new development.
>
> ```abap Bad theme={"theme":"css-variables"}
> FORM fill_table USING    wa   TYPE any 
>             CHANGING ptab TYPE INDEX TABLE. 
> APPEND wa TO ptab. 
> ENDFORM. 
> * ...
> PERFORM fill_table IN PROGRAM my_prog.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> ```

> [accordion] LOOP ASSIGNING with field-symbols should be used instead of LOOP INTO with MODIFY
>
> Using \`LOOP...INTO  with MODIFY statements will put the required record in a work area, process it and put it back in the internal table. It is more efficient to modify the internal table directly by using LOOP...ASSIGNING and field-symbols.
>
> This rule raises an issue when a LOOP...INTO contains one or more MODIFY\` statements.
>
> ```abap Bad theme={"theme":"css-variables"}
> LOOP AT i_bseg INTO wa_bseg.
> ...
> wa_bseg-sgtxt = 'VALUE'.
> MODIFY i_bseg FROM wa_bseg.
> ENDLOOP.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> LOOP AT i_bseg ASSIGNING <fs_bseg>.
> ...
> <fs_bseg>-sgtxt = 'VALUE'.
> ENDLOOP.
> ```

> [accordion] Standard tables should be searched using BINARY SEARCH
>
> The \`READ TABLE ... WITH KEY ... statement performs a linear search of STANDARD tables, which is very inefficient in most cases.
>
> This rule raises an issue when a READ TABLE ... WITH KEY ... statement does not finish with BINARY SEARCH. No issue will be raised for HASHED and SORTED\` tables.
>
> ```abap Bad theme={"theme":"css-variables"}
> TYPES BEGIN OF t_mytable, 
> myfield TYPE i
> END OF t_mytable. 
>
> DATA myworkarea TYPE t_mytable.
>
> DATA mytable TYPE STANDARD TABLE OF t_mytable.
>
> SORT mytable BY myfield.
>
> READ TABLE mytable 
> WITH KEY myfield = 42
> INTO myworkarea. " Noncompliant
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> TYPES BEGIN OF t_mytable, 
> myfield TYPE i
> END OF t_mytable. 
>
> DATA myworkarea TYPE t_mytable.
>
> DATA mytable TYPE STANDARD TABLE OF t_mytable.
>
> SORT mytable BY myfield.
>
> READ TABLE mytable 
> WITH KEY myfield = 42
> INTO myworkarea
> BINARY SEARCH. " Compliant
>
> DATA my_hashed_table TYPE HASHED TABLE OF t_mytable 
> WITH UNIQUE KEY myfield.
>
> DATA my_sorted_table TYPE SORTED TABLE OF t_mytable 
> WITH UNIQUE KEY myfield.
>
> READ TABLE my_hashed_table 
> WITH KEY myfield = 42
> INTO myworkarea. " Compliant
>
> READ TABLE my_sorted_table 
> WITH KEY myfield = 42
> INTO myworkarea. " Compliant
> ```

> [accordion] SAP standard tables should not be modified via Open SQL statements
>
> Modifying SAP standard tables via an Open SQL statement can result in data corruption and unexpected behavior. This is because a direct modification bypasses all validation mechanisms.
>
> Instead, the use of standard functions or SAP Business Add-Ins (BAdIs) is recommended.
>
> This rule raises an issue on Open SQL statements `INSERT, UPDATE, MODIFY, or SELECT ... FOR UPDATE` which target an SAP table, i.e. a table with a name starting with a character between "A" and "X", case insensitive.
>
> ```abap Bad theme={"theme":"css-variables"}
> SELECT my_col FROM my_system_table WHERE my_id = 123 FOR UPDATE. " Noncompliant
>
> SELECT my_col FROM z_custom_table WHERE my_id = 123 FOR UPDATE. " Ignored; modifies a custom table
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> ```

> [accordion] SYSTEM-CALL statement should not be used
>
> The ABAP documentation is pretty clear on this subject :
>
> > This statement is only for
> >
> > !!! Internal use in SAP Basis development !!!
> >
> > Even within SAP Basis, it may only be used in programs within the ABAP+GUI development group.
> >
> > Its use is subject to various restrictions, not all of which may be listed in the documentation. This documentation is intended for internal SAP use within the Basis development group ABAP+GUI.
> >
> > Changes and further development, which may be incompatible, may occur at any time, without warning or notice!
>
> ```abap Bad theme={"theme":"css-variables"}
> SYSTEM-CALL CREATE CLASS c.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> ```

> [accordion] Expressions should not be too complex
>
> The complexity of an expression is defined by the number of `AND, OR, XOR and EQUIV` operators it contains.
>
> A single expression’s complexity should not become too high to keep the code readable.
>
> ```abap Bad theme={"theme":"css-variables"}
> IF ((condition1 AND condition2) OR (condition3 AND condition4)) AND condition5.
> ...
> ENDIF.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> ```

> [accordion] Subqueries and JOIN clauses should not be used
>
> \`JOIN bypasses the SAP table buffer. Buffered tables should be accessed with the simplest SELECT statements possible so as not to risk bypassing the buffer.
>
> If one of the tables in a JOIN is buffered, it would be an advantage to first import the required entries using a SELECT into an internal table itab, and then for example, using the statement SELECT ... FOR ALL ENTRIES IN itab\` to access further tables.
>
> ```abap Bad theme={"theme":"css-variables"}
> SELECT s~carrid s~carrname p~connid
>    INTO CORRESPONDING FIELDS OF TABLE itab
>    FROM scarr AS s
>    LEFT OUTER JOIN spfli AS p ON s~carrid   =  p~carrid
>         AND p~cityfrom = p_cityfr.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> SELECT  carrname
> INTO  TABLE name_tab
> FROM  scarr
> WHERE EXISTS ( select  *
>                FROM  spfli
>                WHERE carrid   =  scarr~carrid AND
>                      cityfrom = 'NEW YORK'        ).
> ```

> [accordion] Asterisks should be used for headers and to comment out code
>
> For readability, SAP recommends that asterisks (`*) only be used to comment out header lines and code. Commentary should be commented using a double quote ("`)
>
> ```abap Bad theme={"theme":"css-variables"}
> * GAC -  13 June 13 - output user data
> * WRITE: / 'Firstname'.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> " GAC -  13 June 13 - output user data
> * WRITE: / 'Firstname'.
> ```

> [accordion] Driver tables should be sorted before use
>
> In `SELECT ... FOR ALL ENTRIES` queries there are two internal tables: the driver internal table, and the target internal table. For each entry in the driver table some data from a database table is stored in the target internal table.
>
> Most of the time, starting by sorting the content of the driver internal table offers improved performance. Indeed in such cases, from one request to another, the data read from the database tends to be much the same, and so for instance the use of database caching is maximised.
>
> ```abap Bad theme={"theme":"css-variables"}
> SELECT carrid , connid , seatsocc FROM flights
> INTO TABLE seatsocc_tab                  		
> FOR ALL ENTRIES IN conn_tab  
> WHERE carrid = conn_tab-carrid
> AND connid = conn_tab-connid
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> SORT conn_tab BY carrid
> ...
> SELECT carrid , connid , seatsocc FROM flights
> INTO TABLE seatsocc_tab                  		
> FOR ALL ENTRIES IN conn_tab  
> WHERE carrid = conn_tab-carrid
> AND connid = conn_tab-connid
> ```

> [accordion] SQL BYPASSING BUFFER clause should not be used
>
> This `BYPASSING BUFFER clause explicitly switches off SAP table buffering, so the SELECT` reads data directly from the database.
>
> By definition, using this clause can lead to performance issues, which is why its use must be strongly indicated.
>
> ```abap Bad theme={"theme":"css-variables"}
> SELECT * 
> INTO US_PERSONS
> FROM PERSONS
> BYPASSING BUFFER
> WHERE CITY EQ 'US'
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> ```

> [accordion] Loops should not contain more than a single CONTINUE, EXIT, CHECK statement
>
> Restricting the number of \`CONTINUE, EXIT and CHECK statements in a loop is done in the interest of good structured programming.
>
> One CONTINUE, EXIT and CHECK\` statement is acceptable in a loop, since it facilitates optimal coding. If there is more than one, the code should be refactored to increase readability.
>
> ```abap Bad theme={"theme":"css-variables"}
> DO counter TIMES.
> IF sy-index = 2.
> CONTINUE.
> ENDIF.
> IF sy-index = 10.
> EXIT.
> ENDIF.
> WRITE sy-index.
> ENDDO.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> ```

> [accordion] SELECT INTO TABLE should be used
>
> `SELECT INTO TABLE is much more efficient than SELECT ... ENDSELECT. SELECT INTO TABLE` needs more memory to hold the result set, but in normal situations, this is not a concern. When memory is a concern, the result set can be divided into smaller sets.
>
> ```abap Bad theme={"theme":"css-variables"}
> SELECT * FROM T006 INTO X006_WA.
> ...
> ENDSELECT.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> SELECT * FROM T006 INTO TABLE X006.
> LOOP AT X006 INTO X006_WA.
> ...
> ENDLOOP.
> ```

> [accordion] CATCH clauses should not be empty
>
> Leaving a `CATCH` block empty means that the exception in question is neither handled nor passed forward to callers for handling at a higher level. Suppressing errors rather than handling them could lead to unpredictable system behavior and should be avoided.
>
> ```abap Bad theme={"theme":"css-variables"}
> try.
> if ABS( NUMBER ) > 100.
>   write / 'Number is large'.
> endif.
> catch CX_SY_ARITHMETIC_ERROR into OREF.
> endtry.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> try.
> if ABS( NUMBER ) > 100.
>   write / 'Number is large'.
> endif.
> catch CX_SY_ARITHMETIC_ERROR into OREF.
> write / OREF->GET_TEXT( ).
> endtry.
> ```

> [accordion] Loops with at most one iteration should be refactored
>
> A loop with at most one iteration is equivalent to the use of an \`IF statement to conditionally execute one piece of code. No developer expects to find such usage of a loop statement. If the initial intention of the author was really to conditionally execute one piece of code, an IF statement should be used in place.
>
> At worst that was not the initial intention of the author and so the body of the loop should be fixed to use the nested STOP, RETURN or EXIT\` statements in a more appropriate way.
>
> ```abap Bad theme={"theme":"css-variables"}
> DATA remainder TYPE i. 
> DO 20 TIMES. 
> remainder = sy-index MOD 2. 
> cl_demo_output=>write_text(). 
> EXIT.  " noncompliant, loop only executes once
> ENDDO.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> DATA remainder TYPE i. 
> DO 20 TIMES. 
> remainder = sy-index MOD 2. 
> cl_demo_output=>write_text(). 
> ENDDO.
> ```

> [accordion] JOIN should be used instead of nested SELECT statements
>
> `SELECT with JOIN` always performs better than nested selects.
>
> ```abap Bad theme={"theme":"css-variables"}
> SELECT * FROM SPFL INTO SPFLI_WA.
> SELECT * FROM SFLOGHT INTO SFLIGHT_WA
> WHERE CARRID = SPFLI_WA-CARRID
> AND CONNID = SPFLIGHT_WA_CONNID.
> ENDSELECT.
> ENDSELECT.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> SELECT * INTO WA
> FROM SPFLI AS P INNER JOIN SFLIGHT AS F
> ON P~CARRID = F~CARRID AND
>     P~CONNID = F~CONNID.
> END-SELECT.
> ```

> [accordion] Duplications in driver tables should deleted before the tables are used
>
> Removing duplicate entries from driver tables enables `OPEN SQL` to generate fewer queries for getting the same data, giving a performance boost.
>
> ```abap Bad theme={"theme":"css-variables"}
> SELECT carrid , connid , seatsocc FROM flights
> INTO TABLE seatsocc_tab
> FOR ALL ENTRIES IN conn_tab
> WHERE carrid = conn_tab-carrid
> AND connid = conn_tab-connid.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> SORT conn_tab BY carrid.
> DELETE ADJACENT DUPLICATES FROM conn_tab COMPARING carrid.
> ...
> SELECT carrid , connid , seatsocc FROM flights
> INTO TABLE seatsocc_tab
> FOR ALL ENTRIES IN conn_tab
> WHERE carrid = conn_tab-carrid
> AND connid = conn_tab-connid.
> ```

> [accordion] EXIT and CHECK statements should not be used in SELECT loops
>
> Using `EXIT and CHECK in SELECT statements to stop the execution of SELECT loop is an expensive and ineffective way to filter data. Filtering should be part of the SELECT loop themselves. Most of the time conditions located in a CHECK statement should be moved to the WHERE clause, and the EXIT statement should typically be replaced by an UP TO 1 ROW` clause.
>
> ```abap Bad theme={"theme":"css-variables"}
> SELECT * FROM SBOOK INTO SBOOK_WA.
> CHECK: SBOOK_WAS-CARRID = 'LH' AND SBOOK_WAS-CONNID = '0400'. "Noncompliant
> ENDSELECT.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> SELECT * FROM SBOOK INTO SBOOK_WA WHERE CARRID = 'LH' AND CONNID = '0400'.
> ENDSELECT.
> ```

> [accordion] SORTED or HASHED internal tables should be accessed with a key
>
> Internal tables can quickly become a source of performance problems if not accessed correctly, `SORTED and HASHED` tables should always be accessed with the appropriate key or partial key.
>
> ```abap Bad theme={"theme":"css-variables"}
> READ TABLE it INTO work_area INDEX 1.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> READ TABLE it INTO work_area WITH KEY color = 'RED'.
> ```

> [accordion] Sort fields should be provided for an internal table sort
>
> Internal tables can be sorted without specifying the specific fields on which to sort. However, doing so is inefficient because when a sort key is not specified, the entire row is used in the sort, which can be markedly inefficient.
>
> ```abap Bad theme={"theme":"css-variables"}
> SORT ITAB.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> SORT ITAB BY LAND WEIGHT.
> ```

> [accordion] Forms should be documented
>
> Every subroutine(`FORM`) should be commented to explain its goal and how it works. This comment can be located just before or after the form definition.
>
> ```abap Bad theme={"theme":"css-variables"}
> FORM my_form.
> ...
> ENDFORM
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> * here is  
> * my comment
> FORM my_form.
> ...
> ENDFORM
> ```

> [accordion] Authorization checks should not rely on hardcoded user properties
>
> Checking logged users' permissions by comparing their name to a hardcoded string can create security vulnerabilities. It prevents system administrators from changing users' permissions when needed (example: when their account has been compromised). Thus system fields \`SY-UNAME and SYST-UNAME should not be compared to hardcoded strings. Use instead AUTHORITY-CHECK to check users' permissions.
>
> This rule raises an issue when either of the system fields SY-UNAME or SYST-UNAME are compared to a hardcoded value in a CASE statement or using one of the following operators: =, EQ, \<>, NE\`.
>
> ```abap Bad theme={"theme":"css-variables"}
> IF SY-UNAME = 'ALICE'. " Noncompliant
> ENDIF.
>
> CASE SY-UNAME.
> WHEN 'A'. " Noncompliant
> ENDCASE.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> AUTHORITY-CHECK OBJECT 'S_CARRID' 
> ID 'CARRID' FIELD mycarrid.
> IF sy-subrc <> 0. 
> MESSAGE 'Not authorized' TYPE 'E'. 
> ENDIF.
> ```

> [accordion] Mass operations should be used with internal tables instead of loops
>
> When several lines must be inserted/updated into an internal table, instead of doing those changes line by line, mass operations should be used because they offer better performance  by design.
>
> This rule raises an issue when a single line operation like `APPEND, CONCATENATE, and INSERT` is performed on an internal table in a loop.
>
> ```abap Bad theme={"theme":"css-variables"}
> LOOP AT ITAB1 INTO WA. 
> APPEND WA TO ITAB2. 
> ENDLOOP.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> APPEND LINES OF ITAB1 TO ITAB2.
> ```

> [accordion] WHEN OTHERS clauses should be last
>
> \`CASE can contain a WHEN OTHERS clause for various reasons: to handle unexpected values, to show that all the cases were properly considered, etc.
>
> For readability purposes, to help a developer quickly spot the default behavior of a CASE statement, it is recommended to put the WHEN OTHERS clause at the end of the CASE statement.
>
> This rule raises an issue if the WHEN OTHERS clause is not the last one of the CASE’s cases.
>
> ```abap Bad theme={"theme":"css-variables"}
> CASE SY-INDEX.
> WHEN OTHERS.   // Noncompliant; WHEN OTHERS should be the last statement
> WRITE 'Unexpected result'
> WHEN ONE.
> WRITE  'One'. 
> WHEN 2.
> WRITE   'Two'.
> ENDCASE.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> ```

> [accordion] System C functions should not be used
>
> According to the SAP documentation:
>
> > System functions are only intended for internal usage. Incompatible changes and further development is possible at any time and without warning or notice.
>
> So calling system C functions using a `CALL` statement should be avoided.
>
> ```abap Bad theme={"theme":"css-variables"}
> CALL 'MULTIPLY' ID 'P1'  FIELD '9999' 
>             ID 'P2'  FIELD '9999' 
>             ID 'RES' FIELD RESULT.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> ```

> [accordion] The operator = should be used to copy the content of an internal table
>
> Using the `= operator to copy the content of an internal table is more efficient than using LOOP + APPEND` statements.
>
> ```abap Bad theme={"theme":"css-variables"}
> REFRESH ITAB2.
> LOOP AT ITAB1 INTO WA.
> APPEND WA TO ITAB2.
> ENDLOOP.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> ITAB2[] = ITAB1[]
> ```

> [accordion] SY-SUBRC should be checked after an AUTHORITY-CHECK statement
>
> Every `AUTHORITY-CHECK statement sets the fields SY-SUBRC (also accessible as SYST-SUBRC) to the authorization check result. Thus SY-SUBRC value should be checked just after every AUTHORITY-CHECK` statement.
>
> ```abap Bad theme={"theme":"css-variables"}
> AUTHORITY-CHECK OBJECT 'S_MYOBJ' "Noncompliant
> ID 'ID1' FIELD myvalue.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> AUTHORITY-CHECK OBJECT 'S_MYOBJ'  "Compliant
> ID 'ID1' FIELD myvalue.
>
> IF sy-subrc <> 0. 
> MESSAGE 'NOT AUTHORIZED' TYPE 'E'. 
> ENDIF.
> ```

> [accordion] CX\_ROOT should not be caught
>
> Because `CX_ROOT is the base exception type, catching it directly probably casts a wider net than you intended. Catching CX_ROOT could mask far more serious system errors that your CATCH` logic was intended to deal with.
>
> Some smaller, more specific exception type should be caught instead.
>
> ```abap Bad theme={"theme":"css-variables"}
> try.
> if ABS( NUMBER ) > 100.
>   write / 'Number is large'.
> endif.
> catch CX_ROOT into OREF.
> write / OREF->GET_TEXT( ).
> endtry.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> try.
> if ABS( NUMBER ) > 100.
>   write / 'Number is large'.
> endif.
> catch CX_SY_ARITHMETIC_ERROR into OREF.
> write / OREF->GET_TEXT( ).
> endtry.
> ```

> [accordion] Subroutine parameters should be passed by reference rather than by value
>
> Passing parameters by reference instead of by value avoids the overhead of making a copy. Passing arguments via copy should only be done when it is technically mandated, as it is for example with RFC function modules.
>
> ```abap Bad theme={"theme":"css-variables"}
> PERFORM subr USING a1 a2 a3 a4 a5.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> PERFORM subr CHANGING a1 a2 a3 a4 a5.
> ```

> [accordion] Method parameters should follow a naming convention
>
> Shared naming conventions allow teams to collaborate efficiently. This rule checks that all method parameters follow a naming convention.
>
> ```abap Bad theme={"theme":"css-variables"}
> METHODS m_fact IMPORTING i1  TYPE i
>                    value(i2) TYPE i
>                RETURNING value(factorial) TYPE i.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> METHODS m_fact IMPORTING I_1  TYPE i
>                    value(i2) TYPE i
>                RETURNING value(R_factorial) TYPE i.
> ```

> [accordion] To SELECT, INSERT or DELETE several lines in databases, internal tables should be used in place of loop control structure
>
> Whenever more than one line needs to be read, inserted or deleted from a database table, it is more efficient to work with an internal table than to read, insert or delete the lines one by one inside a loop.
>
> ```abap Bad theme={"theme":"css-variables"}
> LOOP AT TAB INTO TAB_WA.
> INSERT INTO CUSTOMERS VALUES TAB_WA.
> ENDLOOP.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> INSERT CUSTOMERS FROM TABLE TAB.
> ```

> [accordion] CASE statements should have at least 3 WHEN clauses
>
> \`CASE statements are useful when there are many different cases depending on the value of the same expression.
>
> For just one or two cases however, the code will be more readable with IF\` statements.
>
> ```abap Bad theme={"theme":"css-variables"}
> CASE SY-INDEX.
> WHEN ONE.
> WRITE  'One'.
> WHEN 2.
> WRITE  'Two'.
> ENDCASE.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> CASE SY-INDEX.
> WHEN ONE.
> WRITE  'One'.
> WHEN 2.
> WRITE  'Two'.
> WHEN OTHERS.
> WRITE 'Unexpected result'
> ENDCASE.
> ```

> [accordion] IF ... ELSEIF constructs should end with ELSE clauses
>
> This rule applies whenever an \`IF statement is followed by one or
>
> more ELSEIF statements; the final ELSEIF should be followed by an ELSE statement.
>
> The requirement for a final ELSE statement is defensive programming.
>
> The ELSE statement should either take appropriate action or contain
>
> a suitable comment as to why no action is taken. This is consistent with the
>
> requirement to have a final OTHERS clause in a CASE\`
>
> statement.
>
> ```abap Bad theme={"theme":"css-variables"}
> IF RESULT > 0.
> PERFORM do_something.
> ELSEIF RESULT = 0.
> PERFORM do_something_else.
> ENDIF.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> IF RESULT > 0.
> PERFORM do_something.
> ELSEIF RESULT = 0.
> PERFORM do_something_else.
> ELSE.
> PERFORM error.
> ENDIF.
> ```

> [accordion] DATA BEGIN OF OCCURS should not be used
>
> `DATA BEGIN OF ... OCCURS` has been deprecated and will eventually be removed. All usages should be replaced.
>
> ```abap Bad theme={"theme":"css-variables"}
> DATA BEGIN OF itab OCCURS n. "Noncompliant
> ... 
> DATA END OF itab [VALID BETWEEN intlim1 AND intlim2].
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> DATA BEGIN OF wa. 
>    ... 
> DATA END OF wa. 
> DATA itab LIKE TABLE OF wa.
> ```

> [accordion] Method names should comply with a naming convention
>
> Shared naming conventions allow teams to collaborate efficiently.
>
> This rule raises an issue when a method name does not match a provided regular expression.
>
> For example, with the default provided regular expression ^(\[A-Z0-9\_]*|\[a-z0-9\_]*)\$, the method:
>
> ```abap Bad theme={"theme":"css-variables"}
> METHOD MyMethod "Noncompliant
> ...
> ENDMETHOD.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> METHOD MY_METHOD
> ...
> ENDMETHOD.
> ```

> [accordion] Control flow statements IF, CASE, DO, LOOP, SELECT, WHILE and PROVIDE should not be nested too deeply
>
> Nested control flow statements `IF, CASE, DO, LOOP, SELECT, WHILE and PROVIDE`  are often key ingredients in creating
> what’s known as "Spaghetti code". This code smell can make your program difficult to understand and maintain.
>
> When numerous control structures are placed inside one another, the code becomes a tangled, complex web.
> This significantly reduces the code’s readability and maintainability, and it also complicates the testing process.
>
> ```abap Bad theme={"theme":"css-variables"}
> IF param1 = 2.
> IF param2 = 4.
> DO 3 TIMES.    "Compliant - depth = 3, not exceeding the limit
>   IF sy-index = 2.   "Noncompliant - depth = 4
>     CONTINUE.
>   ENDIF.
>   WRITE sy-index.
> ENDDO.
> ENDIF.
> ENDIF.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> ```

> [accordion] Functions should be documented
>
> Every function should be commented to explain its goal and how it works. This non-empty comment must be located before the function definition.
>
> ```abap Bad theme={"theme":"css-variables"}
> FUNCTION my_function.
> ...
> ENDFUNCTION.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> * here is  
> * my comment
> FUNCTION my_function.
> ...
> ENDFUNCTION.
> ```

> [accordion] SY-SUBRC should be tested after each statement setting it.
>
> The system field \`SY-SUBRC must be tested immediately after any statement setting this variable. Reading this variable informs on previous operation success or errors. Such errors should be handled properly so that the program continues in a consistent state.
>
> This rule raises an issue when the field SY-SUBRC is not checked just after performing one of the following operations:
>
> <ul>
>   <li>
>     Calling a function or method which can throw exceptions.
>   </li>
>
>   <li>
>     Calling one of the file access operation OPEN DATASET, READ DATASET or DELETE DATASET.
>   </li>
> </ul>
>
> SY-SUBRC check must be done either with the CASE, IF or CHECK\` statement.
>
> ```abap Bad theme={"theme":"css-variables"}
> CALL FUNCTION 'STRING_SPLIT'
> EXPORTING
> DELIMITER = ':'
> STRING = FELD
> IMPORTING
> HEAD =   HEAD
> TAIL = TAIL
> EXCEPTIONS
> NOT_FOUND = 1
> OTHERS = 2.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> CALL FUNCTION 'STRING_SPLIT'
> EXPORTING
> DELIMITER = ':'
> STRING = FELD
> IMPORTING
> HEAD =   HEAD
> TAIL = TAIL
> EXCEPTIONS
> NOT_FOUND = 1
> OTHERS = 2.
> CASE SY-SUBRC.
> WHEN 1. ...
> WHEN 2. ...
> WHEN OTHER.
> ENDCASE.
> ```

> [accordion] REFRESH itab should not be used
>
> This statement deletes all rows of an internal table itab. This `REFRESH` statement is deprecated and usage should be avoided.
>
> ```abap Bad theme={"theme":"css-variables"}
> REFRESH itab.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> CLEAR itab.
> ```

> [accordion] Form names should comply with a naming convention
>
> Naming conventions are an important tool in efficient team collaboration. This rule checks that all form names match a regular expression naming convention.
>
> ```abap Bad theme={"theme":"css-variables"}
> FORM MyForm. 
> ...
> ENDFORM.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> FORM MY_FORM. 
> ...
> ENDFORM.
> ```

> [accordion] SQL UPDATE dbtab SET ... statements should have a WHERE clause
>
> `UPDATE dbtab SET ... without a WHERE condition changes all the entries of the table. Check whether dataset to be changed can be limited by a suitable WHERE` condition.
>
> ```abap Bad theme={"theme":"css-variables"}
> UPDATE COUNTRIES SET NAME=country_name.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> UPDATE COUNTRIES SET NAME=country_name WHERE CODE=country_code.
> ```

> [accordion] Keywords should not be used as variable names
>
> Using keywords as variable names may yield incomprehensible code, and should be avoided.
>
> ```abap Bad theme={"theme":"css-variables"}
> DATA:  wa_struct TYPE struct,
>    name       TYPE string,
>    dob          TYPE string,
>    aliases     TYPE string,    " ALIASES is a keyword
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> DATA:  wa_struct TYPE struct,
>    name         TYPE string,
>    dob            TYPE string,
>    alt_names  TYPE string,
> ```

> [accordion] Empty driver tables should not be used in a SELECT/FOR ALL ENTRIES clause
>
> Using an empty driver table in a `SELECT/FOR ALL ENTRIES table has a very important side effect: the complete WHERE clause is not taken into account because a NO WHERE` condition is generated. Thus a full table scan is unexpectedly executed.
>
> ```abap Bad theme={"theme":"css-variables"}
> SELECT carrid , connid , seatsocc FROM flights
> INTO TABLE seatsocc_tab
> FOR ALL ENTRIES IN conn_tab  " Noncompliant; conn_tab may be empty.
> WHERE carrid = conn_tab-carrid
> AND connid = conn_tab-connid.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> IF conn_tab is not initial.
> " ...
> SELECT carrid , connid , seatsocc FROM flights
> INTO TABLE seatsocc_tab
> FOR ALL ENTRIES IN conn_tab
> WHERE carrid = conn_tab-carrid
> AND connid = conn_tab-connid.
> " ...
> ENDIF.
> ```

> [accordion] Macros should be documented
>
> Every macro should be commented to explain its goal and how it works. This comment can be located just before or after the macro definition.
>
> ```abap Bad theme={"theme":"css-variables"}
> DEFINE my_macro.
> ...
> END-OF-DEFINITION.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> * here is  
> * my comment
> DEFINE my_macro.
> ...
> END-OF-DEFINITION.
> ```

> [accordion] Internal source code processing statements should not be used
>
> ABAP provides the ability to manipulate programs dynamically during execution for instance with statements like \`INSERT REPORT and GENERATE SUBROUTINE POOL. Most of those statements are for internal use within SAP Technology Development and incompatible changes are possible at any time without prior warning or notice.
>
> This rule raises an issue when any of the following source code processing statements is used: INSERT REPORT,  READ REPORT, DELETE REPORT, EDITOR-CALL FOR REPORT, SYNTAX-CHECK FOR itab, GENERATE REPORT/SUBROUTINE POOL, LOAD REPORT, SCAN, INSERT TEXTPOOL, READ TEXTPOOL, DELETE TEXTPOOL, EXPORT DYNPRO, IMPORT DYNPRO, DELETE DYNPRO, SYNTAX-CHECK FOR DYNPRO, and GENERATE DYNPRO\`.
>
> ```abap Bad theme={"theme":"css-variables"}
> GENERATE REPORT MY_PROG.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> ```

> [accordion] DELETE FROM dbtab statements should have a WHERE clause
>
> `DELETE FROM dbtab without a WHERE` condition deletes all the entries of the table. Check whether dataset to be deleted can be limited by a suitable WHERE condition.
>
> ```abap Bad theme={"theme":"css-variables"}
> DELETE FROM COUNTRIES.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> DELETE FROM COUNTRIES WHERE CODE = country_code.
> ```

> [accordion] Using CALL TRANSACTION statements without an authority check is security-sensitive
>
> " statements without an authority check is security sensitive. Its access should be restricted to specific users.
>
> This rule raises when a \`CALL TRANSACTION has no explicit authorization check, i.e. when:
>
> <ul>
>   <li>
>     the CALL TRANSACTION statement is not followed by WITH AUTHORITY-CHECK.
>   </li>
>
>   <li>
>     the CALL TRANSACTION statement is not following an AUTHORITY-CHECK statement.
>   </li>
>
>   <li>
>     the CALL TRANSACTION statement is not following a call to the AUTHORITY\_CHECK\_TCODE\` function.
>   </li>
> </ul>
>
> ```abap Bad theme={"theme":"css-variables"}
> AUTHORITY-CHECK OBJECT 'S_DIAGID'
>               ID 'ACTVT' FIELD '03'.
> IF sy-subrc <> 0.
> " show an error message...
> ENDIF.
>
> CALL TRANSACTION 'MY_DIALOG'. " Ok but obsolete since ABAP 7.4.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> CALL FUNCTION 'AUTHORITY_CHECK_TCODE'
> exporting
> tcode  = up_fdta
> exceptions
> ok     = 0
> others = 4.
> IF sy-subrc <> 0.
> " show an error message...
> ENDIF.
>
> CALL TRANSACTION up_fdta USING up_bdc mode 'E'. " Ok but obsolete since ABAP 7.4.
> ```

> [accordion] REFRESH itab FROM TABLE should not be used
>
> This variant of the \`REFRESH statement is deprecated and should be avoided.
>
> This REFRESH statement initializes the internal table itab, reads several rows from the database table dbtab, and adds their contents to the internal table itab. A SELECT\` statement should be used instead.
>
> ```abap Bad theme={"theme":"css-variables"}
> TABLES t100. 
> DATA itab TYPE STANDARD TABLE OF t100.
>
> t100-sprsl = 'E'. 
> t100-arbgb = 'BC'.
>
> REFRESH itab FROM TABLE t100.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> DATA itab TYPE STANDARD TABLE OF t100.
>
> SELECT * 
>    FROM t100 
>    INTO TABLE itab 
>    WHERE sprsl = 'E' AND 
>          arbgb LIKE 'BC%'.
> ```

> [accordion] SQL aggregate functions should not be used to prevent bypassing the SAP buffer
>
> `SQL COUNT(..), MIN(..), MAX(..), SUM(..), AVG(..)` aggregate functions cause the SAP table buffer to be bypassed, so the use of these functions can lead to performance issues.
>
> ```abap Bad theme={"theme":"css-variables"}
> SELECT COUNT(*) 
>    FROM persons 
>    INTO count 
>    WHERE city = 'NEW YORK'.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> ```

> [accordion] All branches in a conditional structure should not have exactly the same implementation
>
> Having all branches of a CASE or IF chain with the same implementation indicates a problem.
>
> In the following code:
>
> ```abap Bad theme={"theme":"css-variables"}
> IF a >0.  "Noncompliant
> doSomething.
> ELSE IF b> 0.
> doSomething.
> ELSE.
> doSomething.
> ENDIF.
>
> CASE i.  "Noncompliant
> WHEN 1 OR 3.
> doSomething.
> WHEN 2.
> doSomething.
> WHEN OTHERS.
>     doSomething.
> ENDCASE.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> IF a >0.   "no issue, this could have been done on purpose to make the code more readable
> doSomething.
> ELSEIF b> 0.
> doSomething.
> ENDIF.
> ```

> [accordion] Unnecessary chain syntax should not be used
>
> When there is only one statement in a chain, the chain syntax can be omitted, which simplifies the code.
>
> ```abap Bad theme={"theme":"css-variables"}
> CLEAR: w_alvvr.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> CLEAR w_alvvr.
> ```

> [accordion] Native SQL should not be statically embedded
>
> The \`EXEC SQL ... END-EXEC statement can be used to embed Native SQL statically in ABAP programs.
>
> According to the SAP documentation:
>
> > Alongside ADBC, it is also possible to embed Native SQL statically between EXEC SQL and ENDEXEC\` in ABAP programs. The recommendation, however, is to use ADBC. While the static embedding of Native SQL offers exclusively static access to the Native SQL interface, ADBC makes modern object-orientated and dynamic access possible. New developments and improvements, such as optimized performance using bulk access across internal tables, are now made only for ADBC.
> >
> > The existing static embedding of Native SQL statements is still supported but should no longer be used in new programs.
>
> ```abap Bad theme={"theme":"css-variables"}
> EXEC SQL.
>   CREATE TABLE abap_docu_demo_mytab (
>            val1 char(10) NOT NULL,
>            val2 char(10) NOT NULL,
>            PRIMARY KEY (val1)      )
> ENDEXEC.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> NEW cl_sql_statement( )->execute_ddl(
>   `CREATE TABLE ` && dbname   &&
>   `( val1 char(10) NOT NULL,` &&
>   `  val2 char(10) NOT NULL,` &&
>   `  PRIMARY KEY (val1) )` ).
> ```

> [accordion] %\_HINTS should not be used
>
> ABAP hints can be used to override the default behavior of the SAP Cost Based Optimizer (CBO). When the execution plan provided by the CBO is not optimal, it is possible to "drive" the CBO by providing the main index to be used to filter rows.
>
> Such optimizations are not portable from one database to another, such as when migrating from Oracle to DB2. Therefore hard coding an optimization should be done only when it is strongly indicated.
>
> ```abap Bad theme={"theme":"css-variables"}
> select MY_COLUMN 
> into it_data
> from MY_TABLE
> WHERE FILTERING_COLUMN = '0'
> %_HINTS ORACLE 'INDEX("MY_TABLE" "MY_INDEX")'.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> ```

> [accordion] Operational statements should not be chained
>
> The main reason for using chained statements is to increase readability, but when used with operational statements, chaining can have the opposite effect. Even worse, it can lead to unexpected program behavior.
>
> ```abap Bad theme={"theme":"css-variables"}
> TRY. 
>  ... 
> CATCH: cx_1, cx_2, cx_3.  " only cx_3 gets the following CATCH block
>  "exception handling 
>   ... 
> ENDTRY.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> TRY. 
>  ... 
> CATCH cx_1.
>  "exception handling 
> CATCH cx_2.
>  "exception handling 
> CATCH cx_3. 
>  "exception handling 
>   ... 
> ENDTRY.
> ```

> [accordion] Open SQL SELECT statements should have an ORDER BY clause
>
> An Open SQL `SELECT statement without an explicit ORDER BY clause will retrieve rows in an unpredictable order. On pool/cluster tables, the current implementation of Open SQL SELECT  returns the result set in the primary key order, but that’s not the case for transparent tables. That’s why it’s safer to always use an ORDER BY` clause.
>
> ```abap Bad theme={"theme":"css-variables"}
> OPEN CURSOR C FOR SELECT * FROM SBOOK WHERE CARRID = 'LH '. "NonCompliant
> SELECT * FROM FLIGHTS WHERE FLIGHT_NUMBER = 'LH '."NonCompliant
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> OPEN CURSOR C FOR SELECT * FROM SBOOK WHERE CARRID = 'LH '
> ORDER BY PRIMARY KEY.
> SELECT * FROM FLIGHTS WHERE FLIGHT_NUMBER = 'LH ' ORDER BY PRIMARY KEY.
> ```

> [accordion] SELECT SINGLE or Up to 1 ROW should be used when retrieving one record
>
> SAP recommends to keep the result set of any request as small as possible for performance reasons.
>
> A \`SELECT...ENDSELECT request will retrieve multiple records at the same time. Stopping immediately such a request with a CHECK, RETURN or EXIT statement will not reduce the number of retrieved records. If the goal is to retrieve a single record, or check that at least one record exists, it is recommended to add UP TO 1 ROWS or to use SELECT SINGLE.
>
> Even if the request already retrieved only one record, adding UP TO 1 ROWS or to using SELECT SINGLE will make the code easier to read.
>
> This rule raises an issue when a SELECT...ENDSELECT which has neither SINGLE nor UP TO 1 ROWS and:
>
> <ul>
>   <li>
>     contains only one statement and it is a CHECK, RETURN or EXIT\`
>   </li>
>
>   <li>
>     or when it is completely empty.
>   </li>
> </ul>
>
> ```abap Bad theme={"theme":"css-variables"}
> SELECT * FROM sbook INTO ls_book WHERE carrid EQ l_carrid.
> EXIT.
> ENDSELECT.
> IF sy-subrc NE 0.
> WRITE:/ 'NO RECORD FOUND'.
> ENDIF.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> SELECT SINGLE * sbook INTO ls_book WHERE carrid EQ l_carrid.
> IF sy-subrc NE 0.
> WRITE:/ 'NO RECORD FOUND'.
> ENDIF.
> ```

> [accordion] CASE statements should have WHEN OTHERS clauses
>
> The requirement for an `OTHERS` clause is defensive programming. The clause should either take appropriate action, or contain a suitable comment as to why no action is taken.
>
> ```abap Bad theme={"theme":"css-variables"}
> CASE SY-INDEX.   // Noncompliant; missing WHEN OTHERS clause
> WHEN ONE.
> WRITE  'One'. 
> WHEN 2.
> WRITE   'Two'.
> ENDCASE.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> CASE SY-INDEX. 
> WHEN ONE.
> WRITE  'One'. 
> WHEN 2.
> WRITE   'Two'.
> WHEN OTHERS. // Compliant
> WRITE 'Unexpected result'
> ENDCASE.
>
> CASE SY-INDEX.
> WHEN OTHERS.   // Compliant
> WRITE 'Unexpected result'
> WHEN ONE.
> WRITE  'One'. 
> WHEN 2.
> WRITE   'Two'.
> ENDCASE.
> ```

> [accordion] SQL DISTINCT operator should not be used to prevent bypassing the SAP buffering
>
> `DISTINCT operator causes the SELECT` statement to avoid the SAP buffering and to read directly from the database and not from the buffer on the application server.
>
> ```abap Bad theme={"theme":"css-variables"}
> SELECT DISTINCT carrid
>    FROM spfli 
>    INTO count 
>    WHERE cityto = 'NEW YORK'.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> ```

> [accordion] Statements should be on separate lines
>
> Putting multiple statements on a single line lowers the code readability and makes debugging the code more complex.
>
> Unresolved directive in \<stdin> - include::\{noncompliant}\[]
>
> Write one statement per line to improve readability.
>
> Unresolved directive in \<stdin> - include::\{compliant}\[]
>
> ```abap Bad theme={"theme":"css-variables"}
> WRITE 'Hello '. WRITE 'World'. "Noncompliant
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> WRITE 'Hello '.
> WRITE 'World'.
> ```

> [accordion] Exception handlers should preserve the original exceptions
>
> When handling a caught exception, the original exception’s message and stack trace should be logged or passed forward.
>
> ```abap Bad theme={"theme":"css-variables"}
> try.
> if ABS( NUMBER ) > 100.
>   write / 'Number is large'.
> endif.
> catch CX_SY_ARITHMETIC_ERROR into OREF.
> endtry.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> try.
> if ABS( NUMBER ) > 100.
>   write / 'Number is large'.
> endif.
> catch CX_SY_ARITHMETIC_ERROR into OREF.
> write / OREF->GET_TEXT( ).
> endtry.
> ```

> [accordion] Magic numbers should not be used
>
> Magic numbers make the code more complex to understand as it requires the reader to have knowledge about the global context to understand the number itself.
> Their usage may seem obvious when writing the code, but it may not be the case for another developer or later once the context faded away.
> -1, 0, and 1 are not considered magic numbers.
>
> ```abap Bad theme={"theme":"css-variables"}
> IF sy-subrc EQ 42.      " Noncompliant - 5 is a magic number
> screen-request = 'OK'.
> ENDIF.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> answer = 42.
> IF sy-subrc EQ answer.  " Compliant
> screen-request = 'OK'.
> ENDIF.
> ```

> [accordion] SQL EXISTS subqueries should not be used
>
> SQL queries that use `EXISTS subqueries are inefficient because the subquery is re-run for every row in the outer query’s table. There are more efficient ways to write most queries, ways that do not use the EXISTS` condition.
>
> ```abap Bad theme={"theme":"css-variables"}
> SELECT name
> FROM employee
> WHERE EXISTS (SELECT * FROM department WHERE department_id = id AND name = 'Marketing');
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> SELECT name
> FROM employee INNER JOIN department AS d
> ON department_id = d.id AND d.name = 'Marketing';
> ```

> [accordion] Mergeable if statements should be combined
>
> Nested code - blocks of code inside blocks of code - is eventually necessary, but increases complexity. This is why keeping the code as flat as possible, by avoiding unnecessary nesting, is considered a good practice.
>
> Merging if statements when possible will decrease the nesting of the code and improve its readability.
>
> ```abap Bad theme={"theme":"css-variables"}
> IF something.
> IF somethingElse.             " Noncompliant
> WRITE / 'hello'.
> ENDIF.
> ENDIF.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> IF something and somethingElse. " Compliant
> WRITE / 'hello'.
> ENDIF.
> ```

> [accordion] Macro names should comply with a naming convention
>
> Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that all macro names match a provided regular expression.
>
> ```abap Bad theme={"theme":"css-variables"}
> DEFINE MyMacro.
> ...
> END-OF-DEFINITION.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> DEFINE my_macro.
> ...
> END-OF-DEFINITION.
> ```

> [accordion] Redundant pairs of parentheses should be removed
>
> The use of parentheses, even those not required to enforce a desired order of operations, can clarify the intent behind a piece of code. However, redundant pairs of parentheses could be misleading and should be removed.
>
> ```abap Bad theme={"theme":"css-variables"}
> CHECK (SY-SUBRC NE 0). "compliant even if ignored by compiler
> IF ((SY-SUBRC EQ 0)). "Noncompliant
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> CHECK (SY-SUBRC NE 0).
> IF (SY-SUBRC EQ 0).
> ```

> [accordion] Using shell interpreter when executing OS commands is security-sensitive
>
> Arbitrary OS command injection vulnerabilities are more likely when a shell is spawned rather than a new process, indeed shell meta-chars can be used (when parameters are user-controlled for instance) to inject OS commands.
>
> ```abap Bad theme={"theme":"css-variables"}
> CALL 'SYSTEM' ID 'COMMAND' FIELD "/usr/bin/file.exe" ID 'TAB' FIELD TAB1.  " Compliant
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> ```

> [accordion] Related if/else if statements should not have the same condition
>
> A chain of if/else if statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to true.
>
> Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it’s simply dead code and at worst, it’s a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.
>
> ```abap Bad theme={"theme":"css-variables"}
> if param = 1.
> Statement.
> elseif param = 2.
> Statement.
> elseif param = 1.  // Noncompliant
> Statement.
> endif.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> if param = 1.
> Statement.
> elseif param = 2.
> Statement.
> elseif param = 3.
> Statement.
> endif.
> ```

> [accordion] Class names should comply with a naming convention
>
> Shared naming conventions allow teams to collaborate efficiently.
>
> This rule raises an issue when a class name does not match a provided regular expression.
>
> ```abap Bad theme={"theme":"css-variables"}
> CLASS MyClass DEFINITION. "Noncompliant
> ...
> ENDCLASS.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> CLASS MY_CLASS DEFINITION.
> ...
> ENDCLASS.
> ```

> [accordion] DATA variable names should comply with a naming convention
>
> Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that all variable names match a provided regular expression.
>
> ```abap Bad theme={"theme":"css-variables"}
> DATA: MyText TYPE string.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> DATA: my_text TYPE string.
> ```

> [accordion] String literals should not be duplicated
>
> Duplicated string literals make the process of refactoring complex and error-prone, as any change would need to be propagated on all occurrences.
>
> ```abap Bad theme={"theme":"css-variables"}
> WRITE: / 'Firstname'.
> *...
> WRITE: / 'Firstname'.
> *...
> WRITE: / 'Firstname'.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> CONSTANTS: fname    TYPE c LENGTH 9 VALUE 'Firstname',
>
> WRITE: / fname.
> *...
> WRITE: / fname.
> *...
> WRITE: / fname.
> ```

> [accordion] switch case clauses should not have too many lines of code
>
> The `switch statement should be used only to clearly define some new branches in the control flow. As soon as a case clause contains too many statements this highly decreases the readability of the overall control flow statement. In such case, the content of the case` clause should be extracted into a dedicated method.
>
> ```abap Bad theme={"theme":"css-variables"}
> CASE SY-INDEX.
> WHEN ONE. // 6 lines till next WHEN
> PERFORM sub1.
> PERFORM sub2.
> PERFORM sub3.
> PERFORM sub4.
> PERFORM sub5.
> WHEN 2.
> ...
> ENDCASE.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> CASE SY-INDEX.
> WHEN ONE. 
> PERFORM extractedSub.
> WHEN 2.
> ...
> ENDCASE.
>
> ...
>
> FORM extractedSub.
> PERFORM sub1.
> PERFORM sub2.
> PERFORM sub3.
> PERFORM sub4.
> PERFORM sub5.
> ENDFORM.
> ```

> [accordion] Function names should comply with a naming convention
>
> Shared coding conventions allow teams to collaborate efficiently. This rule checks that all function names match a provided regular expression.
>
> ```abap Bad theme={"theme":"css-variables"}
> FUNCTION MyFunction. 
> ...
> ENDFUNCTION.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> FUNCTION MY_FUNCTION. 
> ...
> ENDFUNCTION.
> ```

> [accordion] Using hardcoded IP addresses is security-sensitive
>
> Hardcoding IP addresses is security-sensitive. It has led in the past to the following vulnerabilities:
>
> <ul>
>   <li>
>     [CVE-2006-5901](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-5901)
>   </li>
>
>   <li>
>     [CVE-2005-3725](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2005-3725)
>   </li>
> </ul>
>
> Today’s services have an ever-changing architecture due to their scaling and redundancy needs. It is a mistake to think that a service will always have the same IP address. When it does change, the hardcoded IP will have to be modified too. This will have an impact on the product development, delivery, and deployment:
>
> <ul>
>   <li>
>     The developers will have to do a rapid fix every time this happens, instead of having an operation team change a configuration file.
>   </li>
>
>   <li>
>     It misleads to use the same address in every environment (dev, sys, qa, prod).
>   </li>
> </ul>
>
> Last but not least it has an effect on application security. Attackers might be able to decompile the code and thereby discover a potentially sensitive address. They can perform a Denial of Service attack on the service, try to get access to the system, or try to spoof the IP address to bypass security checks. Such attacks can always be possible, but in the case of a hardcoded IP address solving the issue will take more time, which will increase an attack’s impact.
>
> ```abap Bad theme={"theme":"css-variables"}
> READ DATASET file INTO ip MAXIMUM LENGTH len.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> ```

> [accordion] Interface names should comply with a naming convention
>
> Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that all interface names match a provided regular expression.
>
> ```abap Bad theme={"theme":"css-variables"}
> INTERFACE MyInterface. "Noncompliant
> ...
> ENDINTERFACE.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> INTERFACE YIF_myinterface. 
> ...
> ENDINTERFACE.
> ```

> [accordion] Unused local variables should be removed
>
> An unused local variable is a variable that has been declared but is not used anywhere in the block of code where it is defined. It is dead code, contributing to unnecessary complexity and leading to confusion when reading the code. Therefore, it should be removed from your code to maintain clarity and efficiency.
>
> ```abap Bad theme={"theme":"css-variables"}
> FUNCTION f.
> DATA: LOCAL_1 LIKE BAR.
> DATA: LOCAL_2 LIKE BAR. "Noncompliant - LOCAL_2 is unused
>
> SELECT * FROM LOCAL_1.
>
> ENDFUNCTION.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> FUNCTION f.
> DATA: LOCAL_1 LIKE BAR.
>
> SELECT * FROM LOCAL_1.
>
> ENDFUNCTION.
> ```

> [accordion] Source code should be indented consistently
>
> Consistent indentation is a simple and effective way to improve the code’s readability.
> It reduces the differences that are committed to source control systems, making code reviews easier.
>
> This rule raises an issue when the indentation does not match the configured value.
> Only the first line of a badly indented section is reported.
>
> ```abap Bad theme={"theme":"css-variables"}
> CLASS counter IMPLEMENTATION.
> METHOD set.
> count = set_value.   " Noncompliant, expected to start at column 4
> ENDMETHOD.       " Noncompliant, expected to start at column 2
> METHOD increment.
> ADD 1 TO count.
> ENDMETHOD.
> METHOD get.
> get_value = count.
> ENDMETHOD.           " Noncompliant, expected to start at column 2
> ENDCLASS.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> CLASS counter IMPLEMENTATION.
> METHOD set.
> count = set_value. 
> ENDMETHOD.  
> METHOD increment.
> ADD 1 TO count.
> ENDMETHOD.
> METHOD get.
> get_value = count.
> ENDMETHOD.      
> ENDCLASS.
> ```

> [accordion] Two branches in a conditional structure should not have exactly the same implementation
>
> Having two WHEN in a CASE statement or two branches in an IF chain  with the same implementation is at best duplicate code, and at worst a coding error.
>
> ```abap Bad theme={"theme":"css-variables"}
> IF a >= 0 AND a < 10.
> doFirst.
> doTheThing.
> ELSEIF a >= 10 AND a < 20.
> doTheOtherThing.
> ELSEIF a >= 20 AND a < 50.
> doFirst.       // Noncompliant; duplicates first condition
> doTheThing.
> ENDIF.
> ```
>
> ```abap Fix theme={"theme":"css-variables"}
> IF (a >= 0 AND a < 10) OR (a >= 20 AND a < 50).
> doFirst.
> doTheThing.
> ELSEIF a >= 10 AND a < 20.
> doTheOtherThing.
> ENDIF.
> ```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.