在插入数据库表时,找出哪些行是重复的

  • 本文关键字:数据库 插入 abap
  • 更新时间 :
  • 英文 :


我有以下场景:

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

MATNR, LIFNR, ZART

在报告中,我有内部表lt_table TYPE TABLE OF ZDBX

DELETE ADJACENT DUPLICATES FROM lt_table 
COMPARING matnr lifnr zart fact_code.
DELETE FROM ZDBX.
INSERT ZDBX FROM TABLE lt_table.

INSERT语句将导致短转储,因为内部表中存在主键相同但fact_code不同的行。

现在,我知道显而易见的解决方案是只比较DELETE ADJACENT DUPLICATES语句中的主键,但这在我的情况下不起作用,因为用户想决定删除哪个fact_code

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

我能找出(通过系统变量或在ST22中(INSERT在哪一行崩溃吗?(所以我不必做所有出色的工作(

我的理想解决方案是将INSERT放入TRY-CATCH中,找到重复的行,并在Job Log中写入一条包含重复数据的消息。

有可能吗?

(此外,将列fact_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报告来列出和选择不需要的记录。您可以添加用于标记行的复选框列,并通过主键自动取消标记相同的其他记录。

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

可能的解决方案:

  1. 最差的一个:一次插入一行并测试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.
    
  2. 最佳:

    • 将数据库表的当前行读取到内部表lt_duplicates中;您可以使用mkysoft提案只阅读重要行:FOR ALL ENTRIES;请注意,重要的是要确保lt_table不为空,否则将读取表中的所有行
    • 检查内部表lt_table的哪些行存在于lt_duplicates中。它们都是重复的
    • 对于lt_duplicates中不存在的lt_table的所有行,必须确保lt_table中没有其他行具有相同的主键。您可以先按主键对内部表进行排序,然后读取具有相同主键字段的下一行,所有这些行都是重复的

最新更新