You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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.
说明
  1. 使用CL_ABAP_STRUCTDESCR=>CREATE根据主键字段列表生成动态结构,确保CREATE DATA能识别合法类型。
  2. 添加动态内表存储所有重复主键结果,避免仅获取一行数据的局限性。
  3. 保留原有的SQL查询逻辑,仅修正数据对象创建的错误。

内容的提问来源于stack exchange,提问作者sophatron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 07:52:31