如何在 ABAP 中将一个大数据库 table 复制到另一个?

How do I copy a big database table to another in ABAP?

我想将一个大数据库 table 复制到另一个。这是我目前的做法:

OPEN CURSOR WITH HOLD lv_db_cursor FOR
  SELECT * FROM zcustomers.

DO.
  REFRESH gt_custom.
  FETCH NEXT CURSOR lv_db_cursor
    INTO TABLE  gt_custom
    PACKAGE SIZE lv_package_size.

  IF sy-subrc NE 0.
    CLOSE CURSOR lv_db_cursor.
    EXIT.
  ENDIF.

  INSERT zcustomers1 FROM TABLE gt_custom.

  * Write code to modify u r custom table from gt_custom .
ENDDO.

但问题是我收到错误“Enterprise]ASE 运行 out of LOCKS”。 我尝试在插入一些记录后使用 COMMIT 语句,但它关闭了游标。 我不想通过数据库设置增加最大锁定数或在数据库级别制作副本。 我想了解如何在 ABAP 中以最佳性能和低使用内存进行复制... 谢谢。

您还可以使用 combined INSERT and SELECT:

从 ABAP SQL 中“在数据库级别复制”
INSERT zcustomers1 FROM ( SELECT * FROM zcustomers ).

与其他解决方案不同,此 运行s 在一个事务中(数据库上没有不一致)并避免在数据库和 ABAP 服务器之间移动数据,因此速度应该快得多。但是,就像有问题的代码一样,由于在插入期间打开了许多锁,这可能仍然 运行 进入数据库限制(尽管可能会避免其他问题)。这应该可以解决 on database side 而不是 ABAP 的限制。

通过使用 COMMIT CONNECTION instead of COMMIT WORK 可以只提交写入 zcustomers1 的事务,同时保持从 zcustomers 读取的事务打开。

请注意,如果在此代码运行时写入了 zcustomers 或 zcustomers1,那么拥有多个事务(一次读取,多次写入)可能会在数据库中造成不一致。此外,从 zcustomers1 读取仅显示 zcustomers 的部分条目。

DATA:
  gt_custom       TYPE TABLE OF ZCUSTOMERS,
  lv_package_size TYPE i,
  lv_db_cursor    TYPE cursor.

lv_package_size = 10000.

OPEN CURSOR WITH HOLD lv_db_cursor FOR
  SELECT * FROM zcustomers.

DO.
  REFRESH gt_custom.

  FETCH NEXT CURSOR lv_db_cursor
    INTO TABLE   gt_custom
    PACKAGE SIZE lv_package_size.

  IF sy-subrc NE 0.
    CLOSE CURSOR lv_db_cursor.
    EXIT.
  ENDIF.

  MODIFY zcustomers2 FROM TABLE gt_custom.
  " regularily commiting here releases a partial state to the database
  " through that, locks are released and running into ASE error SQL1204 is avoided
  COMMIT CONNECTION default.
ENDDO.