Умови WHERE
Клаузула WHERE зустрічається у двох контекстах: ABAP SQL (запити до бази) і обробка внутрішніх таблиць (LOOP AT, READ TABLE, DELETE, FILTER). Синтаксис схожий, але можливості відрізняються: у SQL ширший набір операторів і підзапити, у internal tables — обмеження на типи і відсутність NULL.
Ця сторінка — коротка шпаргалка по операторах, формам запису і типових пастках. Для повного переліку дивись ABAP Keyword Documentation.
SQL-оператори порівняння
Section titled “SQL-оператори порівняння”Базові: = (EQ), <> (NE), < (LT), > (GT), <= (LE), >= (GE). Комбінуються через AND, OR, NOT; дужки — для явного пріоритету.
SELECT carrid, connid, fltime FROM zdemo_abap_flsch WHERE carrid = 'LH' AND ( fltime > 300 OR cityto = 'NEW YORK' ) AND connid <> '0400' INTO TABLE @DATA(result).BETWEEN, LIKE, IN
Section titled “BETWEEN, LIKE, IN”" ДіапазонWHERE fltime BETWEEN 100 AND 300
" Шаблон: % — довільна послідовність, _ — один символWHERE cityfrom LIKE 'NEW%'
" ESCAPE — коли % або _ має бути літеральноWHERE animal LIKE '%#%' ESCAPE '#'
" Набір значеньWHERE carrid IN ( 'LH', 'AA', 'UA' )
" Кортежний IN — одночасна перевірка кількох колонокWHERE ( id, animal ) IN ( ( 1, 'bear' ), ( 3, 'giraffe' ) )
" Підзапит у INWHERE carrid IN ( SELECT carrid FROM zdemo_abap_carr WHERE currcode = 'USD' )ESCAPE у LIKE задає escape-символ довжиною 1: ESCAPE '#' означає, що #% і #_ у шаблоні трактуються буквально.
Ranges-таблиці
Section titled “Ranges-таблиці”IN приймає range table — внутрішню таблицю зі стандартною структурою SIGN/OPTION/LOW/HIGH. Зручно для умов селекційного екрана або динамічної фільтрації:
DATA rangestab TYPE RANGE OF i.rangestab = VALUE #( ( sign = 'I' option = 'BT' low = 1 high = 10 ) ).
SELECT id FROM @itab AS tab WHERE count IN @rangestab INTO TABLE @DATA(it).SIGN: I (include) / E (exclude). OPTION: EQ/NE/LT/LE/GT/GE/BT (between)/NB/CP (contains pattern)/NP.
Підзапити: EXISTS, ALL/ANY/SOME
Section titled “Підзапити: EXISTS, ALL/ANY/SOME”" Скалярний підзапитWHERE count = ( SELECT key_field FROM zdemo_abap_tab1 WHERE num1 = 40 )
" Квантори ALL / ANY / SOMEWHERE count > ALL ( SELECT key_field FROM zdemo_abap_tab1 )
" Корелюючий підзапит із EXISTSSELECT carrid, carrname FROM zdemo_abap_carr AS c WHERE EXISTS ( SELECT 'X' FROM zdemo_abap_flsch AS f WHERE f~carrid = c~carrid ) INTO TABLE @DATA(carriers_with_flights).IS NULL, IS INITIAL
Section titled “IS NULL, IS INITIAL”У ABAP SQL WHERE валідні обидва предикати: IS [NOT] NULL і IS [NOT] INITIAL.
" NULL у результатах outer join або nullable CDS-поляхWHERE cityto IS NOT NULL
" Ініціальне значення типу колонкиWHERE count IS NOT INITIALДинамічний WHERE
Section titled “Динамічний WHERE”WHERE-умову можна передати як символьний об’єкт або як внутрішню таблицю рядків:
" Один рядокDATA(dyn_where) = `count > 15`.
SELECT id FROM @itab AS tab WHERE (dyn_where) INTO TABLE @DATA(it).Таблиця рядків зручна для довгих умов — кожен елемент містить фрагмент (операнд, оператор, значення):
DATA(dyn_where_tab) = VALUE string_table( ( `animal = 'kangaroo'` ) ( `OR` ) ( `count = 4` ) ).
SELECT id FROM @itab AS tab WHERE (dyn_where_tab) INTO TABLE @DATA(it2).WHERE у внутрішніх таблицях
Section titled “WHERE у внутрішніх таблицях”Синтаксис схожий, але обмеженіший — тільки поля рядка таблиці, без підзапитів і без IS NULL (NULL в ABAP не існує як окреме значення). Натомість доступні символьні предикати (CO/CS/…) і предикати посилань (IS BOUND/IS INSTANCE OF).
" LOOP — обхід з фільтромLOOP AT flights INTO DATA(fl) WHERE carrid = 'LH' AND fltime > 200. " ...ENDLOOP.
" DELETE — видалити відфільтрованіDELETE flights WHERE carrid = 'AA'.
" READ TABLE — знайти перший рядок за умовоюREAD TABLE flights INTO DATA(first) WITH KEY carrid = 'LH'.
" FILTER — конструктор: новий стан з відфільтрованими рядкамиDATA(lh_only) = FILTER #( flights WHERE carrid = 'LH' ).Character/byte предикати
Section titled “Character/byte предикати”Для рядкових/байтових полів доступні предикати, яких немає у “звичайному” WHERE:
| Предикат | Значення |
|---|---|
CO (contains only) | Містить тільки перелічені символи |
CN (contains not only) | Містить не тільки |
CA (contains any) | Містить будь-який з |
NA (not any) | Не містить жодного з |
CS (contains string) | Містить підрядок |
NS (not string) | Не містить підрядок |
CP (covers pattern) | Відповідає шаблону (* і +) |
NP (no pattern) | Не відповідає шаблону |
Працюють у WHERE internal tables і у звичайних ABAP-виразах, не в SQL WHERE.
LOOP AT entries INTO DATA(e) WHERE code CP 'A+B*'. " ...ENDLOOP.IS BOUND / IS INSTANCE OF
Section titled “IS BOUND / IS INSTANCE OF”У WHERE для внутрішніх таблиць доступні також предикати для посилань:
LOOP AT refs INTO DATA(r) WHERE ref IS BOUND. " ...ENDLOOP.
LOOP AT refs INTO DATA(r2) WHERE ref IS INSTANCE OF zcl_special. " ...ENDLOOP.Швидка таблиця “де що доступно”
Section titled “Швидка таблиця “де що доступно””| Можливість | SQL WHERE | Internal table WHERE |
|---|---|---|
=, <>, <, >, <=, >= | так | так |
BETWEEN, LIKE, IN (список/range) | так | так |
Підзапит у IN, EXISTS, ALL/ANY/SOME | так | ні |
IS [NOT] NULL | так | ні |
IS [NOT] INITIAL | так | так |
CO/CN/CA/NA/CS/NS/CP/NP | ні | так |
IS BOUND / IS INSTANCE OF | ні | так |
Динамічна умова ( <string|tab> ) | так | так |
Адаптовано з 31_WHERE_Conditions.md (Apache 2.0). Повний перелік нюансів — в оригіналі.