我有以下场景:
数据库表,让我们用主键称之为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报告来列出和选择不需要的记录。您可以添加用于标记行的复选框列,并通过主键自动取消标记相同的其他记录。
没有特定的解决方案可以知道哪些行是重复的,您必须从头开始编写算法。
可能的解决方案:
-
最差的一个:一次插入一行并测试
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_duplicates
中;您可以使用mkysoft提案只阅读重要行:FOR ALL ENTRIES
;请注意,重要的是要确保lt_table
不为空,否则将读取表中的所有行 - 检查内部表
lt_table
的哪些行存在于lt_duplicates
中。它们都是重复的 - 对于
lt_duplicates
中不存在的lt_table
的所有行,必须确保lt_table
中没有其他行具有相同的主键。您可以先按主键对内部表进行排序,然后读取具有相同主键字段的下一行,所有这些行都是重复的
- 将数据库表的当前行读取到内部表