动态编程练习

动态编程练习 (10题)

#practice #dynamic-prog #rtti #rttc #data-reference

相关概念

📌核心模式(点击查看)
关键词 答案
动态字面量令牌 数据对象直接在语句中
动态标识符令牌 数据对象在括号中,不能有空格
泛型 REF TO DATA 必须使用 ASSIGN 解引用
RTTI 根类 CL_ABAP_TYPEDESCR
RTTC 限制 不能动态创建类/接口

第1题 - 动态令牌 [记忆]

用动态令牌替换字面量和替换标识符的语法区别是什么?

📌点击查看答案
  • 替换字面量:数据对象直接出现在语句中。示例:WRITE lv_text.,其中 lv_text 包含文本。
  • 替换标识符:数据对象必须在不带空格的括号中。示例:CALL FUNCTION (lv_fm_name).,其中 lv_fm_name 包含函数模块名称。

第2题 - 动态 SQL [应用]

编写一个动态 SELECT 语句,表名和 WHERE 条件都在运行时确定。

📌点击查看答案
1
2
3
4
DATA: lv_table TYPE string VALUE 'SFLIGHT',
lv_where TYPE string VALUE `carrid = 'LH'`.

SELECT * FROM (lv_table) INTO TABLE lt_data WHERE (lv_where).

FROM 子句和 WHERE 子句都使用括号中的动态令牌。


第3题 - 动态方法调用 [记忆]

如何动态地向方法调用传递参数?

📌点击查看答案
使用 PARAMETER-TABLEEXCEPTION-TABLE 附加项:
1
2
3
CALL METHOD (lv_method) OF lo_obj
PARAMETER-TABLE lt_params
EXCEPTION-TABLE lt_exceptions.

lt_params 类型为 ABAP_PARMBIND_TAB,包含名称-值对。lt_exceptions 类型为 ABAP_EXCPBIND_TAB。


第4题 - 泛型数据引用 [应用]

使用 TYPE REF TO DATA 创建数据引用。为什么不能直接用 ->* 访问数据?

📌点击查看答案
因为 TYPE REF TO DATA泛型类型 – 编译器在编译时不知道被引用数据对象的结构。必须使用 ASSIGN 解引用:
1
2
3
4
5
DATA: dref TYPE REF TO data.
FIELD-SYMBOLS: <fs> TYPE any.
CREATE DATA dref TYPE i.
ASSIGN dref->* TO <fs>.
<fs> = 42.

第5题 - ASSIGN CASTING [记忆]

ASSIGN ... CASTING 的作用是什么?何时使用?

📌点击查看答案
ASSIGN ... CASTING 让你将数据对象的内存区域视为具有不同类型。字段符号的类型被强加到赋值的数据上而不进行转换。

变体:

  • ASSIGN dref->* TO <fs> CASTING. – 使用字段符号的类型
  • ASSIGN dref->* TO <fs> CASTING TYPE ty_my_type. – 使用显式类型

使用场景:处理需要强加特定结构类型的泛型数据引用时。


第6题 - RTTI 类层次结构 [记忆]

说出用于数据类型描述的主要 RTTI 类及其各自描述的内容。

📌点击查看答案
描述
CL_ABAP_TYPEDESCR 根类(所有类的基类)
CL_ABAP_DATADESCR 所有数据类型
CL_ABAP_ELEMDESCR 基本类型(i, f, c, string 等)
CL_ABAP_STRUCTDESCR 结构类型
CL_ABAP_TABLEDESCR 内表类型
CL_ABAP_REFDESCR 引用类型
CL_ABAP_CLASSDESCR 类类型
CL_ABAP_INTFDESCR 接口类型

第7题 - RTTI describe_by 方法 [应用]

编写代码获取名为 ‘SPFLI’ 的结构的类型描述并确定其 KIND。

📌点击查看答案
1
2
3
4
5
6
7
8
9
10
DATA: lo_type TYPE REF TO cl_abap_typedescr.

cl_abap_typedescr=>describe_by_name(
EXPORTING p_name = 'SPFLI'
RECEIVING p_descr_ref = lo_type
EXCEPTIONS type_not_found = 1 ).

IF lo_type->kind = cl_abap_typedescr=>kind_struct.
" 是结构
ENDIF.

KIND 值:kind_elemkind_structkind_tablekind_refkind_classkind_intf


第8题 - 运行时 CREATE DATA [应用]

编写代码动态创建行类型与数据库表 SPFLI 匹配的内表。

📌点击查看答案
1
2
3
4
5
DATA: gr_data TYPE REF TO data.
FIELD-SYMBOLS: <fs_table> TYPE ANY TABLE.

CREATE DATA gr_data TYPE TABLE OF spfli.
ASSIGN gr_data->* TO <fs_table>.

或完全动态:

1
2
3
DATA: lv_tabname TYPE string VALUE 'SPFLI'.
CREATE DATA gr_data TYPE TABLE OF (lv_tabname).
ASSIGN gr_data->* TO <fs_table>.

第9题 - RTTC 表类型创建 [分析]

解释使用 RTTC 动态创建表类型然后用于创建数据对象的步骤。

📌点击查看答案
步骤:
  1. 获取行类型描述符:lo_line = cl_abap_typedescr=>describe_by_name('SPFLI').
  2. 向下转型为数据描述符:lo_data ?= lo_line.
  3. 创建表类型:lo_table = cl_abap_tabledescr=>create( p_line_type = lo_data ).
  4. 使用动态类型创建数据对象:CREATE DATA dref TYPE HANDLE lo_table.
  5. 解引用:ASSIGN dref->* TO <fs_table>.

create() 的可选参数:p_table_kind(standard/sorted/hashed)、p_uniquep_keyp_key_kind


第10题 - RTTC 限制 [分析]

RTTC 有哪些限制?至少说出两件不能做的事情。

📌点击查看答案
  1. 不能生成类或接口 – RTTC 仅限于数据类型
  2. 不能创建不作为构建块已存在的类型(例如,组件需要已有的 RTTI 描述符)
  3. 动态创建的类型是匿名的 – 它们在类型系统中没有名称,只能通过 HANDLE 引用
  4. 使用 HANDLE 的 CREATE DATA 创建的是匿名数据对象,没有名称 – 只能通过引用访问

📌模式总结(点击查看)
关键词 答案
字面量令牌 数据对象直接使用
标识符令牌 括号,不能有空格
泛型 REF TO DATA 必须 ASSIGN 解引用
CASTING 强加类型但不转换
RTTI 根类 CL_ABAP_TYPEDESCR
describe_by_name 通过名称字符串获取类型
KIND 值 elem, struct, table, ref, class, intf
RTTC 创建表 describe_by_name → create → CREATE DATA HANDLE