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

ABAP向SAP自定义表ZDT_COUNTRY插入记录:解决主键重复报错

SAP插入自定义表数据解决主键重复错误

错误原因

DBSQL_DUPLICATE_KEY_ERROR 错误的核心原因是:你要插入的记录中,**MANDT(客户端)+ ID_PAIS(国家ID)**的主键组合已经存在于ZDT_COUNTRY表中,数据库不允许主键重复。

解决方案

方案1:使用MODIFY语句自动处理插入/更新

MODIFY语句会先检查主键是否存在:如果不存在则插入新记录,如果已存在则更新现有记录。补全8条记录并修改后的代码如下:

REPORT Z_INSERT_COUNTRY.

DATA: lt_countries TYPE TABLE OF ZDT_COUNTRY,
      ls_country   TYPE ZDT_COUNTRY.

* 第1条:美国
ls_country-MANDT = sy-mandt. " 使用当前登录客户端,替代硬编码
ls_country-ID_PAIS = '001'.
ls_country-NAME_PAIS = 'United States'.
ls_country-CAPITAL_PAIS = 'Washington D.C.'.
ls_country-POBLACION_PAIS = '339996567'.
ls_country-SURFACE_PAIS = '9629091'.
ls_country-CURRENCY_COUNTRY = 'US Dollar'.
ls_country-LANGUAGE_COUNTRY = 'English'.
APPEND ls_country TO lt_countries.

CLEAR ls_country.
* 第2条:加拿大
ls_country-MANDT = sy-mandt.
ls_country-ID_PAIS = '002'.
ls_country-NAME_PAIS = 'Canada'.
ls_country-CAPITAL_PAIS = 'Ottawa'.
ls_country-POBLACION_PAIS = '39566248'.
ls_country-SURFACE_PAIS = '9976140'.
ls_country-CURRENCY_COUNTRY = 'Canadian Dollar'.
ls_country-LANGUAGE_COUNTRY = 'English, French'.
APPEND ls_country TO lt_countries.

CLEAR ls_country.
* 第3条:澳大利亚
ls_country-MANDT = sy-mandt.
ls_country-ID_PAIS = '003'.
ls_country-NAME_PAIS = 'Australia'.
ls_country-CAPITAL_PAIS = 'Canberra'.
ls_country-POBLACION_PAIS = '25767000'.
ls_country-SURFACE_PAIS = '7692024'.
ls_country-CURRENCY_COUNTRY = 'Australian Dollar'.
ls_country-LANGUAGE_COUNTRY = 'English'.
APPEND ls_country TO lt_countries.

CLEAR ls_country.
* 第4条:巴西
ls_country-MANDT = sy-mandt.
ls_country-ID_PAIS = '004'.
ls_country-NAME_PAIS = 'Brazil'.
ls_country-CAPITAL_PAIS = 'Brasilia'.
ls_country-POBLACION_PAIS = '218596943'.
ls_country-SURFACE_PAIS = '8515767'.
ls_country-CURRENCY_COUNTRY = 'Brazilian Real'.
ls_country-LANGUAGE_COUNTRY = 'Portuguese'.
APPEND ls_country TO lt_countries.

CLEAR ls_country.
* 第5条:印度
ls_country-MANDT = sy-mandt.
ls_country-ID_PAIS = '005'.
ls_country-NAME_PAIS = 'India'.
ls_country-CAPITAL_PAIS = 'New Delhi'.
ls_country-POBLACION_PAIS = '1425775850'.
ls_country-SURFACE_PAIS = '3287263'.
ls_country-CURRENCY_COUNTRY = 'Indian Rupee'.
ls_country-LANGUAGE_COUNTRY = 'Hindi, English'.
APPEND ls_country TO lt_countries.

CLEAR ls_country.
* 第6条:德国
ls_country-MANDT = sy-mandt.
ls_country-ID_PAIS = '006'.
ls_country-NAME_PAIS = 'Germany'.
ls_country-CAPITAL_PAIS = 'Berlin'.
ls_country-POBLACION_PAIS = '83019200'.
ls_country-SURFACE_PAIS = '357022'.
ls_country-CURRENCY_COUNTRY = 'Euro'.
ls_country-LANGUAGE_COUNTRY = 'German'.
APPEND ls_country TO lt_countries.

CLEAR ls_country.
* 第7条:日本
ls_country-MANDT = sy-mandt.
ls_country-ID_PAIS = '007'.
ls_country-NAME_PAIS = 'Japan'.
ls_country-CAPITAL_PAIS = 'Tokyo'.
ls_country-POBLACION_PAIS = '125124971'.
ls_country-SURFACE_PAIS = '377975'.
ls_country-CURRENCY_COUNTRY = 'Japanese Yen'.
ls_country-LANGUAGE_COUNTRY = 'Japanese'.
APPEND ls_country TO lt_countries.

CLEAR ls_country.
* 第8条:南非
ls_country-MANDT = sy-mandt.
ls_country-ID_PAIS = '008'.
ls_country-NAME_PAIS = 'South Africa'.
ls_country-CAPITAL_PAIS = 'Pretoria'.
ls_country-POBLACION_PAIS = '62027503'.
ls_country-SURFACE_PAIS = '1221037'.
ls_country-CURRENCY_COUNTRY = 'South African Rand'.
ls_country-LANGUAGE_COUNTRY = 'Zulu, Xhosa, English'.
APPEND ls_country TO lt_countries.

* 使用MODIFY代替INSERT,自动处理主键重复
MODIFY ZDT_COUNTRY FROM TABLE lt_countries.
IF sy-subrc = 0.
  WRITE: / sy-dbcnt, '条记录已成功处理(插入/更新)'.
ELSE.
  WRITE: / '数据处理失败'.
ENDIF.

方案2:清空表后插入(仅测试环境使用)

如果是测试环境,确定可以清空现有数据,可在插入前添加删除语句:

* 先清空表(注意:生产环境禁止使用!)
DELETE FROM ZDT_COUNTRY.
IF sy-subrc = 0.
  WRITE: / '表数据已清空'.
ENDIF.

* 然后执行INSERT语句
INSERT ZDT_COUNTRY FROM TABLE lt_countries.
IF sy-subrc = 0.
  WRITE: / sy-dbcnt, '条记录已成功插入'.
ELSE.
  WRITE: / '插入失败'.
ENDIF.

方案3:检查主键后再插入

先查询表中已有的主键组合,避免插入重复值:

* 插入前检查每条记录的主键是否存在
LOOP AT lt_countries INTO ls_country.
  SELECT SINGLE * FROM ZDT_COUNTRY WHERE MANDT = ls_country-MANDT AND ID_PAIS = ls_country-ID_PAIS.
  IF sy-subrc <> 0.
    INSERT ZDT_COUNTRY FROM ls_country.
    IF sy-subrc = 0.
      WRITE: / '记录(MANDT:', ls_country-MANDT, ', ID_PAIS:', ls_country-ID_PAIS, ')已插入'.
    ENDIF.
  ELSE.
    WRITE: / '记录(MANDT:', ls_country-MANDT, ', ID_PAIS:', ls_country-ID_PAIS, ')已存在,跳过插入'.
  ENDIF.
ENDLOOP.

注意事项

  1. 客户端字段MANDT:使用sy-mandt代替硬编码的客户端编号,能让代码适配不同客户端环境,增强通用性。
  2. 生产环境限制:直接清空表或强制插入的操作在生产环境严格禁止,建议使用MODIFY或先检查再插入的逻辑,避免数据丢失或冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 02:12:10