OpenSQL 中的动态 INTO 子句?
Dynamic INTO clause in OpenSQL?
我正在尝试编写一个程序,该程序将从 table 的字段中获取内容,这两个字段均由用户在选择屏幕上指定。
例如,用户可以从 table eqbs
中指定字段 equnr
、b_werk
、b_lager
。
我已经能够像这样完成这个:
" 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.
这将使用用户指定的 table 中的数据正确填充 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 table,仅填写三个可能的关键字段中的前两个),值如下:
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)
视为一个单独的变量,程序转储时出现以下错误:
The current ABAP program attempted to execute an Open SQL statement
containing a dynamic entry. The parser returned the following error:
"The field list and the INTO list must have the same number of
elements."
我是否可以使用新的 Open SQL 语法来完成与我的动态字段列表相协调的动态 INTO 子句?
不要在 INTO 子句中使用字段列表。
试试看
进入 TABLE
的相应领域
必须是 FIELD-SYMBOL 类型 table,其余逻辑由您决定(将通用信息和 almost-empty 中的正确信息放入您的特定目的地一个)。
INTO
上的括号没有达到您的预期,来自 ABAP 帮助:
... 进入(@dobj1,@dobj2,...)
效果
如果结果集由SELECT列表中明确指定的多个列或聚合表达式组成,则可以是基本数据对象列表dobj1、dobj2、...(在括号中并以逗号分隔)在 INTO 之后指定。
在您的情况下,您只有一个值,因此您只能 select 一列,数据将在变量 LV_RESULT
中传递。不是你想要的。由于您要填充现有结构的字段,因此 INTO CORRESPONDING FIELDS OF
构造将在此处起作用。您还可以使用 TABLE
来提高命令的效率。这导致:
SELECT (lv_field_tab) FROM (p_table)
INTO CORRESPONDING FIELDS OF TABLE @lt_zca_str_to_char.
如前所述,您可以使用 INTO CORRESPONDING FIELDS OF ...,但这不是强制性的,它只是为了简化代码。
因此,而不是 使用相应的字段,您可以动态创建一个结构 (RTTC),其组件对应于 LV_FIELD_TAB 中的列,然后您可以使用:
SELECT (lv_field_tab) FROM (p_table) INTO @<structure> ... ENDSELECT.
当然,正如 Gert Beukema 所解释的那样,您最好只做一个 SELECT,通过使用与上述结构相同的逻辑动态创建一个内部 table,您可以然后使用:
SELECT (lv_field_tab) FROM (p_table) INTO TABLE @<internal table> ...
参考网上很多例子如何用RTTC动态创建数据对象。
我正在尝试编写一个程序,该程序将从 table 的字段中获取内容,这两个字段均由用户在选择屏幕上指定。
例如,用户可以从 table eqbs
中指定字段 equnr
、b_werk
、b_lager
。
我已经能够像这样完成这个:
" 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.
这将使用用户指定的 table 中的数据正确填充 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 table,仅填写三个可能的关键字段中的前两个),值如下:
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)
视为一个单独的变量,程序转储时出现以下错误:
The current ABAP program attempted to execute an Open SQL statement containing a dynamic entry. The parser returned the following error: "The field list and the INTO list must have the same number of elements."
我是否可以使用新的 Open SQL 语法来完成与我的动态字段列表相协调的动态 INTO 子句?
不要在 INTO 子句中使用字段列表。
试试看 进入 TABLE
的相应领域必须是 FIELD-SYMBOL 类型 table,其余逻辑由您决定(将通用信息和 almost-empty 中的正确信息放入您的特定目的地一个)。
INTO
上的括号没有达到您的预期,来自 ABAP 帮助:
... 进入(@dobj1,@dobj2,...)
效果
如果结果集由SELECT列表中明确指定的多个列或聚合表达式组成,则可以是基本数据对象列表dobj1、dobj2、...(在括号中并以逗号分隔)在 INTO 之后指定。
在您的情况下,您只有一个值,因此您只能 select 一列,数据将在变量 LV_RESULT
中传递。不是你想要的。由于您要填充现有结构的字段,因此 INTO CORRESPONDING FIELDS OF
构造将在此处起作用。您还可以使用 TABLE
来提高命令的效率。这导致:
SELECT (lv_field_tab) FROM (p_table)
INTO CORRESPONDING FIELDS OF TABLE @lt_zca_str_to_char.
如前所述,您可以使用 INTO CORRESPONDING FIELDS OF ...,但这不是强制性的,它只是为了简化代码。
因此,而不是 使用相应的字段,您可以动态创建一个结构 (RTTC),其组件对应于 LV_FIELD_TAB 中的列,然后您可以使用:
SELECT (lv_field_tab) FROM (p_table) INTO @<structure> ... ENDSELECT.
当然,正如 Gert Beukema 所解释的那样,您最好只做一个 SELECT,通过使用与上述结构相同的逻辑动态创建一个内部 table,您可以然后使用:
SELECT (lv_field_tab) FROM (p_table) INTO TABLE @<internal table> ...
参考网上很多例子如何用RTTC动态创建数据对象。