| Syntax | Notes |
| `... INTO TABLE ...` | An internal table is expected for the result set. It may be declared inline to automatically have a suitable type, which also applies to `... INTO ...`. ```abap SELECT FROM dbtab FIELDS * WHERE ... INTO TABLE @itab. SELECT FROM dbtab FIELDS * WHERE ... INTO TABLE @DATA(itab_inl). ``` |
| `... INTO ...` | Expects a structure when used without `TABLE`. ```abap SELECT SINGLE comp1, comp2, comp3 FROM dbtab WHERE ... INTO @struc. SELECT SINGLE comp1, comp2, comp3 FROM dbtab WHERE ... INTO @DATA(struc_inl). ``` |
| `... INTO CORRESPONDING FIELDS OF [TABLE] ...` | - Only the content of columns for which there are identically named components in the target are assigned. - However, if you want to read data into an existing data object and particular fields are specified in the `SELECT` list or `FIELDS` clause, and if the addition is **not** specified, you might stumble on undesired results. - The target data object must contain enough components and the content of the columns are assigned to the components of the target from left to right in the order specified. The content of surplus components of the target is not changed. - Plus, pay attention to [assignment rules](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenselect_into_conversion.htm). - Basic rule: Without `CORRESPONDING ...`, column names do not play a role but only the position. With `CORRESPONDING ...`, the position of the columns does not play a role but only the name. ```abap SELECT SINGLE comp1, comp2, comp3 FROM dbtab WHERE ... INTO CORRESPONDING FIELDS OF @struc. SELECT FROM dbtab FIELDS comp1, comp2, comp3 WHERE ... INTO CORRESPONDING FIELDS OF TABLE @itab. ``` |
| `... APPENDING [CORRESPONDING FIELDS OF] TABLE ...` | The addition `INTO` initializes the target object. When using the addition `APPENDING`, you can retain existing lines in internal tables. `APPENDING` is also possible with the addition `CORRESPONDING FIELDS OF`. ```abap SELECT * FROM dbtab WHERE ... APPENDING TABLE @itab. "APPENDING is also possible with the addition CORRESPONDING FIELDS OF SELECT * FROM dbtab WHERE ... APPENDING CORRESPONDING FIELDS OF TABLE @diff_itab. ``` |
NEW addition: Specifying an anonymous data object as target object |
- Specifying an [anonymous data object](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenanonymous_data_object_glosry.htm) as target object using the addition [`NEW`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_into_target.htm#!ABAP_ALTERNATIVE_3@3@)
- Only to be used after `INTO` and not `APPENDING`.
``` abap "The examples declares target objects as anonymous data objects inline. SELECT * FROM zdemo_abap_flsch INTO TABLE NEW @DATA(itab_ref). SELECT SINGLE * FROM zdemo_abap_flsch INTO NEW @DATA(wa_ref). ``` |
| `... INTO ( dobj1, dob2, ... ) ...` | Apart from reading into structures and internal tables outlined above, you can also read into individual elementary data objects. Here, the individual elementary data objects as target objects are specified in a comma-separated list (e. g. as existing host variables or declared inline) and put between a pair of parentheses. Note: - The comma-separated list must have the same number of elements as columns in the result set. - The content of the columns in the result set is assigned to the data objects specified in the list from left to right in accordance with the order specified in the `SELECT` list. - Note the [assignment rules](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenselect_into_conversion.htm) also in this context. - More information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinto_clause.htm#!ABAP_ALTERNATIVE_1@1@). ``` abap "Elementary data objects as target data objects DATA id TYPE zdemo_abap_carr-carrid. DATA name TYPE zdemo_abap_carr-carrname. SELECT SINGLE FROM zdemo_abap_carr FIELDS carrid, carrname WHERE carrid = char`LH` INTO ( @id, @name ). "Inline declarations with DATA/FINAL and the "creation of anonymous data objects with NEW are "possible SELECT SINGLE FROM zdemo_abap_carr FIELDS carrid, carrname, url WHERE carrid = char`LH` INTO ( @id, @DATA(name2), NEW @FINAL(dref) ). ``` |
| Subject | Details/Code Snippet |
| `SINGLE` addition: Retrieving a single row into a structure | ``` abap "SINGLE addition "Here, all fields of a single row a read. Specifying an "asterisk * indicates that all fields are to be read. "Alternatively, you can list all the fields separated by comma. "Note that if the selection covers more than one row, e. g. in case "of a non-unique WHERE clause, one of these rows is included in "the result. SELECT SINGLE FROM dbtab FIELDS * WHERE ... INTO @struc. "Existing structure of dbtab's row type "Retrieving a selected set of fields of a single row SELECT SINGLE FROM dbtab FIELDS comp1, comp2, comp3 WHERE ... INTO @DATA(struc2). "Structure declared inline "Alternative syntax without the FIELDS addition "Here, the CORRESPONDING FIELDS OF addition is used. Only the content of "columns that have identically named components in the target data object "is assigned. SELECT SINGLE comp1, comp2, comp3 "Selected set of fields FROM dbtab WHERE ... INTO CORRESPONDING FIELDS OF @struc. "Existing structure ``` |
| Retrieving multiple rows into an internal table | ``` abap SELECT FROM dbtab FIELDS * "All fields WHERE ... INTO TABLE @itab. "itab has an appropriate row type "Alternative syntax without the FIELDS addition SELECT comp1, comp2, comp3 "Selected set of fields FROM dbtab WHERE ... INTO TABLE @DATA(lv_itab). "Internal table declared inline "Selected set of fields, existing variable "See the note on CORRESPONDING FIELDS OF above SELECT FROM dbtab FIELDS comp1, comp2, comp3 "Selected set of fields WHERE ... INTO CORRESPONDING FIELDS OF TABLE @itab. "The addition INTO initializes the target object. When using the addition APPENDING, "you can retain existing lines in internal tables. SELECT * FROM dbtab WHERE ... APPENDING TABLE @itab. "APPENDING is also possible with the addition CORRESPONDING FIELDS OF SELECT * FROM dbtab WHERE ... APPENDING CORRESPONDING FIELDS OF TABLE @diff_itab. ``` |
SELECT loop: Sequentially retrieving multiple rows |
- A `SELECT` loop can be opened if the assignment is made to a structure and the addition `SINGLE` is not used.
- If the row is found, the system field `sy-subrc` is set to `0`.
- The loop must be closed using `ENDSELECT`.
- To terminate the loop completely, you can use the statement [`EXIT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapexit_loop.htm).
- Note: As covered further down, when using the addition `PACKAGE SIZE` and storing the result in a table, a loop is opened, too.
``` abap SELECT FROM dbtab FIELDS * WHERE ... INTO @struc. IF sy-subrc = 0. ... "For example, making changes on data and adding the row to an internal table. ENDIF. ENDSELECT. ``` |
| Checking the existence of a row in a database table | ``` abap "The example uses @abap_true. Other specifications are possible, e.g. 'X'. SELECT SINGLE @abap_true FROM dbtab WHERE ... INTO @DATA(exists). IF exists = abap_true. ... ENDIF. ``` |
DISTINCT addition: Removing rows that occur more than once in a multirow result set |
- Cannot be used with the addition `SINGLE`.
- See more information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_clause.htm).
``` abap "The following example assumes that there are multiple flights "from a city of the specified carrier with the particular destination. "Assume there are 5 flights available from Frankfurt (cityfrom) that "matches the WHERE clause. The first statement only returns one entry "in the internal table, the second 5 (all). "Using the DISTINCT addition SELECT DISTINCT cityfrom FROM zdemo_abap_flsch WHERE carrid = 'LH' AND cityto = 'NEW YORK' INTO TABLE @DATA(itab_distinct). "Not using the DISTINCT addition SELECT cityfrom FROM zdemo_abap_flsch WHERE carrid = 'LH' AND cityto = 'NEW YORK' INTO TABLE @DATA(itab_no_distinct). ``` |
UP TO n ROWS addition: Limiting the number of returned table rows |
[`UP TO n ROWS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_up_to_offset.htm)
``` abap "A maximum of five rows are to be returned "If the INTO clause is the last clause, the UP TO clause must be positioned after it. SELECT * FROM dbtab WHERE ... INTO TABLE @DATA(itab_upto) UP TO 5 ROWS. ``` |
OFFSET n addition: Returning only the table rows after a row with a specified count from the result set |
- [`OFFSET n`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_up_to_offset.htm#!ABAP_ADDITION_2@2@)
- You can only use the addition, if an `ORDER BY` clause is specified.
``` abap "In the example, data of all flights are retrieved, except for the 2 flights "with the shortest flight time. SELECT * FROM ztest_abap_flsch WHERE carrid = 'LH' ORDER BY fltime ASCENDING INTO TABLE @DATA(itab) OFFSET 2. ``` |
PACKAGE SIZE n addition: Storing the result in packages of a specified number of rows |
The addition [`PACKAGE SIZE n`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinto_clause.htm#!ABAP_ONE_ADD@1@) can be specified after `INTO TABLE` and `APPENDING TABLE`. A `SELECT` loop ist opened. After `PACKAGE SIZE`, the number of rows is specified (which can be a host variable, host expression or a literal of type `i`) denoting the number of rows to be inserted in the target object per iteration.
``` abap SELECT FROM dbtab FIELDS comp1, comp2, comp3 WHERE ... INTO TABLE @DATA(itab_pack) PACKAGE SIZE n. ... ENDSELECT. ``` |
INDICATORS [NOT] NULL STRUCTURE addition: Specifying null indicators |
- The `INDICATORS ...` addition is used to specify indicators such as the [null indicator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abennull_indicator_glosry.htm) and store information about which columns of the result set contain the null value and which do not.
- In the example, an appropriate target table is defined to also store information about which columns of the result set contain the null value and which do not.
- More syntax options are available for `INDICATORS ...`. Find more information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_indicators.htm).
``` abap "The following example uses a left outer join to intentionally create null values. For "this purpose, two demo database tables of the cheat sheet repository are cleared and "populated with specific values to visualize null values. DELETE FROM zdemo_abap_tab1. DELETE FROM zdemo_abap_tab2. MODIFY zdemo_abap_tab1 FROM TABLE @( VALUE #( ( key_field = 1 char1 = 'a' char2 = 'y' ) ( key_field = 2 char1 = 'b' char2 = 'z' ) ) ). MODIFY zdemo_abap_tab2 FROM TABLE @( VALUE #( ( key_field = 1 char1 = 'a' ) ( key_field = 2 char1 = 'a' ) ( key_field = 3 char1 = 'b' ) ( key_field = 4 ) ) ). "Note that for the entry 'key_field = 4' no char1 value was passed. "char1 is a shared column of the two database tables, and which is used in "the ON condition of the join. Since there is no entry in char1 for 'key_field = 4', "the joined values are null in that case. "The example visualizes the null values. The INDICATORS addition is used to specify "indicators such as the null indicator. In the example, an appropriate target table "is defined to also store information about which columns of the result set contain "the null value and which do not. TYPES: BEGIN OF st4null, BEGIN OF s2, key_field TYPE zdemo_abap_tab2-key_field, char2 TYPE zdemo_abap_tab1-char2, END OF s2, BEGIN OF nulls, key_field TYPE c LENGTH 1, char2 TYPE c LENGTH 1, END OF nulls, END OF st4null. DATA joined_tab_w_null_ind TYPE TABLE OF st4null WITH EMPTY KEY. SELECT tab2~key_field, tab1~char2 FROM zdemo_abap_tab2 AS tab2 LEFT OUTER JOIN zdemo_abap_tab1 AS tab1 ON tab1~char1 = tab2~char1 INTO TABLE @joined_tab_w_null_ind INDICATORS NULL STRUCTURE nulls. *Internal table content: *S2 NULLS *KEY_FIELD CHAR2 KEY_FIELD CHAR2 *1 y *KEY_FIELD CHAR2 KEY_FIELD CHAR2 *2 y *KEY_FIELD CHAR2 KEY_FIELD CHAR2 *3 z *KEY_FIELD CHAR2 KEY_FIELD CHAR2 *4 X ``` |
| Clause | Details/Code Snippet |
GROUP BY |
[`GROUP BY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapgroupby_clause.htm)
clause: Combining groups of table rows in the result set. You
can also use [SQL expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_expression_glosry.htm "Glossary Entry")
here. Multiple clause elements are separated by a comma. Find more information and syntax options in the [ABAP Keyword Documentation](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapgroupby_clause.htm).
Note that the `GROUP BY` clause requires all columns that are
directly specified in the `SELECT` list or specified there as an
argument of an SQL expression to be specified. An exception to this is
[aggregate
functions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenaggregate_function_glosry.htm "Glossary Entry")
in [aggregate
expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenaggregate_expression_glosry.htm "Glossary Entry")
(except [grouping
functions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abengrouping_glosry.htm "Glossary Entry"))
as shown in the following example.
In the example below, the database table rows that have the same content in column `comp1` are combined. The lowest and highest values in column `comp2` are determined for each of these groups and placed into the combined row.
``` abap SELECT FROM dbtab FIELDS comp1, MIN( comp2 ) AS min, MAX( comp2 ) AS max WHERE ... GROUP BY comp1 INTO ... ``` |
HAVING |
[`HAVING`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaphaving_clause.htm)
clause: Limiting the number of table rows in groups in the
result by setting conditions on these rows. The rows for which a
logical expression is true are inserted in the target variable. Note
that `HAVING` can only be used together with `GROUP BY`.
``` abap SELECT FROM dbtab FIELDS comp1, MIN( comp2 ) AS min, MAX( comp3 ) AS max WHERE ... GROUP BY comp1 HAVING comp1 LIKE '%XYZ%' AND SUM( comp4 ) > 100 INTO ... ``` |
ORDER BY |
[`ORDER BY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaporderby_clause.htm)
clause: Sorting the result set by specified columns.
The following example shows the ordering of the result set based on the
content of the primary key of the [data source](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_source_glosry.htm "Glossary Entry").
You can also order by any columns and by explicitly specifying the sort order. There are more ordering options, for example, by using SQL expressions. Find more information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaporderby_clause.htm).
> **💡 Note** >- Not specifying `ORDER BY` means that the order of entries in the result set is undefined. >- If `ORDER BY` and `GROUP BY` clauses are used, all columns specified after `ORDER BY` must also be specified after `GROUP BY`. >- If aggregate functions are specified after `SELECT`, all columns that are specified after `ORDER BY` and that do not have an alias name for an aggregate function must also be specified after `SELECT` and after the `GROUP BY` clause which is required in this case, too. ``` abap SELECT FROM dbtab FIELDS comp1, comp2, comp3 WHERE ... ORDER BY PRIMARY KEY "comp2 ASCENDING "comp2 DESCENDING INTO ... ``` |
WHERE |
[`WHERE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapwhere.htm) clause: Restricts the number of rows that are included in the result set using logical expressions. See further information on them in the following sections.
``` abap SELECT FROM dbtab FIELDS comp1, comp2, comp3 WHERE comp1 = 'abc' AND comp2 < 123 INTO ... ``` |
| Subject | Details/Code Snippet |
| Using an inner join |
[Inner join](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninner_join_glosry.htm):
- Columns of two or more data sources in a result set can be joined.
- Result set:
- Columns of the rows in the result set of the left side with the columns of the rows in the result set of the right side are joined into a single result set.
- Contains all combinations of rows for whose columns the join condition is true.
- If there are identical column names in multiple data sources, use the [column
selector](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_comp_selector_glosry.htm "Glossary Entry")
`~`.
``` abap SELECT a~comp1, a~comp2, b~comp3, c~comp4 FROM dbtab1 AS a INNER JOIN dbtab2 AS b ON a~comp1 = b~comp1 AND a~comp2 = b~comp2 INNER JOIN dbtab3 AS c ON a~comp1 = c~comp1 WHERE ... INTO ... ``` |
| Using an outer join |
[Outer join](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenouter_join_glosry.htm):
- Realized by either a [left outer join](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenleft_outer_join_glosry.htm) or
a [right outer join](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenright_outer_join_glosry.htm).
- Result set:
- Same result set as the inner join.
- Difference: For each selected row on the left side as `LEFT OUTER JOIN` or on the right side as `RIGHT OUTER JOIN`, at least one row is created in the result set even if no rows on the other side meet the condition. The columns on the other side that do not meet the condition are filled with [null values](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abennull_value_glosry.htm).
``` abap "Example for a left outer join SELECT a~comp1, a~comp2, b~comp3, FROM dbtab1 AS a LEFT OUTER JOIN dbtab2 AS b ON a~comp1 = b~comp1 WHERE ... INTO ... ``` |
| Merging the result sets of multiple queries into a single result set |
... using the [set operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_set_operators_glosry.htm) [`UNION`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapunion.htm#!ABAP_VARIANT_1@1@). In this case, the rows of the result set of the query after `UNION` are inserted into the result set of the query in front of `UNION`.
``` abap SELECT FROM dbtab1 FIELDS ... WHERE ... UNION SELECT FROM dbtab2 FIELDS ... WHERE ... INTO ... ``` |
| Returning distinct rows of a result set (1) |
... of a query specified before the `INTERSECT` addition that are also available in the result set of the query after the `INTERSECT` addition.
``` abap "If you have imported the cheat sheet repository and already run an example class to fill "the demo tables, you can check the contents of the result sets. SELECT zdemo_abap_flsch~carrid, zdemo_abap_carr~carrname FROM zdemo_abap_flsch INNER JOIN zdemo_abap_carr ON zdemo_abap_carr~carrid = zdemo_abap_flsch~carrid ORDER BY zdemo_abap_flsch~carrid INTO TABLE @DATA(itab_no_intersect). "Using INTERSECT; the result set contains distinct rows SELECT zdemo_abap_flsch~carrid, zdemo_abap_carr~carrname FROM zdemo_abap_flsch INNER JOIN zdemo_abap_carr ON zdemo_abap_carr~carrid = zdemo_abap_flsch~carrid INTERSECT SELECT carrid, carrname FROM zdemo_abap_carr ORDER BY carrid INTO TABLE @DATA(itab_w_intersect). ``` |
| Returning distinct rows of a result set (2) |
... of a query specified before the `EXCEPT` addition that are not available in the result set of the query after the `EXCEPT` addition.
```abap "If you have imported the cheat sheet repository and already run an example class to fill "the demo tables, you can check the contents of the result sets. "Selecting all carrier IDs from a database table that do not exist in an "internal table TYPES: ty_demo_tab TYPE TABLE OF zdemo_abap_flsch WITH EMPTY KEY. DATA(itab) = VALUE ty_demo_tab( ( carrid = 'LH' ) ( carrid = 'LH' ) ( carrid = 'LH' ) ( carrid = 'AA' ) ( carrid = 'AA' ) ). "Selecting all carrier IDs for comparison SELECT carrid FROM zdemo_abap_carr INTO TABLE @DATA(all_carrids). "Using EXCEPT; the result set excludes those carrier IDs present in the "internal table SELECT carrid FROM zdemo_abap_carr EXCEPT SELECT it~carrid FROM @itab AS it INNER JOIN zdemo_abap_carr ON zdemo_abap_carr~carrid = it~carrid ORDER BY carrid ASCENDING INTO TABLE @DATA(itab_w_except). ``` |
char\`abc\`) with [built-in ABAP Dictionary
types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddic_builtin_types.htm)
or untyped. See the [Typed Literals](#typed-literals) section further down.
- Regarding host expressions: Structures and internal tables are
possible as host expressions for statements modifying the
content of database tables as shown further down.
- Find more information
[here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_operands.htm).
> **💡 Note**| ABAP repository object | Notes/Code |
| Table entity | ```abap @ClientHandling.type: #CLIENT_INDEPENDENT @AbapCatalog.deliveryClass: #APPLICATION_DATA @AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'CDS table entity' define table entity zdemo_abap_animals_te { key id : abap.int4; animal_name : abap.char(20); species : abap.char(20); age : abap.int4; country_of_origin : abap.char(20); arrival_date : abap.datn; is_carnivore : abap_boolean; } ``` |
| Writable CDS view entity | ```abap @AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'Writable CDS view entity' @Metadata.ignorePropagatedAnnotations: true define writable view entity zdemo_abap_animals_we as select from zdemo_abap_animals_te { key id, animal_name, species, age, country_of_origin, arrival_date, is_carnivore } ``` |
| Class | ```abap CLASS zcl_demo_abap DEFINITION PUBLIC FINAL CREATE PUBLIC . PUBLIC SECTION. INTERFACES if_oo_adt_classrun. PROTECTED SECTION. PRIVATE SECTION. ENDCLASS. CLASS zcl_demo_abap IMPLEMENTATION. METHOD if_oo_adt_classrun~main. *&---------------------------------------------------------------------* *& Using table entities and writable CDS view entities as data types *& in ABAP *&---------------------------------------------------------------------* DATA struc_table_entity TYPE zdemo_abap_animals_te. TYPES struc_type_table_entity TYPE zdemo_abap_animals_te. DATA(another_struc_table_ent) = VALUE zdemo_abap_animals_te( id = 1 animal_name = 'Zeus' ). DATA struc_writable_ve TYPE zdemo_abap_animals_we. TYPES struc_type_writable_ve TYPE zdemo_abap_animals_we. DATA(another_struc_writable_ve) = VALUE zdemo_abap_animals_we( id = 2 animal_name = 'Leo' ). *&---------------------------------------------------------------------* *& Performing CRUD operations using a table entity and ABAP SQL *&---------------------------------------------------------------------* out->write( `---- Performing CRUD operations on table entities using ABAP SQL ----` ). out->write( |\n| ). DELETE FROM zdemo_abap_animals_te. "DATA animals_table type table of zdemo_abap_animals_te with empty key. INSERT zdemo_abap_animals_te FROM TABLE @( VALUE #( ( id = 1 animal_name = 'Zeus' species = 'Lion' age = 5 country_of_origin = '' arrival_date = '20220115' is_carnivore = abap_true ) ( id = 2 animal_name = 'Leo' species = 'Lion' age = 7 country_of_origin = '' arrival_date = '20241205' is_carnivore = abap_true ) ( id = 3 animal_name = 'Jumbo' species = 'Elephant' age = 10 country_of_origin = 'India' arrival_date = '20190526' is_carnivore = abap_false ) ( id = 4 animal_name = 'Little' species = 'Elephant' age = 4 country_of_origin = 'India' arrival_date = '20240314' is_carnivore = abap_false ) ( id = 5 animal_name = 'Daisy' species = 'Zebra' age = 4 country_of_origin = 'South Africa' arrival_date = '20220207' is_carnivore = abap_false ) ( id = 6 animal_name = 'Buddy' species = 'Owl' age = 3 country_of_origin = 'Canada' arrival_date = '20210111' is_carnivore = abap_true ) ( id = 7 animal_name = 'Sunny' species = 'Dolphin' age = 7 country_of_origin = 'Australia' arrival_date = '20190527' is_carnivore = abap_false ) ( id = 8 animal_name = 'Nala' species = 'Giraffe' age = 6 country_of_origin = 'Tanzania' arrival_date = '20210807' is_carnivore = abap_false ) ( id = 9 animal_name = 'Oscar' species = 'Tiger' age = 8 country_of_origin = 'Russia' arrival_date = '20191018' is_carnivore = abap_true ) ( id = 10 animal_name = 'Charlie' species = 'Chimpanzee' is_carnivore = abap_false ) ( id = 12 ) ) ). out->write( |sy-dbcnt after 1st INSERT: { sy-dbcnt }| ). SELECT COUNT(*) FROM zdemo_abap_animals_te INTO @DATA(number_of_entries). out->write( |Number of data entries after 1st INSERT: { number_of_entries }| ). INSERT zdemo_abap_animals_te FROM TABLE @( VALUE #( ( id = 1 animal_name = 'Lora' species = 'Parrot' age = 2 country_of_origin = 'Mexico' arrival_date = '20240712' is_carnivore = abap_false ) ( id = 11 animal_name = 'Teddy' species = 'Koala' age = 4 country_of_origin = 'Australia' arrival_date = '20240225' is_carnivore = abap_false ) ) ) ACCEPTING DUPLICATE KEYS. out->write( |sy-dbcnt after 2nd INSERT: { sy-dbcnt }| ). SELECT COUNT(*) FROM zdemo_abap_animals_te INTO @number_of_entries. out->write( |Number of data entries after 1st INSERT: { number_of_entries }| ). MODIFY zdemo_abap_animals_te FROM TABLE @( VALUE #( ( id = 12 animal_name = 'Peanut' species = 'Penguin' age = 6 country_of_origin = 'Antarctica' arrival_date = '20200410' is_carnivore = abap_false ) ( id = 13 animal_name = 'Lora' species = 'Parrot' age = 2 country_of_origin = 'Mexico' arrival_date = '20240712' is_carnivore = abap_false ) ( id = 14 animal_name = 'Jumpy' species = 'Kangaroo' age = 4 country_of_origin = 'Australia' arrival_date = '20211117' is_carnivore = abap_false ) ) ). out->write( |sy-dbcnt after MODIFY: { sy-dbcnt }| ). SELECT COUNT(*) FROM zdemo_abap_animals_te INTO @number_of_entries. out->write( |Number of data entries after MODIFY: { number_of_entries }| ). SELECT SINGLE * FROM zdemo_abap_animals_te WHERE id = 10 INTO @DATA(data_set). UPDATE zdemo_abap_animals_te FROM @( VALUE #( BASE data_set age = 3 country_of_origin = 'Uganda' arrival_date = '20231214' ) ). out->write( |sy-dbcnt after 1st UPDATE: { sy-dbcnt }| ). UPDATE zdemo_abap_animals_te SET country_of_origin = 'Kenya' WHERE country_of_origin IS INITIAL. out->write( |sy-dbcnt after 2nd UPDATE: { sy-dbcnt }| ). SELECT * FROM zdemo_abap_animals_te ORDER BY id INTO TABLE @DATA(itab_te). out->write( `Table entries retrieved from table entity:` ). out->write( itab_te ). DELETE FROM zdemo_abap_animals_te WHERE id > 10. out->write( |sy-dbcnt after DELETE: { sy-dbcnt }| ). SELECT COUNT(*) FROM zdemo_abap_animals_te INTO @number_of_entries. out->write( |Number of data entries after DELETE: { number_of_entries }| ). out->write( |\n| ). out->write( repeat( val = '_' occ = 100 ) ). out->write( |\n| ). *&---------------------------------------------------------------------* *& Performing CRUD operations using a writable CDS view entities and ABAP SQL *&---------------------------------------------------------------------* out->write( `---- Performing CRUD operations on a writable CDS view entity using ABAP SQL ----` ). out->write( |\n| ). SELECT COUNT(*) FROM zdemo_abap_animals_we INTO @DATA(we_number_of_entries). out->write( |Number of data entries accessed via writable CDS view entity: { we_number_of_entries }| ). INSERT zdemo_abap_animals_we FROM TABLE @( VALUE #( ( id = 15 ) ( id = 16 animal_name = 'Fuzz' species = 'Polar bear' ) ) ). out->write( |sy-dbcnt after INSERT: { sy-dbcnt }| ). SELECT COUNT(*) FROM zdemo_abap_animals_we INTO @we_number_of_entries. out->write( |Number of data entries after INSERT: { we_number_of_entries }| ). MODIFY zdemo_abap_animals_we FROM @( VALUE #( id = 15 animal_name = 'Hunter' species = 'Jaguar' age = 3 country_of_origin = 'Brazil' arrival_date = '20230423' is_carnivore = abap_true ) ). out->write( |sy-dbcnt after MODIFY: { sy-dbcnt }| ). SELECT SINGLE * FROM zdemo_abap_animals_we WHERE id = 16 INTO @DATA(entry). UPDATE zdemo_abap_animals_we FROM @( VALUE #( BASE entry animal_name = 'Fuzzy' age = 7 country_of_origin = 'Canada' arrival_date = '20190223' is_carnivore = abap_true ) ). out->write( |sy-dbcnt after UPDATE: { sy-dbcnt }| ). DELETE zdemo_abap_animals_we FROM @( VALUE #( id = 10 ) ). out->write( |sy-dbcnt after 1st DELETE: { sy-dbcnt }| ). SELECT COUNT(*) FROM zdemo_abap_animals_we INTO @we_number_of_entries. out->write( |Number of data entries after 1st DELETE: { we_number_of_entries }| ). DELETE FROM zdemo_abap_animals_we WHERE id <= 5. out->write( |sy-dbcnt after 2nd DELETE: { sy-dbcnt }| ). SELECT COUNT(*) FROM zdemo_abap_animals_we INTO @we_number_of_entries. out->write( |Number of data entries after 2nd DELETE: { we_number_of_entries }| ). SELECT * FROM zdemo_abap_animals_we ORDER BY id INTO TABLE @DATA(itab_we). out->write( `Table entries retrieved via writable CDS view entity:` ). out->write( itab_we ). ENDMETHOD. ENDCLASS. ``` |