ABAP程序处理多主键表时CREATE_DATA报错问题排查
错误原因
CREATE DATA 语句要求传入合法的ABAP数据类型名称,但当前代码将多个主键字段用逗号拼接成字符串(如"BELNR,BUKRS,GJAHR,MANDT")直接作为类型参数传入,这并非有效的ABAP数据类型,因此触发类型未知的运行时错误。
解决方案
需要动态构建包含所有主键字段的结构类型,而非直接传入逗号分隔的字段列表。可以通过CL_ABAP_STRUCTDESCR类的CREATE方法生成动态结构描述符,再基于该描述符创建数据对象。此外,原代码使用EXEC SQL仅能获取一行结果,若存在多组重复主键,需改用动态内表存储所有结果。
修正后的代码
REPORT ZDUPLICATE_TEST. PARAMETERS: p_table TYPE tabname. DATA: lv_tabname TYPE dd02l-tabname, lt_keyfields TYPE TABLE OF dd03l-fieldname, ls_keyfield TYPE dd03l-fieldname, lv_keyfields_string TYPE string, lv_query TYPE string, lt_table TYPE REF TO data, lt_table_line TYPE REF TO data, lo_struct_descr TYPE REF TO cl_abap_structdescr, lo_table_descr TYPE REF TO cl_abap_tabledescr. FIELD-SYMBOLS: <lt_table> TYPE STANDARD TABLE, <lt_table_line> TYPE any. START-OF-SELECTION. SELECT SINGLE tabname INTO lv_tabname FROM dd02l WHERE tabname = p_table. IF sy-subrc = 0. WRITE: / 'Table exists'. SELECT fieldname INTO TABLE lt_keyfields FROM dd03l WHERE tabname = p_table AND keyflag = 'X'. IF sy-subrc = 0 AND lt_keyfields IS NOT INITIAL. " 拼接主键字段字符串用于SQL查询 LOOP AT lt_keyfields INTO ls_keyfield. IF lv_keyfields_string IS NOT INITIAL. CONCATENATE lv_keyfields_string ',' ls_keyfield INTO lv_keyfields_string. ELSE. lv_keyfields_string = ls_keyfield. ENDIF. ENDLOOP. " 构建动态结构描述符 lo_struct_descr = cl_abap_structdescr=>create( p_components = VALUE #( FOR field IN lt_keyfields ( name = field type = cl_abap_typedescr=>describe_by_name( field ) ) ) ). " 基于结构创建动态内表和行对象 lo_table_descr = cl_abap_tabledescr=>create( p_line_type = lo_struct_descr ). CREATE DATA lt_table TYPE HANDLE lo_table_descr. ASSIGN lt_table->* TO <lt_table>. CREATE DATA lt_table_line TYPE HANDLE lo_struct_descr. ASSIGN lt_table_line->* TO <lt_table_line>. " 构建SQL查询语句 lv_query = |SELECT { lv_keyfields_string }, COUNT(*) AS CNT FROM { p_table } GROUP BY { lv_keyfields_string } HAVING COUNT(*) > 1|. " 执行动态SQL并获取所有结果 EXEC SQL PERFORMING fetch_result. EXECUTE STATEMENT :lv_query INTO :<lt_table_line>. ENDEXEC. IF <lt_table> IS NOT INITIAL. WRITE: / 'Duplicates found for the keys:', lv_keyfields_string. LOOP AT <lt_table> ASSIGNING <lt_table_line>. WRITE: / 'Key: ', <lt_table_line>, 'Count: ', sy-dbcnt. ENDLOOP. ELSE. WRITE: / 'No duplicates found'. ENDIF. ELSE. WRITE: / 'No primary keys found'. ENDIF. ELSE. WRITE: / 'Can''t find table'. ENDIF. FORM fetch_result. APPEND <lt_table_line> TO <lt_table>. ENDFORM.
说明
- 使用
CL_ABAP_STRUCTDESCR=>CREATE根据主键字段列表生成动态结构,确保CREATE DATA能识别合法类型。 - 添加动态内表存储所有重复主键结果,避免仅获取一行数据的局限性。
- 保留原有的SQL查询逻辑,仅修正数据对象创建的错误。
内容的提问来源于stack exchange,提问作者sophatron
相关产品推荐
相关产品推荐

