Предложение динамического INTO в OpenSQL?

Я пытаюсь написать программу, которая будет извлекать содержимое из полей таблицы, указанных пользователем на экране выбора.

Например, пользователь может указать поля equnr, b_werk, b_lager из таблицы eqbs.

Я смог сделать это так:

" Determine list of fields provided by user
DATA(lv_fields) = COND string(
  WHEN p_key3 IS NOT INITIAL AND p_string IS NOT INITIAL THEN
    |{ p_key1 }, { p_key2 }, { p_key3 }, { p_string }|
  WHEN p_key2 IS NOT INITIAL AND p_string IS NOT INITIAL THEN
    |{ p_key1 }, { p_key2 }, { p_string }|
  WHEN p_key2 IS NOT INITIAL AND p_string IS NOT INITIAL THEN
    |{ p_key1 }, { p_string }| ).

DATA: lv_field_tab TYPE TABLE OF line.
APPEND lv_fields TO lv_field_tab.

" Determine table specified by user and prepare for Open SQL query
DATA t_ref TYPE REF TO data.

FIELD-SYMBOLS: <t>    TYPE any,
               <comp> TYPE any.

CREATE DATA t_ref TYPE (p_table).
ASSIGN t_ref->* TO <t>.
ASSIGN COMPONENT lv_fields OF STRUCTURE <t> TO <comp>.

" Prepare result container
DATA: lt_zca_str_to_char TYPE TABLE OF zca_str_to_char,
      ls_zca_str_to_char TYPE zca_str_to_char.

SELECT (lv_field_tab) FROM (p_table) INTO (@ls_zca_str_to_char-key1, @ls_zca_str_to_char-key2, @ls_zca_str_to_char-key3, @ls_zca_str_to_char-string).
  APPEND ls_zca_str_to_char TO lt_zca_str_to_char.
ENDSELECT.

Это правильно заполнит lt_zca_str_to_char данными из таблицы, указанной пользователем.

Однако это означает, что пользователь всегда предоставляет p_key1, p_key2, и p_key3. Я мог бы выполнить другой оператор выбора в зависимости от того, сколько ключевых полей предоставляет пользователь, но что в этом интересного?

Я решил решить эту проблему так:

DATA(lv_results) = COND string(
  WHEN p_key3 IS NOT INITIAL AND p_string IS NOT INITIAL THEN
    |(@ls_zca_str_to_char-key1, @ls_zca_str_to_char-key2, @ls_zca_str_to_char-key3, @ls_zca_str_to_char-string)|
  WHEN p_key2 IS NOT INITIAL AND p_string IS NOT INITIAL THEN
    |(@ls_zca_str_to_char-key1, @ls_zca_str_to_char-key2, @ls_zca_str_to_char-string)|
  WHEN p_key2 IS NOT INITIAL AND p_string IS NOT INITIAL THEN
    |(@ls_zca_str_to_char-key1, @ls_zca_str_to_char-string)| ).

SELECT (lv_field_tab) FROM (p_table) INTO (@lv_results).
  APPEND ls_zca_str_to_char TO lt_zca_str_to_char.
ENDSELECT.

Это активируется, и когда я перейду к своему запросу Open SQL (из таблицы Z, заполнив только первые два из трех возможных ключевых полей), значения будут следующими:

lv_field_tab = GUID, TEXT_ID, TEXT_DATA (Хорошо)

p_table = ZCR_TRANS_TEXT (Хорошо)

lv_results = (@ls_zca_str_to_char-key1, @ls_zca_str_to_char-key2, @ls_zca_str_to_char-string) (Хорошо, 3 = 3!)

Но, поскольку я предполагаю, что компилятор видит (@lv_results) как одну единственную переменную, программа выгружается со следующей ошибкой:

Текущая программа ABAP попыталась выполнить оператор Open SQL, содержащий динамическую запись. Синтаксический анализатор вернул следующую ошибку: «Список полей и список INTO должны иметь одинаковое количество элементов».

Могу ли я использовать новый синтаксис Open SQL для выполнения моего динамического предложения INTO в гармонии с моим динамическим списком полей?


person gkubed    schedule 13.03.2018    source источник


Ответы (3)


Скобки на INTO не соответствуют вашим ожиданиям из справки ABAP:

... INTO (@ dobj1, @ dobj2, ...)

Эффект

Если набор результатов состоит из нескольких столбцов или агрегатных выражений, явно указанных в списке SELECT, список элементарных объектов данных dobj1, dobj2, ... (в круглых скобках и разделенных запятыми) может быть указан после INTO.

В вашем случае у вас есть только одно значение, поэтому вы можете выбрать только один столбец, и данные будут переданы в переменной LV_RESULT. Это не то что вы ищете. Поскольку вы хотите заполнить поля существующей структуры, конструкция INTO CORRESPONDING FIELDS OF будет работать здесь. И вы также можете использовать TABLE, чтобы сделать вашу команду более эффективной. Это ведет к:

SELECT (lv_field_tab) FROM (p_table) 
       INTO CORRESPONDING FIELDS OF TABLE @lt_zca_str_to_char.
person Gert Beukema    schedule 13.03.2018
comment
Спасибо, Герт. Просто примечание для всех, кто будет читать это в будущем, чтобы я смог выполнить эту работу, мне пришлось изменить свое lv_fields назначение, включив в него AS key1, AS key2 и т. Д. Мне очень нравится этот ответ, потому что он позволил мне записать результаты прямо в таблица вместо структуры. - person gkubed; 14.03.2018

Как было сказано ранее, вы можете использовать INTO CORRESPONDING FIELDS OF ..., но это не обязательно, это только для упрощения кода.

Итак, вместо использования СООТВЕТСТВУЮЩИХ ПОЛЕЙ вы можете создать структуру динамически (RTTC) с ее компонентами, соответствующими столбцам в LV_FIELD_TAB, и затем вы можете использовать:

SELECT (lv_field_tab) FROM (p_table) INTO @<structure> ... ENDSELECT.

Но, конечно, как объяснил Герт Бёкема, вам лучше сделать только один SELECT, динамически создав внутреннюю таблицу с той же логикой, что и для структуры выше, и затем вы можете использовать:

SELECT (lv_field_tab) FROM (p_table) INTO TABLE @<internal table> ...

Просмотрите множество примеров в Интернете, как динамически создавать объекты данных с помощью RTTC.

person Sandra Rossi    schedule 13.03.2018

Не используйте список полей для вашего предложения INTO.

Попробуйте с В СООТВЕТСТВУЮЩИЕ ПОЛЯ ТАБЛИЦЫ

Любая таблица должна быть типом FIELD-SYMBOL, а остальная логика зависит от вас (чтобы поместить правильную информацию из вашего общего и почти пустого в конкретную целевую).

person VXLozano    schedule 13.03.2018