@linkup-ai/abap-ai 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +384 -0
- package/dist/adt-client.js +364 -0
- package/dist/cli/activate.js +113 -0
- package/dist/cli/init.js +333 -0
- package/dist/cli/remove.js +80 -0
- package/dist/cli/status.js +229 -0
- package/dist/cli/systems.js +68 -0
- package/dist/cli.js +81 -0
- package/dist/index.js +1318 -0
- package/dist/knowledge/abap/abap-dictionary.md +199 -0
- package/dist/knowledge/abap/abap-sql.md +296 -0
- package/dist/knowledge/abap/amdp.md +273 -0
- package/dist/knowledge/abap/clean-code.md +293 -0
- package/dist/knowledge/abap/cloud-background-processing.md +250 -0
- package/dist/knowledge/abap/cloud-communication.md +265 -0
- package/dist/knowledge/abap/cloud-development.md +176 -0
- package/dist/knowledge/abap/cloud-extensibility.md +252 -0
- package/dist/knowledge/abap/cloud-released-apis.md +261 -0
- package/dist/knowledge/abap/constructor-expressions.md +289 -0
- package/dist/knowledge/abap/enhancements.md +232 -0
- package/dist/knowledge/abap/exceptions.md +271 -0
- package/dist/knowledge/abap/internal-tables.md +205 -0
- package/dist/knowledge/abap/object-orientation.md +298 -0
- package/dist/knowledge/abap/performance.md +216 -0
- package/dist/knowledge/abap/rap-abstract-entities.md +206 -0
- package/dist/knowledge/abap/rap-business-events.md +216 -0
- package/dist/knowledge/abap/rap-draft.md +191 -0
- package/dist/knowledge/abap/rap-eml.md +453 -0
- package/dist/knowledge/abap/rap-end-to-end.md +486 -0
- package/dist/knowledge/abap/rap-feature-control.md +185 -0
- package/dist/knowledge/abap/rap-numbering.md +280 -0
- package/dist/knowledge/abap/rap-service-exposure.md +163 -0
- package/dist/knowledge/abap/rap-unmanaged.md +468 -0
- package/dist/knowledge/abap/string-processing.md +180 -0
- package/dist/knowledge/abap/unit-testing.md +303 -0
- package/dist/knowledge/abap-cds/access-control.md +241 -0
- package/dist/knowledge/abap-cds/annotations.md +331 -0
- package/dist/knowledge/abap-cds/associations.md +254 -0
- package/dist/knowledge/abap-cds/expressions.md +230 -0
- package/dist/knowledge/abap-cds/functions.md +245 -0
- package/dist/knowledge/abap-cds/metadata-extensions.md +294 -0
- package/dist/knowledge/cap/authentication.md +278 -0
- package/dist/knowledge/cap/cdl-syntax.md +247 -0
- package/dist/knowledge/cap/cql-queries.md +266 -0
- package/dist/knowledge/cap/deployment.md +343 -0
- package/dist/knowledge/cap/event-handlers.md +287 -0
- package/dist/knowledge/cap/fiori-integration.md +303 -0
- package/dist/knowledge/cap/service-definitions.md +287 -0
- package/dist/knowledge/fiori/annotations.md +347 -0
- package/dist/knowledge/fiori/deployment.md +340 -0
- package/dist/knowledge/fiori/fiori-elements.md +332 -0
- package/dist/knowledge/fiori/fiori-side-effects.md +107 -0
- package/dist/knowledge/fiori/fiori-valuelist.md +144 -0
- package/dist/knowledge/fiori/ui5-controllers.md +358 -0
- package/dist/knowledge/fiori/ui5-data-binding.md +311 -0
- package/dist/knowledge/fiori/ui5-fragments-dialogs.md +330 -0
- package/dist/knowledge/fiori/ui5-manifest.md +411 -0
- package/dist/knowledge/fiori/ui5-routing.md +303 -0
- package/dist/knowledge/fiori/ui5-xml-views.md +294 -0
- package/dist/logger.js +114 -0
- package/dist/system-profile.js +207 -0
- package/dist/tools/abap-doc.js +72 -0
- package/dist/tools/abapgit.js +161 -0
- package/dist/tools/activate.js +68 -0
- package/dist/tools/atc-check.js +117 -0
- package/dist/tools/auth-object.js +56 -0
- package/dist/tools/breakpoints.js +76 -0
- package/dist/tools/call-hierarchy.js +84 -0
- package/dist/tools/cds-annotations.js +98 -0
- package/dist/tools/cds-dependencies.js +65 -0
- package/dist/tools/check.js +47 -0
- package/dist/tools/code-completion.js +70 -0
- package/dist/tools/code-coverage.js +111 -0
- package/dist/tools/create-amdp.js +111 -0
- package/dist/tools/create-dcl.js +81 -0
- package/dist/tools/create-transport.js +38 -0
- package/dist/tools/create.js +285 -0
- package/dist/tools/data-preview.js +37 -0
- package/dist/tools/delete.js +45 -0
- package/dist/tools/deploy-bsp.js +298 -0
- package/dist/tools/discovery.js +59 -0
- package/dist/tools/element-info.js +93 -0
- package/dist/tools/enhancements.js +186 -0
- package/dist/tools/extract-method.js +44 -0
- package/dist/tools/function-group.js +59 -0
- package/dist/tools/knowledge.js +275 -0
- package/dist/tools/lock-object.js +75 -0
- package/dist/tools/message-class.js +67 -0
- package/dist/tools/navigate.js +80 -0
- package/dist/tools/number-range.js +57 -0
- package/dist/tools/object-documentation.js +43 -0
- package/dist/tools/object-structure.js +78 -0
- package/dist/tools/object-versions.js +57 -0
- package/dist/tools/package-contents.js +60 -0
- package/dist/tools/pretty-printer.js +35 -0
- package/dist/tools/publish-binding.js +49 -0
- package/dist/tools/quick-fix.js +69 -0
- package/dist/tools/read.js +167 -0
- package/dist/tools/refactor-rename.js +60 -0
- package/dist/tools/release-transport.js +24 -0
- package/dist/tools/released-apis.js +51 -0
- package/dist/tools/repository-tree.js +90 -0
- package/dist/tools/scaffold-rap.js +642 -0
- package/dist/tools/search.js +73 -0
- package/dist/tools/shared/data-format.js +101 -0
- package/dist/tools/sql-console.js +17 -0
- package/dist/tools/system-info.js +270 -0
- package/dist/tools/traces.js +66 -0
- package/dist/tools/transport-contents.js +83 -0
- package/dist/tools/transports.js +67 -0
- package/dist/tools/unit-test.js +135 -0
- package/dist/tools/where-used.js +59 -0
- package/dist/tools/write.js +101 -0
- package/package.json +49 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# ABAP Dictionary — domains, data elements, table types, structures, tables
|
|
2
|
+
|
|
3
|
+
## Domain (DOMA)
|
|
4
|
+
|
|
5
|
+
```abap
|
|
6
|
+
" Defines technical attributes + value range
|
|
7
|
+
" Created in ADT or SE11
|
|
8
|
+
|
|
9
|
+
" Key properties:
|
|
10
|
+
" - Data type (CHAR, NUMC, DEC, CURR, QUAN, DATS, TIMS, INT4, STRING, etc.)
|
|
11
|
+
" - Length / decimals
|
|
12
|
+
" - Fixed values (value list)
|
|
13
|
+
" - Conversion routine (ALPHA, MATN1, CUNIT, etc.)
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### Common data types for domains
|
|
17
|
+
|
|
18
|
+
| Type | Description | Example |
|
|
19
|
+
|------|-------------|---------|
|
|
20
|
+
| `CHAR(n)` | Character | Status (1), Name (40) |
|
|
21
|
+
| `NUMC(n)` | Numeric text | Order number (10) |
|
|
22
|
+
| `DEC(n,d)` | Packed decimal | Amount (15,2) |
|
|
23
|
+
| `CURR(n,d)` | Currency amount | Price (17,2) — needs currency reference |
|
|
24
|
+
| `QUAN(n,d)` | Quantity | Weight (13,3) — needs unit reference |
|
|
25
|
+
| `DATS` | Date (8) | YYYYMMDD |
|
|
26
|
+
| `TIMS` | Time (6) | HHMMSS |
|
|
27
|
+
| `INT4` | Integer (4 bytes) | Counter |
|
|
28
|
+
| `STRING` | Variable length | Long text |
|
|
29
|
+
| `RAWSTRING` | Variable binary | File content |
|
|
30
|
+
| `CUKY(5)` | Currency key | EUR, USD |
|
|
31
|
+
| `UNIT(3)` | Unit of measure | KG, PC |
|
|
32
|
+
|
|
33
|
+
### Conversion routines
|
|
34
|
+
|
|
35
|
+
| Routine | Effect | Example |
|
|
36
|
+
|---------|--------|---------|
|
|
37
|
+
| `ALPHA` | Leading zeros | 1234 ↔ 0000001234 |
|
|
38
|
+
| `MATN1` | Material number | 123 ↔ 000000000000000123 |
|
|
39
|
+
| `CUNIT` | Unit of measure | KG ↔ KG (ISO conversion) |
|
|
40
|
+
| `ISOLA` | Language | EN ↔ E |
|
|
41
|
+
|
|
42
|
+
## Data Element (DTEL)
|
|
43
|
+
|
|
44
|
+
```abap
|
|
45
|
+
" Links domain to semantic meaning
|
|
46
|
+
" Provides: field labels (short, medium, long, heading), F1 help, search help
|
|
47
|
+
|
|
48
|
+
" Key properties:
|
|
49
|
+
" - Domain reference (technical type) OR direct type specification
|
|
50
|
+
" - Labels: Short (10), Medium (20), Long (40), Heading (55)
|
|
51
|
+
" - Documentation (F1 help)
|
|
52
|
+
" - Search help attachment
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Built-in data elements for RAP
|
|
56
|
+
|
|
57
|
+
| Data Element | Type | Usage |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| `abp_creation_user` | CHAR 12 | @Semantics.user.createdBy |
|
|
60
|
+
| `abp_creation_tstmpl` | TIMESTAMPL | @Semantics.systemDateTime.createdAt |
|
|
61
|
+
| `abp_locinst_lastchange_user` | CHAR 12 | @Semantics.user.localInstanceLastChangedBy |
|
|
62
|
+
| `abp_locinst_lastchange_tstmpl` | TIMESTAMPL | @Semantics.systemDateTime.localInstanceLastChangedAt |
|
|
63
|
+
| `abp_lastchange_tstmpl` | TIMESTAMPL | @Semantics.systemDateTime.lastChangedAt |
|
|
64
|
+
|
|
65
|
+
## Structure (TABL type S)
|
|
66
|
+
|
|
67
|
+
```abap
|
|
68
|
+
" Flat structure — defined in ADT as TABL with category Structure
|
|
69
|
+
define structure zs_address {
|
|
70
|
+
street : abap.char(60);
|
|
71
|
+
city : abap.char(40);
|
|
72
|
+
zipcode : abap.char(10);
|
|
73
|
+
country : abap.char(3);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
" In ABAP code — inline structure type
|
|
77
|
+
TYPES: BEGIN OF zts_order_item,
|
|
78
|
+
order_id TYPE numc10,
|
|
79
|
+
item_no TYPE numc6,
|
|
80
|
+
material TYPE matnr,
|
|
81
|
+
quantity TYPE menge_d,
|
|
82
|
+
price TYPE netwr,
|
|
83
|
+
END OF zts_order_item.
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Table Type (TTYP)
|
|
87
|
+
|
|
88
|
+
```abap
|
|
89
|
+
" Standard table type
|
|
90
|
+
define table type ztt_order_items {
|
|
91
|
+
type: zs_order_item;
|
|
92
|
+
tableCategory: STANDARD;
|
|
93
|
+
key: order_id, item_no;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
" In ABAP code
|
|
97
|
+
TYPES ztt_items TYPE STANDARD TABLE OF zts_order_item WITH DEFAULT KEY.
|
|
98
|
+
TYPES ztt_items_sorted TYPE SORTED TABLE OF zts_order_item WITH UNIQUE KEY order_id item_no.
|
|
99
|
+
TYPES ztt_items_hashed TYPE HASHED TABLE OF zts_order_item WITH UNIQUE KEY order_id item_no.
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Transparent Table (TABL type T)
|
|
103
|
+
|
|
104
|
+
```abap
|
|
105
|
+
@EndUserText.label : 'Order Header'
|
|
106
|
+
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
|
|
107
|
+
@AbapCatalog.tableCategory : #TRANSPARENT
|
|
108
|
+
@AbapCatalog.deliveryClass : #A
|
|
109
|
+
@AbapCatalog.dataMaintenance : #RESTRICTED
|
|
110
|
+
define table ztab_order {
|
|
111
|
+
key client : abap.clnt not null;
|
|
112
|
+
key order_id : abap.numc(10) not null;
|
|
113
|
+
customer_id : kunnr;
|
|
114
|
+
order_date : abap.dats;
|
|
115
|
+
@AbapCatalog.currency.currencyCode : 'ztab_order.currency_code'
|
|
116
|
+
total_amount : abap.curr(17,2);
|
|
117
|
+
currency_code : abap.cuky(5);
|
|
118
|
+
status : abap.char(1);
|
|
119
|
+
description : abap.char(256);
|
|
120
|
+
created_by : abp_creation_user;
|
|
121
|
+
created_at : abp_creation_tstmpl;
|
|
122
|
+
last_changed_by : abp_locinst_lastchange_user;
|
|
123
|
+
last_changed_at : abp_locinst_lastchange_tstmpl;
|
|
124
|
+
local_last_changed_at : abp_lastchange_tstmpl;
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Delivery Class
|
|
129
|
+
|
|
130
|
+
| Class | Description | Use |
|
|
131
|
+
|:-----:|-------------|-----|
|
|
132
|
+
| `A` | Application table | Custom data (default for Z tables) |
|
|
133
|
+
| `C` | Customizing | Config maintained by user |
|
|
134
|
+
| `L` | Temporary | Transient data, no transport |
|
|
135
|
+
| `G` | Customizing (protected) | System config |
|
|
136
|
+
| `S` | System table | SAP internal |
|
|
137
|
+
|
|
138
|
+
### Table Category
|
|
139
|
+
|
|
140
|
+
| Category | Description |
|
|
141
|
+
|----------|-------------|
|
|
142
|
+
| `#TRANSPARENT` | Regular DB table |
|
|
143
|
+
| `#STRUCTURE` | No DB persistence |
|
|
144
|
+
| `#APPEND` | Append structure |
|
|
145
|
+
| `#GLOBAL_TEMPORARY` | Session-scoped temp table |
|
|
146
|
+
|
|
147
|
+
## CURR/QUAN Reference Annotations
|
|
148
|
+
|
|
149
|
+
```abap
|
|
150
|
+
" CURR must reference CUKY field
|
|
151
|
+
@AbapCatalog.currency.currencyCode : 'ztab_order.currency_code'
|
|
152
|
+
total_amount : abap.curr(17,2);
|
|
153
|
+
currency_code : abap.cuky(5);
|
|
154
|
+
|
|
155
|
+
" QUAN must reference UNIT field
|
|
156
|
+
@AbapCatalog.quantity.unitOfMeasure : 'ztab_order.unit'
|
|
157
|
+
weight : abap.quan(13,3);
|
|
158
|
+
unit : abap.unit(3);
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## CDS View Entity — Consuming DDIC
|
|
162
|
+
|
|
163
|
+
```abap
|
|
164
|
+
@AccessControl.authorizationCheck: #CHECK
|
|
165
|
+
define view entity ZI_Order as select from ztab_order
|
|
166
|
+
{
|
|
167
|
+
key order_id as OrderID,
|
|
168
|
+
customer_id as CustomerID,
|
|
169
|
+
order_date as OrderDate,
|
|
170
|
+
@Semantics.amount.currencyCode: 'CurrencyCode'
|
|
171
|
+
total_amount as TotalAmount,
|
|
172
|
+
currency_code as CurrencyCode,
|
|
173
|
+
status as Status,
|
|
174
|
+
@Semantics.user.createdBy: true
|
|
175
|
+
created_by as CreatedBy,
|
|
176
|
+
@Semantics.systemDateTime.createdAt: true
|
|
177
|
+
created_at as CreatedAt
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Rules
|
|
182
|
+
- CURR fields MUST have `@AbapCatalog.currency.currencyCode` referencing CUKY field
|
|
183
|
+
- QUAN fields MUST have `@AbapCatalog.quantity.unitOfMeasure` referencing UNIT field
|
|
184
|
+
- RAP tables: always include 5 admin fields (created_by/at, last_changed_by/at, local_last_changed_at)
|
|
185
|
+
- Use delivery class A for custom application tables
|
|
186
|
+
- Key fields: always include `client : abap.clnt not null` as first key for client-dependent tables
|
|
187
|
+
- Use NUMC for business keys (order numbers, document numbers) — enables ALPHA conversion
|
|
188
|
+
- Use data elements (not direct types) for reusable fields — provides labels + search helps
|
|
189
|
+
|
|
190
|
+
## Anti-Patterns
|
|
191
|
+
| Anti-Pattern | Correct |
|
|
192
|
+
|---|---|
|
|
193
|
+
| CURR field without CUKY reference | Always pair with `@AbapCatalog.currency.currencyCode` |
|
|
194
|
+
| QUAN field without UNIT reference | Always pair with `@AbapCatalog.quantity.unitOfMeasure` |
|
|
195
|
+
| RAP table without admin fields | Include all 5 timestamp/user fields |
|
|
196
|
+
| `abap.char(1)` for boolean | Use `abap_boolean` or domain with X/'' values |
|
|
197
|
+
| Delivery class L for persistent data | Use A (application data) or C (customizing) |
|
|
198
|
+
| Missing `not null` on key fields | All key fields must be `not null` |
|
|
199
|
+
| Client field missing from table | Include `key client : abap.clnt not null` for client-dependent |
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
# ABAP SQL — SELECT, JOIN, CTE, aggregation, DML
|
|
2
|
+
|
|
3
|
+
## Basic SELECT
|
|
4
|
+
|
|
5
|
+
```abap
|
|
6
|
+
" Single row
|
|
7
|
+
SELECT SINGLE * FROM ztab_orders INTO @DATA(zs_order) WHERE order_id = '1000'.
|
|
8
|
+
|
|
9
|
+
" Into internal table
|
|
10
|
+
SELECT * FROM ztab_orders INTO TABLE @DATA(zt_orders).
|
|
11
|
+
|
|
12
|
+
" Specific fields with alias
|
|
13
|
+
SELECT order_id AS id, customer, amount
|
|
14
|
+
FROM ztab_orders
|
|
15
|
+
INTO TABLE @DATA(zt_result).
|
|
16
|
+
|
|
17
|
+
" UP TO n ROWS + OFFSET (paging)
|
|
18
|
+
SELECT * FROM ztab_orders
|
|
19
|
+
INTO TABLE @DATA(zt_page)
|
|
20
|
+
UP TO 20 ROWS OFFSET 40.
|
|
21
|
+
|
|
22
|
+
" DISTINCT
|
|
23
|
+
SELECT DISTINCT category FROM ztab_orders INTO TABLE @DATA(zt_cats).
|
|
24
|
+
|
|
25
|
+
" Calculated fields
|
|
26
|
+
SELECT order_id, price * quantity AS total
|
|
27
|
+
FROM ztab_items
|
|
28
|
+
INTO TABLE @DATA(zt_totals).
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## WHERE Conditions
|
|
32
|
+
|
|
33
|
+
```abap
|
|
34
|
+
" Comparison
|
|
35
|
+
WHERE amount > 1000
|
|
36
|
+
WHERE status <> 'D'
|
|
37
|
+
|
|
38
|
+
" BETWEEN
|
|
39
|
+
WHERE created_at BETWEEN '20250101' AND '20251231'
|
|
40
|
+
|
|
41
|
+
" IN list
|
|
42
|
+
WHERE status IN ( 'A', 'B', 'C' )
|
|
43
|
+
|
|
44
|
+
" LIKE pattern
|
|
45
|
+
WHERE name LIKE 'SAP%' " Starts with
|
|
46
|
+
WHERE name LIKE '%GmbH' " Ends with
|
|
47
|
+
WHERE code LIKE 'A_C' " Single char wildcard
|
|
48
|
+
|
|
49
|
+
" NULL handling
|
|
50
|
+
WHERE description IS NOT NULL
|
|
51
|
+
WHERE field IS NOT INITIAL
|
|
52
|
+
|
|
53
|
+
" Combined
|
|
54
|
+
WHERE ( status = 'A' OR status = 'B' ) AND amount >= 100
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## FOR ALL ENTRIES
|
|
58
|
+
|
|
59
|
+
```abap
|
|
60
|
+
" MUST check IS NOT INITIAL — empty table returns ALL rows
|
|
61
|
+
IF zt_keys IS NOT INITIAL.
|
|
62
|
+
SELECT * FROM ztab_orders
|
|
63
|
+
FOR ALL ENTRIES IN @zt_keys
|
|
64
|
+
WHERE order_id = @zt_keys-order_id
|
|
65
|
+
AND item_no = @zt_keys-item_no
|
|
66
|
+
INTO TABLE @DATA(zt_matched).
|
|
67
|
+
ENDIF.
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## JOIN Operations
|
|
71
|
+
|
|
72
|
+
```abap
|
|
73
|
+
" INNER JOIN
|
|
74
|
+
SELECT o~order_id, o~customer, c~name
|
|
75
|
+
FROM ztab_orders AS o
|
|
76
|
+
INNER JOIN ztab_customers AS c ON o~customer = c~customer_id
|
|
77
|
+
INTO TABLE @DATA(zt_joined).
|
|
78
|
+
|
|
79
|
+
" LEFT OUTER JOIN — all from left, NULL if no match
|
|
80
|
+
SELECT o~order_id, i~item_no, i~description
|
|
81
|
+
FROM ztab_orders AS o
|
|
82
|
+
LEFT OUTER JOIN ztab_items AS i ON o~order_id = i~order_id
|
|
83
|
+
INTO TABLE @DATA(zt_left).
|
|
84
|
+
|
|
85
|
+
" Multiple JOINs
|
|
86
|
+
SELECT o~order_id, c~name, i~description
|
|
87
|
+
FROM ztab_orders AS o
|
|
88
|
+
INNER JOIN ztab_customers AS c ON o~customer = c~customer_id
|
|
89
|
+
INNER JOIN ztab_items AS i ON o~order_id = i~order_id
|
|
90
|
+
INTO TABLE @DATA(zt_full).
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Aggregate Functions
|
|
94
|
+
|
|
95
|
+
```abap
|
|
96
|
+
SELECT COUNT(*) FROM ztab_orders INTO @DATA(lv_count).
|
|
97
|
+
|
|
98
|
+
SELECT customer,
|
|
99
|
+
COUNT(*) AS order_count,
|
|
100
|
+
SUM( amount ) AS total_amount,
|
|
101
|
+
AVG( amount ) AS avg_amount,
|
|
102
|
+
MIN( created_at ) AS first_order,
|
|
103
|
+
MAX( created_at ) AS last_order
|
|
104
|
+
FROM ztab_orders
|
|
105
|
+
GROUP BY customer
|
|
106
|
+
INTO TABLE @DATA(zt_stats).
|
|
107
|
+
|
|
108
|
+
" HAVING — filter on aggregates
|
|
109
|
+
SELECT customer, COUNT(*) AS cnt
|
|
110
|
+
FROM ztab_orders
|
|
111
|
+
GROUP BY customer
|
|
112
|
+
HAVING COUNT(*) > 5
|
|
113
|
+
INTO TABLE @DATA(zt_frequent).
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Subqueries
|
|
117
|
+
|
|
118
|
+
```abap
|
|
119
|
+
" EXISTS
|
|
120
|
+
SELECT * FROM ztab_customers AS c
|
|
121
|
+
WHERE EXISTS ( SELECT * FROM ztab_orders AS o
|
|
122
|
+
WHERE o~customer = c~customer_id )
|
|
123
|
+
INTO TABLE @DATA(zt_with_orders).
|
|
124
|
+
|
|
125
|
+
" NOT EXISTS
|
|
126
|
+
SELECT * FROM ztab_customers AS c
|
|
127
|
+
WHERE NOT EXISTS ( SELECT * FROM ztab_orders AS o
|
|
128
|
+
WHERE o~customer = c~customer_id )
|
|
129
|
+
INTO TABLE @DATA(zt_no_orders).
|
|
130
|
+
|
|
131
|
+
" IN subquery
|
|
132
|
+
SELECT * FROM ztab_customers
|
|
133
|
+
WHERE customer_id IN ( SELECT customer FROM ztab_orders
|
|
134
|
+
WHERE amount > 10000 )
|
|
135
|
+
INTO TABLE @DATA(zt_big_spenders).
|
|
136
|
+
|
|
137
|
+
" Scalar subquery
|
|
138
|
+
SELECT customer,
|
|
139
|
+
( SELECT COUNT(*) FROM ztab_orders AS o
|
|
140
|
+
WHERE o~customer = c~customer_id ) AS order_count
|
|
141
|
+
FROM ztab_customers AS c
|
|
142
|
+
INTO TABLE @DATA(zt_with_counts).
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Common Table Expressions (CTE)
|
|
146
|
+
|
|
147
|
+
```abap
|
|
148
|
+
WITH
|
|
149
|
+
+orders AS (
|
|
150
|
+
SELECT customer, COUNT(*) AS cnt, SUM( amount ) AS total
|
|
151
|
+
FROM ztab_orders
|
|
152
|
+
GROUP BY customer ),
|
|
153
|
+
+customers AS (
|
|
154
|
+
SELECT customer_id, name
|
|
155
|
+
FROM ztab_customers )
|
|
156
|
+
SELECT c~name, o~cnt, o~total
|
|
157
|
+
FROM +orders AS o
|
|
158
|
+
INNER JOIN +customers AS c ON o~customer = c~customer_id
|
|
159
|
+
INTO TABLE @DATA(zt_report).
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## CASE Expressions
|
|
163
|
+
|
|
164
|
+
```abap
|
|
165
|
+
SELECT order_id,
|
|
166
|
+
CASE status
|
|
167
|
+
WHEN 'A' THEN 'Active'
|
|
168
|
+
WHEN 'C' THEN 'Closed'
|
|
169
|
+
ELSE 'Unknown'
|
|
170
|
+
END AS status_text,
|
|
171
|
+
CASE
|
|
172
|
+
WHEN amount < 100 THEN 'Small'
|
|
173
|
+
WHEN amount < 1000 THEN 'Medium'
|
|
174
|
+
ELSE 'Large'
|
|
175
|
+
END AS size_category
|
|
176
|
+
FROM ztab_orders
|
|
177
|
+
INTO TABLE @DATA(zt_classified).
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## SQL Functions
|
|
181
|
+
|
|
182
|
+
```abap
|
|
183
|
+
" String
|
|
184
|
+
SELECT CONCAT_WITH_SPACE( first_name, last_name, 1 ) AS full_name,
|
|
185
|
+
UPPER( name ) AS upper_name,
|
|
186
|
+
SUBSTRING( code, 1, 3 ) AS prefix,
|
|
187
|
+
LENGTH( description ) AS desc_len,
|
|
188
|
+
REPLACE( text, 'old', 'new' ) AS replaced,
|
|
189
|
+
LPAD( id, 10, '0' ) AS padded_id
|
|
190
|
+
FROM ztab_data INTO TABLE @DATA(zt_str).
|
|
191
|
+
|
|
192
|
+
" Numeric
|
|
193
|
+
SELECT ABS( amount ) AS absolute,
|
|
194
|
+
ROUND( price, 2 ) AS rounded,
|
|
195
|
+
CEIL( value ) AS ceiling,
|
|
196
|
+
FLOOR( value ) AS floored,
|
|
197
|
+
MOD( number, 10 ) AS remainder
|
|
198
|
+
FROM ztab_data INTO TABLE @DATA(zt_num).
|
|
199
|
+
|
|
200
|
+
" Date
|
|
201
|
+
SELECT DATS_DAYS_BETWEEN( date1, date2 ) AS diff,
|
|
202
|
+
DATS_ADD_DAYS( created_at, 30 ) AS due_date,
|
|
203
|
+
EXTRACT_YEAR( created_at ) AS year
|
|
204
|
+
FROM ztab_data INTO TABLE @DATA(zt_dates).
|
|
205
|
+
|
|
206
|
+
" COALESCE — NULL handling
|
|
207
|
+
SELECT COALESCE( description, 'N/A' ) AS desc
|
|
208
|
+
FROM ztab_data INTO TABLE @DATA(zt_null).
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## ORDER BY
|
|
212
|
+
|
|
213
|
+
```abap
|
|
214
|
+
SELECT * FROM ztab_orders
|
|
215
|
+
ORDER BY customer ASCENDING, amount DESCENDING
|
|
216
|
+
INTO TABLE @DATA(zt_sorted).
|
|
217
|
+
|
|
218
|
+
SELECT customer, COUNT(*) AS cnt
|
|
219
|
+
FROM ztab_orders
|
|
220
|
+
GROUP BY customer
|
|
221
|
+
ORDER BY cnt DESCENDING
|
|
222
|
+
INTO TABLE @DATA(zt_ranked).
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## DML — INSERT, UPDATE, MODIFY, DELETE
|
|
226
|
+
|
|
227
|
+
```abap
|
|
228
|
+
" INSERT
|
|
229
|
+
INSERT ztab_orders FROM @zs_order.
|
|
230
|
+
INSERT ztab_orders FROM TABLE @zt_orders.
|
|
231
|
+
|
|
232
|
+
" UPDATE
|
|
233
|
+
UPDATE ztab_orders SET status = 'C' WHERE order_id = '1000'.
|
|
234
|
+
UPDATE ztab_orders FROM @zs_order.
|
|
235
|
+
UPDATE ztab_orders FROM TABLE @zt_orders.
|
|
236
|
+
|
|
237
|
+
" MODIFY — INSERT or UPDATE by key
|
|
238
|
+
MODIFY ztab_orders FROM @zs_order.
|
|
239
|
+
MODIFY ztab_orders FROM TABLE @zt_orders.
|
|
240
|
+
|
|
241
|
+
" DELETE
|
|
242
|
+
DELETE FROM ztab_orders WHERE status = 'D'.
|
|
243
|
+
DELETE ztab_orders FROM TABLE @zt_del_keys.
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## INDICATORS for Partial Updates
|
|
247
|
+
|
|
248
|
+
```abap
|
|
249
|
+
DATA zs_upd TYPE ztab_orders.
|
|
250
|
+
DATA zs_ind TYPE ztab_orders_indicators.
|
|
251
|
+
|
|
252
|
+
zs_upd-order_id = '1000'.
|
|
253
|
+
zs_upd-status = 'C'.
|
|
254
|
+
zs_ind-status = abap_true.
|
|
255
|
+
|
|
256
|
+
UPDATE ztab_orders FROM @zs_upd INDICATORS SET STRUCTURE zs_ind.
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## PACKAGE SIZE
|
|
260
|
+
|
|
261
|
+
```abap
|
|
262
|
+
SELECT * FROM ztab_orders INTO TABLE @DATA(zt_chunk) PACKAGE SIZE 1000.
|
|
263
|
+
" Process chunk
|
|
264
|
+
CLEAR zt_chunk.
|
|
265
|
+
ENDSELECT.
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## Rules
|
|
271
|
+
|
|
272
|
+
- Always SELECT only needed fields — avoid `SELECT *` in production
|
|
273
|
+
- Always check `IS NOT INITIAL` before FOR ALL ENTRIES
|
|
274
|
+
- Use JOINs instead of nested SELECTs or SELECT in LOOP
|
|
275
|
+
- Use aggregate functions in SQL, not in ABAP after SELECT
|
|
276
|
+
- Use CTE for complex multi-step queries
|
|
277
|
+
- Use `@DATA(...)` inline declarations for results
|
|
278
|
+
- Use PACKAGE SIZE for processing millions of rows
|
|
279
|
+
- Escape host variables with `@` in new ABAP SQL syntax
|
|
280
|
+
- Use COALESCE for NULL-safe field access in outer joins
|
|
281
|
+
- Use ORDER BY in SQL when possible, avoid SORT after SELECT
|
|
282
|
+
|
|
283
|
+
## Anti-Patterns
|
|
284
|
+
|
|
285
|
+
| Anti-Pattern | Correct Approach |
|
|
286
|
+
|---|---|
|
|
287
|
+
| `SELECT * FROM dbtab` in production | `SELECT field1, field2 FROM dbtab` |
|
|
288
|
+
| `SELECT ... ENDSELECT` (row-by-row) | `SELECT ... INTO TABLE @itab` |
|
|
289
|
+
| SELECT inside LOOP | Use JOIN or FOR ALL ENTRIES |
|
|
290
|
+
| FOR ALL ENTRIES without empty check | `IF itab IS NOT INITIAL` before SELECT |
|
|
291
|
+
| `SELECT ... ORDER BY` then `SORT itab` | ORDER BY in SQL is sufficient |
|
|
292
|
+
| Aggregating in ABAP (LOOP + sum) | `SELECT SUM( field )` in SQL |
|
|
293
|
+
| `SELECT COUNT(*) ... WHERE` to check existence | `SELECT SINGLE @abap_true ... INTO @DATA(lv_exists)` |
|
|
294
|
+
| Using `MODIFY dbtab` when only UPDATE needed | Use UPDATE for explicit intent |
|
|
295
|
+
| Missing `@` escape for host variables | Always use `@` in new syntax |
|
|
296
|
+
| `DELETE FROM dbtab` without WHERE (deletes all) | Always add WHERE clause |
|