ABAP SQL
ABAP SQL — підмножина SQL, вбудована в ABAP і незалежна від СКБД. Одна й та сама команда працює на HANA, Oracle, DB2. Ядро перекладає ABAP SQL у Native SQL конкретної бази і автоматично обробляє client handling, буферизацію, access control.
Ця сторінка — швидкий лук-ап основного синтаксису. Повний перелік нюансів — ABAP Keyword Documentation.
SELECT — базові форми
Section titled “SELECT — базові форми”" Окремі поля → внутрішня таблицяSELECT carrid, connid, fltime FROM zdemo_abap_flsch WHERE carrid = 'LH' INTO TABLE @DATA(flights).
" Усі поля → структура (перший рядок)SELECT SINGLE * FROM zdemo_abap_carr WHERE carrid = 'LH' INTO @DATA(carrier).
" АгрегаціяSELECT carrid, COUNT(*) AS cnt, SUM( fltime ) AS total FROM zdemo_abap_flsch GROUP BY carrid INTO TABLE @DATA(stats).Варіанти цілі
Section titled “Варіанти цілі”| Форма | Що робить |
|---|---|
INTO TABLE @itab | Повна заміна внутрішньої таблиці |
APPENDING TABLE @itab | Додає до наявної |
INTO @struct (+SINGLE) | Один рядок |
INTO (@v1, @v2, ...) | Окремі поля у окремі змінні |
INTO CORRESPONDING FIELDS OF TABLE @itab | Мапить по іменах (не всі поля SELECT мають бути у цілі) |
INTO NEW @DATA(ref) / INTO TABLE NEW @DATA(ref) | Створює анонімний data object, повертає data reference |
PACKAGE SIZE n | Читання батчами — відкриває цикл, у тілі обробляється чергова порція |
Inline-оголошення: INTO TABLE @DATA(result) — тип виводиться з SELECT-list.
" PACKAGE SIZE — батчева обробка великих наборівSELECT carrid, connid FROM zdemo_abap_flsch INTO TABLE @DATA(batch) PACKAGE SIZE 100. " тіло циклу: обробляємо batchENDSELECT.Клаузули
Section titled “Клаузули”SELECT carrid, connid, fltime FROM zdemo_abap_flsch WHERE carrid IN ('LH', 'AA') AND fltime > 200 GROUP BY carrid, connid, fltime " якщо є аґреґати — усі неаґреґовані обовʼязкові HAVING SUM( fltime ) > 1000 " фільтр після GROUP BY ORDER BY carrid, fltime DESCENDING INTO TABLE @DATA(res) UP TO 50 ROWS. " обмеження кількостіUP TO n ROWS і OFFSET n — для пагінації (працюють у парі з ORDER BY). FOR ALL ENTRIES IN @itab — альтернатива IN для великих списків, але з нюансами дедуплікації.
SELECT f.carrid, f.connid, c.carrname, p.price FROM zdemo_abap_flsch AS f INNER JOIN zdemo_abap_carr AS c ON c.carrid = f.carrid LEFT OUTER JOIN zdemo_abap_fli AS p ON p.carrid = f.carrid AND p.connid = f.connid INTO TABLE @DATA(joined).Підтримуються INNER JOIN, LEFT OUTER JOIN, RIGHT OUTER JOIN. Для CDS view entity з асоціаціями — path expressions (\_carr-carrname), див. CDS View Entities.
UNION / INTERSECT / EXCEPT
Section titled “UNION / INTERSECT / EXCEPT”SELECT carrid FROM zdemo_abap_carrUNIONSELECT carrid FROM zdemo_abap_flschINTO TABLE @DATA(all_carriers).UNION — обʼєднання без дублікатів, UNION ALL — з дублікатами, INTERSECT — перетин, EXCEPT — різниця.
CTE (Common Table Expressions)
Section titled “CTE (Common Table Expressions)”WITH дозволяє оголосити іменовані допоміжні запити:
WITH +heavy_flights AS ( SELECT carrid, connid FROM zdemo_abap_flsch WHERE fltime > 500 ), +result AS ( SELECT c.carrid, c.carrname FROM zdemo_abap_carr AS c INNER JOIN +heavy_flights AS h ON h.carrid = c.carrid ) SELECT * FROM +result INTO TABLE @DATA(out).Імена CTE починаються з +. Можна явно перелічити колонки: +heavy_flights( c, cn ) AS ( SELECT carrid, connid FROM ... ). У парі з PACKAGE SIZE цикл закривається ENDWITH. замість ENDSELECT.. Для ієрархій — WITH HIERARCHY, див. Ієрархії.
SQL-вирази
Section titled “SQL-вирази”У SELECT-list можна рахувати на стороні бази:
SELECT carrid, seatsocc + seatsmax AS total, seatsocc / seatsmax * 100 AS rate, CASE WHEN fltime > 300 THEN 'LONG' ELSE 'SHORT' END AS category, COALESCE( cityto, 'N/A' ) AS city_to, CAST( fltime AS DEC( 8, 2 ) ) AS fltime_dec FROM zdemo_abap_flsch INTO TABLE @DATA(res).Арифметика: +, -, *, /; CAST; CASE (simple і complex); COALESCE, NULLIF.
Вбудовані функції:
- Рядкові:
CONCAT,CONCAT_WITH_SPACE,INITCAP,UPPER,LOWER,LEFT,RIGHT,SUBSTRING,LENGTH,LPAD,RPAD,LTRIM,RTRIM,REPLACE,INSTR,LOCATE. - Regex:
LIKE_REGEXPR,LOCATE_REGEXPR,OCCURRENCES_REGEXPR,REPLACE_REGEXPR,SUBSTRING_REGEXPR. - Числові:
ABS,CEIL,FLOOR,ROUND,DIV,DIVISION,MOD. - Дата/час:
ADD_DAYS,ADD_MONTHS,IS_VALID. - Конвертація:
CURRENCY_CONVERSION,UNIT_CONVERSION,BINTOHEX,HEXTOBIN,TO_BLOB,TO_CLOB. - Aggregate / спец:
COUNT,SUM,AVG,MIN,MAX,STRING_AGG,UUID.
Типовані літерали
Section titled “Типовані літерали”SELECT carrid, char`X` AS flag, int4`42` AS magic, numc`007` AS code FROM zdemo_abap_carr WHERE carrid = char`LH` INTO TABLE @DATA(res).Формат: typenamevalue“. Типовані літерали — рекомендовані замість нетипованих ('X', 42), бо їх тип перевіряється на етапі активації.
CRUD-оператори
Section titled “CRUD-оператори”" Вставка з однієї структури / таблиціINSERT INTO zdemo_abap_tab VALUES @new_row.INSERT zdemo_abap_tab FROM TABLE @new_rows.
" ACCEPTING DUPLICATE KEYS — не падати на дублях, а пропускатиINSERT zdemo_abap_tab FROM TABLE @new_rows ACCEPTING DUPLICATE KEYS.
" Вставка результату SELECT (subquery)INSERT zdemo_abap_tab FROM ( SELECT * FROM other_tab WHERE carrid = 'LH' ).
" Оновлення за WHEREUPDATE zdemo_abap_tab SET field1 = 'X' WHERE carrid = 'LH'.
" Точкове — через структуру (оновлює усі не-ключові поля)UPDATE zdemo_abap_tab FROM @row.
" MODIFY — UPSERT (INSERT якщо немає, UPDATE якщо є)MODIFY zdemo_abap_tab FROM TABLE @rows.
" ВидаленняDELETE FROM zdemo_abap_tab WHERE carrid = 'AA'.DELETE zdemo_abap_tab FROM TABLE @to_delete.Результат — у sy-subrc (0 — успіх, 4 — нічого не змінилось). Кількість рядків — у sy-dbcnt.
MERGE — upsert на основі іншого джерела
Section titled “MERGE — upsert на основі іншого джерела”MERGE модифікує таблицю, звіряючи її з іншим джерелом даних (таблицею, CDS view, підзапитом). Для кожного рядка джерела — якщо збіг за ключем знайдено, робиться UPDATE; якщо ні — INSERT.
MERGE zdemo_abap_target USING @source_table AS s ON zdemo_abap_target~carrid = s~carrid WHEN MATCHED THEN UPDATE SET carrname = s~carrname WHEN NOT MATCHED THEN INSERT ( carrid, carrname ) VALUES ( s~carrid, s~carrname ).Відрізняється від ABAP-ного MODIFY FROM TABLE @rows тим, що джерело — SQL-запит або host-таблиця, а логіка upsert — декларативна через WHEN MATCHED / WHEN NOT MATCHED.
Динамічний SQL
Section titled “Динамічний SQL”Імена таблиць/полів/умови як рядки чи таблиці рядків:
DATA(tabname) = 'ZDEMO_ABAP_CARR'.DATA(fieldlist) = VALUE string_table( ( `carrid` ) ( `carrname` ) ).DATA(where_cond) = |carrid = 'LH'|.
SELECT (fieldlist) FROM (tabname) WHERE (where_cond) INTO TABLE @DATA(res).FOR ALL ENTRIES
Section titled “FOR ALL ENTRIES”Коли треба селект за списком, що сидить у internal table:
IF carriers IS NOT INITIAL. SELECT carrid, connid FROM zdemo_abap_flsch FOR ALL ENTRIES IN @carriers WHERE carrid = @carriers-carrid INTO TABLE @DATA(res).ENDIF.Альтернатива у modern ABAP — використовувати internal table безпосередньо як джерело даних у WHERE / JOIN (наприклад, WHERE fld IN @itab).
Адаптовано з 03_ABAP_SQL.md (Apache 2.0). Повний перелік нюансів — в оригіналі.