@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.
Files changed (114) hide show
  1. package/README.md +384 -0
  2. package/dist/adt-client.js +364 -0
  3. package/dist/cli/activate.js +113 -0
  4. package/dist/cli/init.js +333 -0
  5. package/dist/cli/remove.js +80 -0
  6. package/dist/cli/status.js +229 -0
  7. package/dist/cli/systems.js +68 -0
  8. package/dist/cli.js +81 -0
  9. package/dist/index.js +1318 -0
  10. package/dist/knowledge/abap/abap-dictionary.md +199 -0
  11. package/dist/knowledge/abap/abap-sql.md +296 -0
  12. package/dist/knowledge/abap/amdp.md +273 -0
  13. package/dist/knowledge/abap/clean-code.md +293 -0
  14. package/dist/knowledge/abap/cloud-background-processing.md +250 -0
  15. package/dist/knowledge/abap/cloud-communication.md +265 -0
  16. package/dist/knowledge/abap/cloud-development.md +176 -0
  17. package/dist/knowledge/abap/cloud-extensibility.md +252 -0
  18. package/dist/knowledge/abap/cloud-released-apis.md +261 -0
  19. package/dist/knowledge/abap/constructor-expressions.md +289 -0
  20. package/dist/knowledge/abap/enhancements.md +232 -0
  21. package/dist/knowledge/abap/exceptions.md +271 -0
  22. package/dist/knowledge/abap/internal-tables.md +205 -0
  23. package/dist/knowledge/abap/object-orientation.md +298 -0
  24. package/dist/knowledge/abap/performance.md +216 -0
  25. package/dist/knowledge/abap/rap-abstract-entities.md +206 -0
  26. package/dist/knowledge/abap/rap-business-events.md +216 -0
  27. package/dist/knowledge/abap/rap-draft.md +191 -0
  28. package/dist/knowledge/abap/rap-eml.md +453 -0
  29. package/dist/knowledge/abap/rap-end-to-end.md +486 -0
  30. package/dist/knowledge/abap/rap-feature-control.md +185 -0
  31. package/dist/knowledge/abap/rap-numbering.md +280 -0
  32. package/dist/knowledge/abap/rap-service-exposure.md +163 -0
  33. package/dist/knowledge/abap/rap-unmanaged.md +468 -0
  34. package/dist/knowledge/abap/string-processing.md +180 -0
  35. package/dist/knowledge/abap/unit-testing.md +303 -0
  36. package/dist/knowledge/abap-cds/access-control.md +241 -0
  37. package/dist/knowledge/abap-cds/annotations.md +331 -0
  38. package/dist/knowledge/abap-cds/associations.md +254 -0
  39. package/dist/knowledge/abap-cds/expressions.md +230 -0
  40. package/dist/knowledge/abap-cds/functions.md +245 -0
  41. package/dist/knowledge/abap-cds/metadata-extensions.md +294 -0
  42. package/dist/knowledge/cap/authentication.md +278 -0
  43. package/dist/knowledge/cap/cdl-syntax.md +247 -0
  44. package/dist/knowledge/cap/cql-queries.md +266 -0
  45. package/dist/knowledge/cap/deployment.md +343 -0
  46. package/dist/knowledge/cap/event-handlers.md +287 -0
  47. package/dist/knowledge/cap/fiori-integration.md +303 -0
  48. package/dist/knowledge/cap/service-definitions.md +287 -0
  49. package/dist/knowledge/fiori/annotations.md +347 -0
  50. package/dist/knowledge/fiori/deployment.md +340 -0
  51. package/dist/knowledge/fiori/fiori-elements.md +332 -0
  52. package/dist/knowledge/fiori/fiori-side-effects.md +107 -0
  53. package/dist/knowledge/fiori/fiori-valuelist.md +144 -0
  54. package/dist/knowledge/fiori/ui5-controllers.md +358 -0
  55. package/dist/knowledge/fiori/ui5-data-binding.md +311 -0
  56. package/dist/knowledge/fiori/ui5-fragments-dialogs.md +330 -0
  57. package/dist/knowledge/fiori/ui5-manifest.md +411 -0
  58. package/dist/knowledge/fiori/ui5-routing.md +303 -0
  59. package/dist/knowledge/fiori/ui5-xml-views.md +294 -0
  60. package/dist/logger.js +114 -0
  61. package/dist/system-profile.js +207 -0
  62. package/dist/tools/abap-doc.js +72 -0
  63. package/dist/tools/abapgit.js +161 -0
  64. package/dist/tools/activate.js +68 -0
  65. package/dist/tools/atc-check.js +117 -0
  66. package/dist/tools/auth-object.js +56 -0
  67. package/dist/tools/breakpoints.js +76 -0
  68. package/dist/tools/call-hierarchy.js +84 -0
  69. package/dist/tools/cds-annotations.js +98 -0
  70. package/dist/tools/cds-dependencies.js +65 -0
  71. package/dist/tools/check.js +47 -0
  72. package/dist/tools/code-completion.js +70 -0
  73. package/dist/tools/code-coverage.js +111 -0
  74. package/dist/tools/create-amdp.js +111 -0
  75. package/dist/tools/create-dcl.js +81 -0
  76. package/dist/tools/create-transport.js +38 -0
  77. package/dist/tools/create.js +285 -0
  78. package/dist/tools/data-preview.js +37 -0
  79. package/dist/tools/delete.js +45 -0
  80. package/dist/tools/deploy-bsp.js +298 -0
  81. package/dist/tools/discovery.js +59 -0
  82. package/dist/tools/element-info.js +93 -0
  83. package/dist/tools/enhancements.js +186 -0
  84. package/dist/tools/extract-method.js +44 -0
  85. package/dist/tools/function-group.js +59 -0
  86. package/dist/tools/knowledge.js +275 -0
  87. package/dist/tools/lock-object.js +75 -0
  88. package/dist/tools/message-class.js +67 -0
  89. package/dist/tools/navigate.js +80 -0
  90. package/dist/tools/number-range.js +57 -0
  91. package/dist/tools/object-documentation.js +43 -0
  92. package/dist/tools/object-structure.js +78 -0
  93. package/dist/tools/object-versions.js +57 -0
  94. package/dist/tools/package-contents.js +60 -0
  95. package/dist/tools/pretty-printer.js +35 -0
  96. package/dist/tools/publish-binding.js +49 -0
  97. package/dist/tools/quick-fix.js +69 -0
  98. package/dist/tools/read.js +167 -0
  99. package/dist/tools/refactor-rename.js +60 -0
  100. package/dist/tools/release-transport.js +24 -0
  101. package/dist/tools/released-apis.js +51 -0
  102. package/dist/tools/repository-tree.js +90 -0
  103. package/dist/tools/scaffold-rap.js +642 -0
  104. package/dist/tools/search.js +73 -0
  105. package/dist/tools/shared/data-format.js +101 -0
  106. package/dist/tools/sql-console.js +17 -0
  107. package/dist/tools/system-info.js +270 -0
  108. package/dist/tools/traces.js +66 -0
  109. package/dist/tools/transport-contents.js +83 -0
  110. package/dist/tools/transports.js +67 -0
  111. package/dist/tools/unit-test.js +135 -0
  112. package/dist/tools/where-used.js +59 -0
  113. package/dist/tools/write.js +101 -0
  114. 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 |