> ## 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

<AccordionGroup>
  <Accordion title="BREAK-POINT statement should not be used in production">
    <div class="paragraph">
      <p>A <code>BREAK-POINT</code> 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.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      IF wv_parallel EQ 'X'.
      BREAK-POINT.  
      WAIT UNTIL g_nb_return EQ wv_nb_call.
      ENDIF.
      ```

      ```abap Fix theme={null}
      IF wv_parallel EQ 'X'.
      WAIT UNTIL g_nb_return EQ wv_nb_call.
      ENDIF.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Jump statements should not be redundant">
    <div class="paragraph">
      <p>Jump statements, such as <code>CHECK and CONTINUE</code> 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.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      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={null}
      LOOP AT myTable.
      PERFORM form_open USING ...
      CHECK retcode = 0.
      ...
      PERFORM form_close.
      ENDLOOP.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="An internal table should be sorted before duplicates are deleted">
    <div class="paragraph">
      <p>Calling <code>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</code> part of the command looks for multiple rows side-by-side with the same content.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      DELETE ADJACENT DUPLICATES FROM ITAB COMPARING LAND.
      ```

      ```abap Fix theme={null}
      SORT ITAB BY LAND.
      DELETE ADJACENT DUPLICATES FROM ITAB COMPARING LAND.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="FORM... ENDFORM and PERFORM should not be used">
    <div class="paragraph">
      <p>Procedural development in general, and <code>FORM... ENDFORM, and PERFORM</code> specifically, have been been classified as obsolete by SAP and should be avoided. Classes and methods should be used for all new development.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      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={null}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="LOOP ASSIGNING with field-symbols should be used instead of LOOP INTO with MODIFY">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph">
      <p>This rule raises an issue when a LOOP...INTO contains one or more MODIFY\` statements.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      LOOP AT i_bseg INTO wa_bseg.
      ...
      wa_bseg-sgtxt = 'VALUE'.
      MODIFY i_bseg FROM wa_bseg.
      ENDLOOP.
      ```

      ```abap Fix theme={null}
      LOOP AT i_bseg ASSIGNING <fs_bseg>.
      ...
      <fs_bseg>-sgtxt = 'VALUE'.
      ENDLOOP.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Standard tables should be searched using BINARY SEARCH">
    <div class="paragraph">
      <p>The \`READ TABLE ... WITH KEY ... statement performs a linear search of STANDARD tables, which is very inefficient in most cases.</p>
    </div>

    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      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={null}
      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
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="SAP standard tables should not be modified via Open SQL statements">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph">
      <p>Instead, the use of standard functions or SAP Business Add-Ins (BAdIs) is recommended.</p>
    </div>

    <div class="paragraph">
      <p>This rule raises an issue on Open SQL statements <code>INSERT, UPDATE, MODIFY, or SELECT ... FOR UPDATE</code> which target an SAP table, i.e. a table with a name starting with a character between "A" and "X", case insensitive.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      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={null}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="SYSTEM-CALL statement should not be used">
    <div class="paragraph">
      <p>The ABAP documentation is pretty clear on this subject :</p>
    </div>

    <div class="quoteblock">
      <blockquote>
        <div class="paragraph">
          <p>This statement is only for</p>
        </div>

        <div class="paragraph">
          <p>!!! Internal use in SAP Basis development !!!</p>
        </div>

        <div class="paragraph">
          <p>Even within SAP Basis, it may only be used in programs within the ABAP+GUI development group.</p>
        </div>

        <div class="paragraph">
          <p>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.</p>
        </div>

        <div class="paragraph">
          <p>Changes and further development, which may be incompatible, may occur at any time, without warning or notice!</p>
        </div>
      </blockquote>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      SYSTEM-CALL CREATE CLASS c.
      ```

      ```abap Fix theme={null}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Expressions should not be too complex">
    <div class="paragraph">
      <p>The complexity of an expression is defined by the number of <code>AND, OR, XOR and EQUIV</code> operators it contains.</p>
    </div>

    <div class="paragraph">
      <p>A single expression’s complexity should not become too high to keep the code readable.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      IF ((condition1 AND condition2) OR (condition3 AND condition4)) AND condition5.
      ...
      ENDIF.
      ```

      ```abap Fix theme={null}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Subqueries and JOIN clauses should not be used">
    <div class="paragraph">
      <p>\`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.</p>
    </div>

    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      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={null}
      SELECT  carrname
      INTO  TABLE name_tab
      FROM  scarr
      WHERE EXISTS ( select  *
                     FROM  spfli
                     WHERE carrid   =  scarr~carrid AND
                           cityfrom = 'NEW YORK'        ).
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Asterisks should be used for headers and to comment out code">
    <div class="paragraph">
      <p>For readability, SAP recommends that asterisks (<code>\*) only be used to comment out header lines and code. Commentary should be commented using a double quote ("</code>)</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      * GAC -  13 June 13 - output user data
      * WRITE: / 'Firstname'.
      ```

      ```abap Fix theme={null}
      " GAC -  13 June 13 - output user data
      * WRITE: / 'Firstname'.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Driver tables should be sorted before use">
    <div class="paragraph">
      <p>In <code>SELECT ... FOR ALL ENTRIES</code> 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.</p>
    </div>

    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      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={null}
      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
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="SQL BYPASSING BUFFER clause should not be used">
    <div class="paragraph">
      <p>This <code>BYPASSING BUFFER clause explicitly switches off SAP table buffering, so the SELECT</code> reads data directly from the database.</p>
    </div>

    <div class="paragraph">
      <p>By definition, using this clause can lead to performance issues, which is why its use must be strongly indicated.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      SELECT * 
      INTO US_PERSONS
      FROM PERSONS
      BYPASSING BUFFER
      WHERE CITY EQ 'US'
      ```

      ```abap Fix theme={null}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Loops should not contain more than a single CONTINUE, EXIT, CHECK statement">
    <div class="paragraph">
      <p>Restricting the number of \`CONTINUE, EXIT and CHECK statements in a loop is done in the interest of good structured programming.</p>
    </div>

    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      DO counter TIMES.
      IF sy-index = 2.
      CONTINUE.
      ENDIF.
      IF sy-index = 10.
      EXIT.
      ENDIF.
      WRITE sy-index.
      ENDDO.
      ```

      ```abap Fix theme={null}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="SELECT INTO TABLE should be used">
    <div class="paragraph">
      <p><code>SELECT INTO TABLE is much more efficient than SELECT ... ENDSELECT. SELECT INTO TABLE</code> 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.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      SELECT * FROM T006 INTO X006_WA.
      ...
      ENDSELECT.
      ```

      ```abap Fix theme={null}
      SELECT * FROM T006 INTO TABLE X006.
      LOOP AT X006 INTO X006_WA.
      ...
      ENDLOOP.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="CATCH clauses should not be empty">
    <div class="paragraph">
      <p>Leaving a <code>CATCH</code> 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.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      try.
      if ABS( NUMBER ) > 100.
        write / 'Number is large'.
      endif.
      catch CX_SY_ARITHMETIC_ERROR into OREF.
      endtry.
      ```

      ```abap Fix theme={null}
      try.
      if ABS( NUMBER ) > 100.
        write / 'Number is large'.
      endif.
      catch CX_SY_ARITHMETIC_ERROR into OREF.
      write / OREF->GET_TEXT( ).
      endtry.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Loops with at most one iteration should be refactored">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      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={null}
      DATA remainder TYPE i. 
      DO 20 TIMES. 
      remainder = sy-index MOD 2. 
      cl_demo_output=>write_text(). 
      ENDDO.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="JOIN should be used instead of nested SELECT statements">
    <div class="paragraph">
      <p><code>SELECT with JOIN</code> always performs better than nested selects.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      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={null}
      SELECT * INTO WA
      FROM SPFLI AS P INNER JOIN SFLIGHT AS F
      ON P~CARRID = F~CARRID AND
          P~CONNID = F~CONNID.
      END-SELECT.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Duplications in driver tables should deleted before the tables are used">
    <div class="paragraph">
      <p>Removing duplicate entries from driver tables enables <code>OPEN SQL</code> to generate fewer queries for getting the same data, giving a performance boost.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      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={null}
      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.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="EXIT and CHECK statements should not be used in SELECT loops">
    <div class="paragraph">
      <p>Using <code>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</code> clause.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      SELECT * FROM SBOOK INTO SBOOK_WA.
      CHECK: SBOOK_WAS-CARRID = 'LH' AND SBOOK_WAS-CONNID = '0400'. "Noncompliant
      ENDSELECT.
      ```

      ```abap Fix theme={null}
      SELECT * FROM SBOOK INTO SBOOK_WA WHERE CARRID = 'LH' AND CONNID = '0400'.
      ENDSELECT.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="SORTED or HASHED internal tables should be accessed with a key">
    <div class="paragraph">
      <p>Internal tables can quickly become a source of performance problems if not accessed correctly, <code>SORTED and HASHED</code> tables should always be accessed with the appropriate key or partial key.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      READ TABLE it INTO work_area INDEX 1.
      ```

      ```abap Fix theme={null}
      READ TABLE it INTO work_area WITH KEY color = 'RED'.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Sort fields should be provided for an internal table sort">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      SORT ITAB.
      ```

      ```abap Fix theme={null}
      SORT ITAB BY LAND WEIGHT.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Forms should be documented">
    <div class="paragraph">
      <p>Every subroutine(<code>FORM</code>) should be commented to explain its goal and how it works. This comment can be located just before or after the form definition.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      FORM my_form.
      ...
      ENDFORM
      ```

      ```abap Fix theme={null}
      * here is  
      * my comment
      FORM my_form.
      ...
      ENDFORM
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Authorization checks should not rely on hardcoded user properties">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph">
      <p>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\`.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      IF SY-UNAME = 'ALICE'. " Noncompliant
      ENDIF.

      CASE SY-UNAME.
      WHEN 'A'. " Noncompliant
      ENDCASE.
      ```

      ```abap Fix theme={null}
      AUTHORITY-CHECK OBJECT 'S_CARRID' 
      ID 'CARRID' FIELD mycarrid.
      IF sy-subrc <> 0. 
      MESSAGE 'Not authorized' TYPE 'E'. 
      ENDIF.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Mass operations should be used with internal tables instead of loops">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph">
      <p>This rule raises an issue when a single line operation like <code>APPEND, CONCATENATE, and INSERT</code> is performed on an internal table in a loop.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      LOOP AT ITAB1 INTO WA. 
      APPEND WA TO ITAB2. 
      ENDLOOP.
      ```

      ```abap Fix theme={null}
      APPEND LINES OF ITAB1 TO ITAB2.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="WHEN OTHERS clauses should be last">
    <div class="paragraph">
      <p>\`CASE can contain a WHEN OTHERS clause for various reasons: to handle unexpected values, to show that all the cases were properly considered, etc.</p>
    </div>

    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph">
      <p>This rule raises an issue if the WHEN OTHERS clause is not the last one of the CASE’s cases.</p>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      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={null}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="System C functions should not be used">
    <div class="paragraph">
      <p>According to the SAP documentation:</p>
    </div>

    <div class="quoteblock">
      <blockquote>
        <div class="paragraph">
          <p>System functions are only intended for internal usage. Incompatible changes and further development is possible at any time and without warning or notice.</p>
        </div>
      </blockquote>
    </div>

    <div class="paragraph">
      <p>So calling system C functions using a <code>CALL</code> statement should be avoided.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      CALL 'MULTIPLY' ID 'P1'  FIELD '9999' 
                  ID 'P2'  FIELD '9999' 
                  ID 'RES' FIELD RESULT.
      ```

      ```abap Fix theme={null}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="The operator = should be used to copy the content of an internal table">
    <div class="paragraph">
      <p>Using the <code>= operator to copy the content of an internal table is more efficient than using LOOP + APPEND</code> statements.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      REFRESH ITAB2.
      LOOP AT ITAB1 INTO WA.
      APPEND WA TO ITAB2.
      ENDLOOP.
      ```

      ```abap Fix theme={null}
      ITAB2[] = ITAB1[]
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="SY-SUBRC should be checked after an AUTHORITY-CHECK statement">
    <div class="paragraph">
      <p>Every <code>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</code> statement.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      AUTHORITY-CHECK OBJECT 'S_MYOBJ' "Noncompliant
      ID 'ID1' FIELD myvalue.
      ```

      ```abap Fix theme={null}
      AUTHORITY-CHECK OBJECT 'S_MYOBJ'  "Compliant
      ID 'ID1' FIELD myvalue.

      IF sy-subrc <> 0. 
      MESSAGE 'NOT AUTHORIZED' TYPE 'E'. 
      ENDIF.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="CX_ROOT should not be caught">
    <div class="paragraph">
      <p>Because <code>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</code> logic was intended to deal with.</p>
    </div>

    <div class="paragraph">
      <p>Some smaller, more specific exception type should be caught instead.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      try.
      if ABS( NUMBER ) > 100.
        write / 'Number is large'.
      endif.
      catch CX_ROOT into OREF.
      write / OREF->GET_TEXT( ).
      endtry.
      ```

      ```abap Fix theme={null}
      try.
      if ABS( NUMBER ) > 100.
        write / 'Number is large'.
      endif.
      catch CX_SY_ARITHMETIC_ERROR into OREF.
      write / OREF->GET_TEXT( ).
      endtry.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Subroutine parameters should be passed by reference rather than by value">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      PERFORM subr USING a1 a2 a3 a4 a5.
      ```

      ```abap Fix theme={null}
      PERFORM subr CHANGING a1 a2 a3 a4 a5.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Method parameters should follow a naming convention">
    <div class="paragraph">
      <p>Shared naming conventions allow teams to collaborate efficiently. This rule checks that all method parameters follow a naming convention.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      METHODS m_fact IMPORTING i1  TYPE i
                         value(i2) TYPE i
                     RETURNING value(factorial) TYPE i.
      ```

      ```abap Fix theme={null}
      METHODS m_fact IMPORTING I_1  TYPE i
                         value(i2) TYPE i
                     RETURNING value(R_factorial) TYPE i.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="To SELECT, INSERT or DELETE several lines in databases, internal tables should be used in place of loop control structure">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      LOOP AT TAB INTO TAB_WA.
      INSERT INTO CUSTOMERS VALUES TAB_WA.
      ENDLOOP.
      ```

      ```abap Fix theme={null}
      INSERT CUSTOMERS FROM TABLE TAB.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="CASE statements should have at least 3 WHEN clauses">
    <div class="paragraph">
      <p>\`CASE statements are useful when there are many different cases depending on the value of the same expression.</p>
    </div>

    <div class="paragraph">
      <p>For just one or two cases however, the code will be more readable with IF\` statements.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      CASE SY-INDEX.
      WHEN ONE.
      WRITE  'One'.
      WHEN 2.
      WRITE  'Two'.
      ENDCASE.
      ```

      ```abap Fix theme={null}
      CASE SY-INDEX.
      WHEN ONE.
      WRITE  'One'.
      WHEN 2.
      WRITE  'Two'.
      WHEN OTHERS.
      WRITE 'Unexpected result'
      ENDCASE.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="IF ... ELSEIF constructs should end with ELSE clauses">
    <div class="paragraph">
      <p>This rule applies whenever an \`IF statement is followed by one or</p>
    </div>

    <div class="paragraph">
      <p>more ELSEIF statements; the final ELSEIF should be followed by an ELSE statement.</p>
    </div>

    <div class="paragraph">
      <p>The requirement for a final ELSE statement is defensive programming.</p>
    </div>

    <div class="paragraph">
      <p>The ELSE statement should either take appropriate action or contain</p>
    </div>

    <div class="paragraph">
      <p>a suitable comment as to why no action is taken. This is consistent with the</p>
    </div>

    <div class="paragraph">
      <p>requirement to have a final OTHERS clause in a CASE\`</p>
    </div>

    <div class="paragraph">
      <p>statement.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      IF RESULT > 0.
      PERFORM do_something.
      ELSEIF RESULT = 0.
      PERFORM do_something_else.
      ENDIF.
      ```

      ```abap Fix theme={null}
      IF RESULT > 0.
      PERFORM do_something.
      ELSEIF RESULT = 0.
      PERFORM do_something_else.
      ELSE.
      PERFORM error.
      ENDIF.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="DATA BEGIN OF OCCURS should not be used">
    <div class="paragraph">
      <p><code>DATA BEGIN OF ... OCCURS</code> has been deprecated and will eventually be removed. All usages should be replaced.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      DATA BEGIN OF itab OCCURS n. "Noncompliant
      ... 
      DATA END OF itab [VALID BETWEEN intlim1 AND intlim2].
      ```

      ```abap Fix theme={null}
      DATA BEGIN OF wa. 
         ... 
      DATA END OF wa. 
      DATA itab LIKE TABLE OF wa.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Method names should comply with a naming convention">
    <div class="paragraph">
      <p>Shared naming conventions allow teams to collaborate efficiently.</p>
    </div>

    <div class="paragraph">
      <p>This rule raises an issue when a method name does not match a provided regular expression.</p>
    </div>

    <div class="paragraph">
      <p>For example, with the default provided regular expression ^(\[A-Z0-9\_]*|\[a-z0-9\_]*)\$, the method:</p>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      METHOD MyMethod "Noncompliant
      ...
      ENDMETHOD.
      ```

      ```abap Fix theme={null}
      METHOD MY_METHOD
      ...
      ENDMETHOD.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Control flow statements IF, CASE, DO, LOOP, SELECT, WHILE and PROVIDE should not be nested too deeply">
    <div class="paragraph">
      <p>Nested control flow statements <code>IF, CASE, DO, LOOP, SELECT, WHILE and PROVIDE</code>  are often key ingredients in creating
      what’s known as "Spaghetti code". This code smell can make your program difficult to understand and maintain.</p>
    </div>

    <div class="paragraph">
      <p>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.</p>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      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={null}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Functions should be documented">
    <div class="paragraph">
      <p>Every function should be commented to explain its goal and how it works. This non-empty comment must be located before the function definition.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      FUNCTION my_function.
      ...
      ENDFUNCTION.
      ```

      ```abap Fix theme={null}
      * here is  
      * my comment
      FUNCTION my_function.
      ...
      ENDFUNCTION.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="SY-SUBRC should be tested after each statement setting it.">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph">
      <p>This rule raises an issue when the field SY-SUBRC is not checked just after performing one of the following operations:</p>
    </div>

    <div class="ulist">
      <ul>
        <li>
          <p>Calling a function or method which can throw exceptions.</p>
        </li>

        <li>
          <p>Calling one of the file access operation OPEN DATASET, READ DATASET or DELETE DATASET.</p>
        </li>
      </ul>
    </div>

    <div class="paragraph">
      <p>SY-SUBRC check must be done either with the CASE, IF or CHECK\` statement.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      CALL FUNCTION 'STRING_SPLIT'
      EXPORTING
      DELIMITER = ':'
      STRING = FELD
      IMPORTING
      HEAD =   HEAD
      TAIL = TAIL
      EXCEPTIONS
      NOT_FOUND = 1
      OTHERS = 2.
      ```

      ```abap Fix theme={null}
      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.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="REFRESH itab should not be used">
    <div class="paragraph">
      <p>This statement deletes all rows of an internal table itab. This <code>REFRESH</code> statement is deprecated and usage should be avoided.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      REFRESH itab.
      ```

      ```abap Fix theme={null}
      CLEAR itab.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Form names should comply with a naming convention">
    <div class="paragraph">
      <p>Naming conventions are an important tool in efficient team collaboration. This rule checks that all form names match a regular expression naming convention.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      FORM MyForm. 
      ...
      ENDFORM.
      ```

      ```abap Fix theme={null}
      FORM MY_FORM. 
      ...
      ENDFORM.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="SQL UPDATE dbtab SET ... statements should have a WHERE clause">
    <div class="paragraph">
      <p><code>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</code> condition.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      UPDATE COUNTRIES SET NAME=country_name.
      ```

      ```abap Fix theme={null}
      UPDATE COUNTRIES SET NAME=country_name WHERE CODE=country_code.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Keywords should not be used as variable names">
    <div class="paragraph">
      <p>Using keywords as variable names may yield incomprehensible code, and should be avoided.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      DATA:  wa_struct TYPE struct,
         name       TYPE string,
         dob          TYPE string,
         aliases     TYPE string,    " ALIASES is a keyword
      ```

      ```abap Fix theme={null}
      DATA:  wa_struct TYPE struct,
         name         TYPE string,
         dob            TYPE string,
         alt_names  TYPE string,
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Empty driver tables should not be used in a SELECT/FOR ALL ENTRIES clause">
    <div class="paragraph">
      <p>Using an empty driver table in a <code>SELECT/FOR ALL ENTRIES table has a very important side effect: the complete WHERE clause is not taken into account because a NO WHERE</code> condition is generated. Thus a full table scan is unexpectedly executed.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      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={null}
      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.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Macros should be documented">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      DEFINE my_macro.
      ...
      END-OF-DEFINITION.
      ```

      ```abap Fix theme={null}
      * here is  
      * my comment
      DEFINE my_macro.
      ...
      END-OF-DEFINITION.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Internal source code processing statements should not be used">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph">
      <p>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\`.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      GENERATE REPORT MY_PROG.
      ```

      ```abap Fix theme={null}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="DELETE FROM dbtab statements should have a WHERE clause">
    <div class="paragraph">
      <p><code>DELETE FROM dbtab without a WHERE</code> condition deletes all the entries of the table. Check whether dataset to be deleted can be limited by a suitable WHERE condition.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      DELETE FROM COUNTRIES.
      ```

      ```abap Fix theme={null}
      DELETE FROM COUNTRIES WHERE CODE = country_code.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Using CALL TRANSACTION statements without an authority check is security-sensitive">
    <div class="paragraph">
      <p>" statements without an authority check is security sensitive. Its access should be restricted to specific users.</p>
    </div>

    <div class="paragraph">
      <p>This rule raises when a \`CALL TRANSACTION has no explicit authorization check, i.e. when:</p>
    </div>

    <div class="ulist">
      <ul>
        <li>
          <p>the CALL TRANSACTION statement is not followed by WITH AUTHORITY-CHECK.</p>
        </li>

        <li>
          <p>the CALL TRANSACTION statement is not following an AUTHORITY-CHECK statement.</p>
        </li>

        <li>
          <p>the CALL TRANSACTION statement is not following a call to the AUTHORITY\_CHECK\_TCODE\` function.</p>
        </li>
      </ul>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      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={null}
      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.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="REFRESH itab FROM TABLE should not be used">
    <div class="paragraph">
      <p>This variant of the \`REFRESH statement is deprecated and should be avoided.</p>
    </div>

    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      TABLES t100. 
      DATA itab TYPE STANDARD TABLE OF t100.

      t100-sprsl = 'E'. 
      t100-arbgb = 'BC'.

      REFRESH itab FROM TABLE t100.
      ```

      ```abap Fix theme={null}
      DATA itab TYPE STANDARD TABLE OF t100.

      SELECT * 
         FROM t100 
         INTO TABLE itab 
         WHERE sprsl = 'E' AND 
               arbgb LIKE 'BC%'.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="SQL aggregate functions should not be used to prevent bypassing the SAP buffer">
    <div class="paragraph">
      <p><code>SQL COUNT(..), MIN(..), MAX(..), SUM(..), AVG(..)</code> aggregate functions cause the SAP table buffer to be bypassed, so the use of these functions can lead to performance issues.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      SELECT COUNT(*) 
         FROM persons 
         INTO count 
         WHERE city = 'NEW YORK'.
      ```

      ```abap Fix theme={null}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="All branches in a conditional structure should not have exactly the same implementation">
    <div class="paragraph">
      <p>Having all branches of a CASE or IF chain with the same implementation indicates a problem.</p>
    </div>

    <div class="paragraph">
      <p>In the following code:</p>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      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={null}
      IF a >0.   "no issue, this could have been done on purpose to make the code more readable
      doSomething.
      ELSEIF b> 0.
      doSomething.
      ENDIF.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Unnecessary chain syntax should not be used">
    <div class="paragraph">
      <p>When there is only one statement in a chain, the chain syntax can be omitted, which simplifies the code.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      CLEAR: w_alvvr.
      ```

      ```abap Fix theme={null}
      CLEAR w_alvvr.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Native SQL should not be statically embedded">
    <div class="paragraph">
      <p>The \`EXEC SQL ... END-EXEC statement can be used to embed Native SQL statically in ABAP programs.</p>
    </div>

    <div class="paragraph">
      <p>According to the SAP documentation:</p>
    </div>

    <div class="quoteblock">
      <blockquote>
        <div class="paragraph">
          <p>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.</p>
        </div>

        <div class="paragraph">
          <p>The existing static embedding of Native SQL statements is still supported but should no longer be used in new programs.</p>
        </div>
      </blockquote>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      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={null}
      NEW cl_sql_statement( )->execute_ddl(
        `CREATE TABLE ` && dbname   &&
        `( val1 char(10) NOT NULL,` &&
        `  val2 char(10) NOT NULL,` &&
        `  PRIMARY KEY (val1) )` ).
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="%_HINTS should not be used">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      select MY_COLUMN 
      into it_data
      from MY_TABLE
      WHERE FILTERING_COLUMN = '0'
      %_HINTS ORACLE 'INDEX("MY_TABLE" "MY_INDEX")'.
      ```

      ```abap Fix theme={null}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Operational statements should not be chained">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      TRY. 
       ... 
      CATCH: cx_1, cx_2, cx_3.  " only cx_3 gets the following CATCH block
       "exception handling 
        ... 
      ENDTRY.
      ```

      ```abap Fix theme={null}
      TRY. 
       ... 
      CATCH cx_1.
       "exception handling 
      CATCH cx_2.
       "exception handling 
      CATCH cx_3. 
       "exception handling 
        ... 
      ENDTRY.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Open SQL SELECT statements should have an ORDER BY clause">
    <div class="paragraph">
      <p>An Open SQL <code>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</code> clause.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      OPEN CURSOR C FOR SELECT * FROM SBOOK WHERE CARRID = 'LH '. "NonCompliant
      SELECT * FROM FLIGHTS WHERE FLIGHT_NUMBER = 'LH '."NonCompliant
      ```

      ```abap Fix theme={null}
      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.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="SELECT SINGLE or Up to 1 ROW should be used when retrieving one record">
    <div class="paragraph">
      <p>SAP recommends to keep the result set of any request as small as possible for performance reasons.</p>
    </div>

    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph">
      <p>This rule raises an issue when a SELECT...ENDSELECT which has neither SINGLE nor UP TO 1 ROWS and:</p>
    </div>

    <div class="ulist">
      <ul>
        <li>
          <p>contains only one statement and it is a CHECK, RETURN or EXIT\`</p>
        </li>

        <li>
          <p>or when it is completely empty.</p>
        </li>
      </ul>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      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={null}
      SELECT SINGLE * sbook INTO ls_book WHERE carrid EQ l_carrid.
      IF sy-subrc NE 0.
      WRITE:/ 'NO RECORD FOUND'.
      ENDIF.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="CASE statements should have WHEN OTHERS clauses">
    <div class="paragraph">
      <p>The requirement for an <code>OTHERS</code> clause is defensive programming. The clause should either take appropriate action, or contain a suitable comment as to why no action is taken.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      CASE SY-INDEX.   // Noncompliant; missing WHEN OTHERS clause
      WHEN ONE.
      WRITE  'One'. 
      WHEN 2.
      WRITE   'Two'.
      ENDCASE.
      ```

      ```abap Fix theme={null}
      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.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="SQL DISTINCT operator should not be used to prevent bypassing the SAP buffering">
    <div class="paragraph">
      <p><code>DISTINCT operator causes the SELECT</code> statement to avoid the SAP buffering and to read directly from the database and not from the buffer on the application server.</p>
    </div>

    <div class="paragraph" />

    <CodeGroup>
      ```abap Bad theme={null}
      SELECT DISTINCT carrid
         FROM spfli 
         INTO count 
         WHERE cityto = 'NEW YORK'.
      ```

      ```abap Fix theme={null}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Statements should be on separate lines">
    <div class="paragraph">
      <p>Putting multiple statements on a single line lowers the code readability and makes debugging the code more complex.</p>
    </div>

    <div class="paragraph">
      <p>Unresolved directive in \<stdin> - include::\{noncompliant}\[]</p>
    </div>

    <div class="paragraph">
      <p>Write one statement per line to improve readability.</p>
    </div>

    <div class="paragraph">
      <p>Unresolved directive in \<stdin> - include::\{compliant}\[]</p>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      WRITE 'Hello '. WRITE 'World'. "Noncompliant
      ```

      ```abap Fix theme={null}
      WRITE 'Hello '.
      WRITE 'World'.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Exception handlers should preserve the original exceptions">
    <div class="paragraph">
      <p>When handling a caught exception, the original exception’s message and stack trace should be logged or passed forward.</p>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      try.
      if ABS( NUMBER ) > 100.
        write / 'Number is large'.
      endif.
      catch CX_SY_ARITHMETIC_ERROR into OREF.
      endtry.
      ```

      ```abap Fix theme={null}
      try.
      if ABS( NUMBER ) > 100.
        write / 'Number is large'.
      endif.
      catch CX_SY_ARITHMETIC_ERROR into OREF.
      write / OREF->GET_TEXT( ).
      endtry.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Magic numbers should not be used">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      IF sy-subrc EQ 42.      " Noncompliant - 5 is a magic number
      screen-request = 'OK'.
      ENDIF.
      ```

      ```abap Fix theme={null}
      answer = 42.
      IF sy-subrc EQ answer.  " Compliant
      screen-request = 'OK'.
      ENDIF.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="SQL EXISTS subqueries should not be used ">
    <div class="paragraph">
      <p>SQL queries that use <code>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</code> condition.</p>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      SELECT name
      FROM employee
      WHERE EXISTS (SELECT * FROM department WHERE department_id = id AND name = 'Marketing');
      ```

      ```abap Fix theme={null}
      SELECT name
      FROM employee INNER JOIN department AS d
      ON department_id = d.id AND d.name = 'Marketing';
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Mergeable if statements should be combined">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph">
      <p>Merging if statements when possible will decrease the nesting of the code and improve its readability.</p>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      IF something.
      IF somethingElse.             " Noncompliant
      WRITE / 'hello'.
      ENDIF.
      ENDIF.
      ```

      ```abap Fix theme={null}
      IF something and somethingElse. " Compliant
      WRITE / 'hello'.
      ENDIF.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Macro names should comply with a naming convention">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      DEFINE MyMacro.
      ...
      END-OF-DEFINITION.
      ```

      ```abap Fix theme={null}
      DEFINE my_macro.
      ...
      END-OF-DEFINITION.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Redundant pairs of parentheses should be removed">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      CHECK (SY-SUBRC NE 0). "compliant even if ignored by compiler
      IF ((SY-SUBRC EQ 0)). "Noncompliant
      ```

      ```abap Fix theme={null}
      CHECK (SY-SUBRC NE 0).
      IF (SY-SUBRC EQ 0).
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Using shell interpreter when executing OS commands is security-sensitive">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      CALL 'SYSTEM' ID 'COMMAND' FIELD "/usr/bin/file.exe" ID 'TAB' FIELD TAB1.  " Compliant
      ```

      ```abap Fix theme={null}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Related if/else if statements should not have the same condition">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph">
      <p>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.</p>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      if param = 1.
      Statement.
      elseif param = 2.
      Statement.
      elseif param = 1.  // Noncompliant
      Statement.
      endif.
      ```

      ```abap Fix theme={null}
      if param = 1.
      Statement.
      elseif param = 2.
      Statement.
      elseif param = 3.
      Statement.
      endif.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Class names should comply with a naming convention">
    <div class="paragraph">
      <p>Shared naming conventions allow teams to collaborate efficiently.</p>
    </div>

    <div class="paragraph">
      <p>This rule raises an issue when a class name does not match a provided regular expression.</p>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      CLASS MyClass DEFINITION. "Noncompliant
      ...
      ENDCLASS.
      ```

      ```abap Fix theme={null}
      CLASS MY_CLASS DEFINITION.
      ...
      ENDCLASS.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="DATA variable names should comply with a naming convention">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      DATA: MyText TYPE string.
      ```

      ```abap Fix theme={null}
      DATA: my_text TYPE string.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="String literals should not be duplicated">
    <div class="paragraph">
      <p>Duplicated string literals make the process of refactoring complex and error-prone, as any change would need to be propagated on all occurrences.</p>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      WRITE: / 'Firstname'.
      *...
      WRITE: / 'Firstname'.
      *...
      WRITE: / 'Firstname'.
      ```

      ```abap Fix theme={null}
      CONSTANTS: fname    TYPE c LENGTH 9 VALUE 'Firstname',

      WRITE: / fname.
      *...
      WRITE: / fname.
      *...
      WRITE: / fname.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="switch case clauses should not have too many lines of code">
    <div class="paragraph">
      <p>The <code>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</code> clause should be extracted into a dedicated method.</p>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      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={null}
      CASE SY-INDEX.
      WHEN ONE. 
      PERFORM extractedSub.
      WHEN 2.
      ...
      ENDCASE.

      ...

      FORM extractedSub.
      PERFORM sub1.
      PERFORM sub2.
      PERFORM sub3.
      PERFORM sub4.
      PERFORM sub5.
      ENDFORM.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Function names should comply with a naming convention">
    <div class="paragraph">
      <p>Shared coding conventions allow teams to collaborate efficiently. This rule checks that all function names match a provided regular expression.</p>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      FUNCTION MyFunction. 
      ...
      ENDFUNCTION.
      ```

      ```abap Fix theme={null}
      FUNCTION MY_FUNCTION. 
      ...
      ENDFUNCTION.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Using hardcoded IP addresses is security-sensitive">
    <div class="paragraph">
      <p>Hardcoding IP addresses is security-sensitive. It has led in the past to the following vulnerabilities:</p>
    </div>

    <div class="ulist">
      <ul>
        <li>
          <p><a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-5901">CVE-2006-5901</a></p>
        </li>

        <li>
          <p><a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2005-3725">CVE-2005-3725</a></p>
        </li>
      </ul>
    </div>

    <div class="paragraph">
      <p>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:</p>
    </div>

    <div class="ulist">
      <ul>
        <li>
          <p>The developers will have to do a rapid fix every time this happens, instead of having an operation team change a configuration file.</p>
        </li>

        <li>
          <p>It misleads to use the same address in every environment (dev, sys, qa, prod).</p>
        </li>
      </ul>
    </div>

    <div class="paragraph">
      <p>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.</p>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      READ DATASET file INTO ip MAXIMUM LENGTH len.
      ```

      ```abap Fix theme={null}
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Interface names should comply with a naming convention">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      INTERFACE MyInterface. "Noncompliant
      ...
      ENDINTERFACE.
      ```

      ```abap Fix theme={null}
      INTERFACE YIF_myinterface. 
      ...
      ENDINTERFACE.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Unused local variables should be removed">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      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={null}
      FUNCTION f.
      DATA: LOCAL_1 LIKE BAR.

      SELECT * FROM LOCAL_1.

      ENDFUNCTION.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Source code should be indented consistently">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <div class="paragraph">
      <p>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.</p>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      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={null}
      CLASS counter IMPLEMENTATION.
      METHOD set.
      count = set_value. 
      ENDMETHOD.  
      METHOD increment.
      ADD 1 TO count.
      ENDMETHOD.
      METHOD get.
      get_value = count.
      ENDMETHOD.      
      ENDCLASS.
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Two branches in a conditional structure should not have exactly the same implementation">
    <div class="paragraph">
      <p>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.</p>
    </div>

    <CodeGroup>
      ```abap Bad theme={null}
      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={null}
      IF (a >= 0 AND a < 10) OR (a >= 20 AND a < 50).
      doFirst.
      doTheThing.
      ELSEIF a >= 10 AND a < 20.
      doTheOtherThing.
      ENDIF.
      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>
