如何在 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.
我想将一个大数据库 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
:
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.