Abap 在插入DB表时,找出哪些行是重复的?

Abap 在插入DB表时,找出哪些行是重复的?,abap,Abap,我有以下情况: 数据库表,我们用主键称之为ZDBX: MATNR, LIFNR, ZART 在报告中,我有ZDBX的内部表格lt_表格类型表格 DELETE ADJACENT DUPLICATES FROM lt_table COMPARING matnr lifnr zart fact_code. DELETE FROM ZDBX. INSERT ZDBX FROM TABLE lt_table. INSERT语句将导致短转储,因为内部表中的行具有相同的主键,但不同的fact\u

我有以下情况:

数据库表,我们用主键称之为
ZDBX

MATNR, LIFNR, ZART
在报告中,我有ZDBX的内部表格
lt_表格类型表格

DELETE ADJACENT DUPLICATES FROM lt_table 
   COMPARING matnr lifnr zart fact_code.

DELETE FROM ZDBX.
INSERT ZDBX FROM TABLE lt_table.
INSERT
语句将导致短转储,因为内部表中的行具有相同的主键,但不同的
fact\u code

现在,我知道显而易见的解决方案是只比较
删除相邻重复项
语句中的主键,但这在我的情况下不起作用,因为用户想要决定删除哪个
事实代码

目前,我的解决方案是将本地表(就在
INSERT
之前)导出到excel中,找到重复的表,并询问用户想要哪个
fact\u code

我可以(通过系统变量或在
ST22
中)找出插入崩溃的行吗? (所以我不必做所有的excel工作)

我的理想解决方案是将INSERT放入一个
TRY-CATCH
,找到重复的行,并使用重复的数据将消息写入作业日志

可能吗


(另外,将列
事实\u code
设置为主键不是用户同意的解决方案)

您可以使用FOR ALL ENTRIES指令查找现有项目

  SELECT *
    FROM ZDBX
    INTO TABLE lt_dublicates
    FOR ALL ENTRIES IN lt_table
    WHERE MATNR EQ lt_table-MATNR
      AND LIFNR EQ lt_table-LIFNR 
      AND ZART  EQ lt_table-ZART.

我更喜欢创建ABAP报告来列出和选择不需要的记录。您可以添加复选框列来标记行,并通过主键自动取消标记相同的其他记录。

没有特定的解决方案来知道哪些行是重复的,您必须从头开始编写算法

可能的解决办法:

  • 最差的一个:一次插入一行并测试
    SY-SUBRC
    ,如果插入成功将为0,另一个值通常是重复的行。如果存在任何重复,请回滚插入

    LOOP AT lt_table INTO DATA(ls_table).
      INSERT zdbx FROM ls_table. " one line at a time
      IF sy-subrc <> 0.
        APPEND ls_table TO lt_error.
      ENDIF.
    ENDLOOP.
    IF lt_error IS NOT INITIAL.
      ROLLBACK WORK.
    ELSE.
      COMMIT WORK.
    ENDIF.
    
    在lt\u表中循环到数据(ls\u表)。
    从ls_表中插入zdbx。“一次一行
    如果sy subrc为0。
    将ls\u表附加到lt\u错误。
    恩迪夫。
    结束循环。
    如果lt_错误不是初始错误。
    回滚工作。
    其他的
    投入工作。
    恩迪夫。
    
  • 最佳选择:

    • 将数据库表的当前行读入内部表
      lt_duplicates
      ;您可以使用mkysoft建议仅读取重要行:
      用于所有条目
      ;小心,确保
      lt_table
      不为空非常重要,否则将读取表中的所有行
    • 检查内部表的哪些行
      lt\u table
      存在于
      lt\u duplicates
      中。它们都是重复的
    • 对于
      lt_table
      中不存在的所有
      lt_duplicates
      行,必须确保没有另一行
      lt_table
      具有相同主键。可以通过先按主键对内部表排序,然后读取下一行来完成此操作如果具有相同的主键字段,则所有这些行都是重复的

  • 在选择事实代码之前是否有必要尝试插入?如果没有,您已经有一个已排序的列表。在列表中循环,如果它们的键+事实代码与前一行相同,则提供一个对话框。感谢您的想法,我将实现它。这是最适合我给定场景的。这个想法很好,但在我的情况下不起作用,因为se重复的数据在内部表中。我不插入数据,它已经在DB表中。第二种解决方案在我的情况下不起作用,因为重复的数据在内部表中。(在从内部表插入之前,我删除DB表中的所有数据)。正如我在描述中提到的,我无法从内部表中删除重复的数据,因为用户必须决定要删除哪个事实代码。在一个梦幻世界中,我本来想在DB表中插入15000行,但报告崩溃/捕获异常,我看到第1200行是重复的。对不起,我没有注意到数据库表在插入之前被清空的事实。所以问题是关于在内部表中识别重复项的,这已经得到了回答。一旦您确认这另一个问题/答案是您要查找的,我将删除我的答案。我的逻辑是非常有缺陷的,因为我想在e INSERT语句,正如@Samleijenhorst所指出的,我可以在INSERT之前轻松地在循环中进行检查。因为我无法删除delete INTERNATIONG DUPLICAES语句中的重复项,所以我认为唯一的选择必须是签入INSERT语句。我最初寻找的答案不是您所建议的答案ted,但讨论让我意识到没有理由直接“检查”插页。因此,感谢您提出的建议答案,这就是我现在正在寻找的答案:)