[ABAP] Dynamische WHERE-Clause für AMDP aus SELECT-OPTIONS / RANGES generieren

Bei Datenbankzugriffen mit AMDP / NATIVE SQL besteht nicht die Möglichkeit einfach RANGES in den SELECT-Statements zu übergeben.
Die RANGES müssen dazu zuerst in einen String umgewandelt werden. Dieser String kann dann in der WHERE-Condition verarbeitet werden.

Variante 1 (cl_shdb_seltab)

DATA: lv_usnam TYPE rkpf-usnam.

SELECT-OPTIONS: so_usnam FOR lv_usnam.

INITIALIZATION.

  so_usnam[] = VALUE #( ( sign = 'I' option = 'EQ' low = 'USER1' high = '' )
                        ( sign = 'I' option = 'EQ' low = 'USER2' high = '' )
                      ).

START-OF-SELECTION.
* wandelt ein SELECT-OPTIONS / RANGE in WHERE-String um
  TRY.
* WHERE-Condition ohne fehlerhaft gesetzte Klammern und unnötige Leerzeichen
      DATA(lv_where) = condense( cl_shdb_seltab=>new( so_usnam[] )->sql_where_condition( 'USNAM' ) ).

      WRITE: / lv_where.

    CATCH cx_root INTO DATA(e_txt).
  ENDTRY.

Variante 2 (cl_shdb_seltab, erzeugt fehlerhaftes WHERE-Statement)

DATA: lv_usnam TYPE rkpf-usnam.

SELECT-OPTIONS: so_usnam FOR lv_usnam.

INITIALIZATION.

  so_usnam[] = VALUE #( ( sign = 'I' option = 'EQ' low = 'USER1' high = '' )
                        ( sign = 'I' option = 'EQ' low = 'USER2' high = '' )
                      ).

START-OF-SELECTION.
* wandelt ein oder mehrere SELECT-OPTIONS / RANGE in WHERE-String um
  TRY.
* WHERE-Condition mit fehlerhaft gesetzte Klammern und unnötigen Leerzeichen
      DATA(lv_where) = cl_shdb_seltab=>combine_seltabs(
                                                        it_named_seltabs = VALUE #(
                                                                                    (
                                                                                      name = 'USNAM'              " RKPF-USNAM
                                                                                      dref = REF #( so_usnam[] )  " Referenz auf SELECT-OPTIONS / RANGE
                                                                                    )
                                                                                  )
                                                      ).

      WRITE: / lv_where.

    CATCH cx_root INTO DATA(e_txt).
  ENDTRY.

Variante 3 (cl_lib_seltab, OBSOLET)

DATA: lv_usnam TYPE rkpf-usnam.

SELECT-OPTIONS: so_usnam FOR lv_usnam.

INITIALIZATION.

  so_usnam[] = VALUE #( ( sign = 'I' option = 'EQ' low = 'USER1' high = '' )
                        ( sign = 'I' option = 'EQ' low = 'USER2' high = '' )
                      ).

START-OF-SELECTION.
* wandelt ein SELECT-OPTIONS / RANGE in WHERE-String um
  TRY.
* WHERE-Condition ohne fehlerhaft gesetzte Klammern und unnötige Leerzeichen
      DATA(lv_where) = condense( cl_lib_seltab=>new( so_usnam[] )->sql_where_condition( 'USNAM' ) ).

      WRITE: / lv_where.

    CATCH cx_root INTO DATA(e_txt).
  ENDTRY.

Variante 4 (FREE_SELECTIONS_RANGE_2_WHERE)

DATA: lv_usnam TYPE rkpf-usnam.

SELECT-OPTIONS: so_usnam FOR lv_usnam.

INITIALIZATION.

  so_usnam[] = VALUE #( ( sign = 'I' option = 'EQ' low = 'USER1' high = '' )
                        ( sign = 'I' option = 'EQ' low = 'USER2' high = '' )
                      ).

START-OF-SELECTION.

  DATA(it_ranges) = VALUE rsds_trange(
                                       (
* Tabellenname
                                         tablename = 'RKPF'
                                         frange_t = VALUE #(
                                                             (
* Feldname
                                                                fieldname = 'USNAM'
* RANGE aus SELECT-OPTIONS
                                                                selopt_t  = VALUE #( FOR <so> IN so_usnam
                                                                                     (
                                                                                       sign   = <so>-sign
                                                                                       option = <so>-option
                                                                                       low    = <so>-low
                                                                                       high   = <so>-high
                                                                                     )
                                                                                   )
                                                             )
                                                           )
                                       )
                                     ).

* Rückgabe
  DATA: it_where TYPE rsds_twhere.

* Freie Abgrenzungen: Konvertierung Format RSDS_TRANGE ==> RSDS_TWHERE
  CALL FUNCTION 'FREE_SELECTIONS_RANGE_2_WHERE'
    EXPORTING
      field_ranges  = it_ranges
    IMPORTING
      where_clauses = it_where.

* Ausgabe
  LOOP AT it_where ASSIGNING FIELD-SYMBOL(<e>).
    WRITE: / 'Table:', <e>-tablename.
    LOOP AT <e>-where_tab ASSIGNING FIELD-SYMBOL(<w>).
      WRITE: / <w>-line.
    ENDLOOP.
  ENDLOOP.

Links