Начиная с версии 7.52 ABAP позволяет делать внутреннюю таблицу источником данных.
Существует два варианта выполнения подобного запроса:
1. Выполнение операции на стороне сервера приложений. Работает только с операциями которые поддерживают работу с буфером.
2. Выполнение на стороне базы данных.
Для выполнения второго случая, операция должна поддерживаться самой базой данных. Иначе получаете исключение CX_SY_SQL_UNSUPPORTED_FEATURE. (удалось выполнить только в системе с HANA. Сомневаюсь, что другие БД поддерживают данную операцию)
Есть некоторые ограничения при использовании:
- Можно указать только одну внутреннюю таблицу;
- Необходимо указать псевдоним при помощи оператора AS;
- Внутренняя таблица не должна содержать устаревшие типы данных DF16_SCL и DF34_SCL ;
- Если используется дополнение ORDER BY PRIMORY KEY, должен быть указан первичный ключ;
- Внутренняя таблица может иметь строки элементарного типа и или структуру, но не может иметь вложенных подструктур;
- Внутренняя таблица должно иметь явно определенный первичный ключ;
- Нельзя при статическом указании таблицы во FROM использовать обобщённые типы таблиц (вроде INDEX TABLE). Обобщённые типы могут быть использованы при динамическом FROM;
- Строки со ссылкой на SSTRING обрабатываются как строки с фиксированной длинной и игнорированием завершающих пробелов.
Теперь рассмотрим 1 вариант. Выбор у нас не особо большой
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
* TYPES: BEGIN OF lty_s_data, name TYPE text10, value TYPE i, END OF lty_s_data, lty_t_data TYPE TABLE OF lty_s_data WITH KEY name. DATA lt_data TYPE lty_t_data. lt_data = VALUE #( ( name = 'Lada' value = 5 ) ( name = 'BMW' value = 7 ) ( name = 'Volvo' value = 5 ) ( name = 'Fiat' value = 9 ) ). SELECT * FROM @lt_data AS inh_tab WHERE value = 5 INTO TABLE @DATA(lt_result). SELECT count( * ) FROM @lt_data AS inh_tab WHERE value = 5 INTO TABLE @DATA(lv_result). |
По рекомендациям применять Select к внутренней таблице стоит только если у нас данная операция не возможна через классические READ и LOOP AT, т.к. классическое чтение работает побыстрее.
Для следующей операции уже нужна БД
1 2 3 4 |
SELECT SUM( value ) FROM @lt_data AS inh_tab WHERE value = 5 INTO TABLE @DATA(lv_sum). |
Пример с объединением данных из таблицы БД и внутренней уже интереснее.(Пока возьму из документации, т.к. пропал доступ к подходящей системе)
1 2 3 4 5 6 7 8 9 10 11 |
DATA itab TYPE HASHED TABLE OF scarr WITH UNIQUE KEY mandt carrid. itab = VALUE #( ( carrid = 'LH' carrname = 'L.H.' ) ( carrid = 'UA' carrname = 'U.A.' ) ). SELECT scarr~carrid, scarr~carrname, spfli~connid FROM @itab AS scarr INNER JOIN spfli ON scarr~carrid = spfli~carrid INTO TABLE @DATA(result) ##db_feature_mode[itabs_in_from_clause]. |
Наиболее полезно будет для замены FOR ALL ENTRIES, т.к. он, например, не работает с функциями агрегации.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
* select * from sbook into table @lt_bookings where connid = '0017' order by primory key. "Было if lt_bookings is not initial. select * from spfli into table @data(lt_connection) where carrid = @lt_bookings-carrid and connid = @lt_bookings-connid order by primory key. endif. "Стало select * from spfli where exist ( select @abap_true from @lt_bookings as _lt_bookings where carrid = @spfli-carrid and connid = @spfli-connid ) order by primory key into table @data(lt_connection2) |
Если потребуется использовать, например, GROUP BY, способ с внутренней будет очень даже к месту.
Отличная статья!