ABAP中,用Ranges定义的内表,由于数据量大导致运行错误
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ABAP中,用Ranges定义的内表,由于数据量大导致运行错误相关的知识,希望对你有一定的参考价值。
我用Ranges定义了一个内表
RANGES S_MARC FOR MARC-MATNR.
然后向这个内表中插入了一些数据,大概有五万多条,然后根据这个表里的数据去删除自建表中的资料
DELETE ZTEST WHERE MATNR IN S_MARC. (ZTEST是自建表,不是内表)
ZTEST是个自建表,不是内表,测试发现删除内表资料不会出错. 删除自建表资料时,好像S_MARC这个内表中的资料条目数有限制,测试9000多条的时候可以正常运行,超过1万就会运行错误,请问这种情况该如何解决?用ranges定义的内表是否有条目数限制?谢谢
以下是参考:
要通过 DELETE 语句用内表 从数据库表 中删除多行 ,请使用下 列语法:
语法
DELETE <dbtab> [CLIENT SPECIFIED] FROM TABLE <itab>.
如果需要在 运行时间指 定数据库表 的名称,请 使用下列语 法:
DELETE (<dbtabname>) [CLIENT SPECIFIED] FROM TABLE <itab>.
这些语句从 数据库表中 删除主码与 内表 <itab> 中的某行相 同的行。
内表的长度 至少与数据 库表的主码 的长度相同 。
如果因为数 据库表中没 有哪一行的 主码与指定 的相同,从 而系统没有 删除任何行 ,那么,系 统不会终止 整个操作, 而是继续处 理内表的下 一行。
如果已经处 理了内表中 所有的行, SY-SUBRC 将设置为 0。否则, 设置为 4。在稍后 的时候,从 内表的总行 数中减去 SY-DBCNT 中给出的实 际已删除的 行数,就可 计算系统尚 未删除的行 数。如果内 表是空的, 那么 SY-SUBRC 和 SY-DBCNT 都将设置为 0。
相对而言, 操作多行的 集合比操作 单行更有效 。
TABLES SPFLI.
DATA ITAB LIKE SPFLI OCCURS 10 WITH HEADER LINE.
ITAB-CARRID = 'UA'. ITAB-CONNID = '0011'.
APPEND ITAB.
ITAB-CARRID = 'LH'. ITAB-CONNID = '1245'.
APPEND ITAB.
ITAB-CARRID = 'AA'. ITAB-CONNID = '4574'.
APPEND ITAB.
................
DELETE SPFLI FROM TABLE ITAB.
在该示例中 ,用与数据 库表 SPFLI 相同的结构 定义了内表 ITAB。 填写 ITAB之 后,SPFLI 中主码(CARRID 和 CONNID) 与内表的某 行相同的行 都将被删除 。 参考技术A ranges 是有数量限制的,但是现在我也不确定是多少条,可能跟内存也有关系追问
我也尝试定义一个和range一样的内表,如
DATA: BEGIN OF S_MARC OCCURS 0,
SIGN TYPE C,
OPTION TYPE C LENGTH 2,
LOW LIKE MARA-MATNR,
HIGH LIKE MARA-MATNR,
END OF S_MARC.
然后再向这个内表中插入数据,这样也不行,也是有条数限制
方法1
定义多个ranges table, 把五万多条分开了装
方法2
data: lt_ztest type standard table of ztest.
然后向这个内表中插入了一些数据,大概有五万多条,然后根据这个表里的数据去删除自建表中的资料
select *
from ztest
into corresponding fields of table lt_ztest
for all entries in lt_ztest
where matnr = lt_ztest-matnr.
delete ztest from table lt_ztest.追问
非常感谢,目前我用的是第二种方法,但感觉速度上有点慢,效率比较差,不知道还有没有其他更好的方法呢
追答delete后面可以接的条件好像不多, 所以我还没想到什么好方法
参考技术C 我3千条就错误 参考技术D综合原因影响,事实上就是sql长度影响:
首先衡量select后面字段数,会不会超出
然后计算 range,预估长度有多少,实际是in(range[1],range[2]....)
考虑是否还有for all这类调用内表的衍生的长度,实际也是in('','',......)
where条件还有哪些长度,最后累加1/2/3,不超过sql最长长度即可
ABAP 中内表的复制
内表1和内表2中字段条目不同,不用LOOP如何实现内表数据从1复制到2?
ABAP中的内表相当于其他程序设计语言中的二维数组,存储多行结构相同的数据? 不同于二维数组,内表在创建后,列结构与列数是固定不变的,而行数是动态增长的
? 内表支持循环对每行数据进行操作,也支持整体操作
? 内表是具有行和列的表结构,然而,不同于数据库表,内表仅在程序运行期间在内存中存储数据
?ABAP中有三种内表类型:标准表,哈希表,排序表
-- ABAP内表数据类型
? 内表数据对象是实际的内表,可以用数据进行填充
? 内表数据类型是用于定义内表数据对象的抽象数据类型(ADT)
? 可以使用的内表数据类型有:
?Structure
? 数据库表
? 用户自定义数据类型
--ABAP内表声明
1>
TYPES: BEGIN OF line,
field1 TYPE i,
field2 TYPE i,
END OF line.
* 声明一个数据类型
DATA: ITAB_WA TYPE(LIKE) line. “ 声明一个内表工作区
DATA: ITAB TYPE(LIKE) line OCCURS 0. “ 声明一个无工作区的内表
DATA: ITAB TYPE(LIKE) STANDARD TABLE OF line INITIAL SIZE 0. “ 声明一个有工作区的内表
DATA: ITAB TYPE(LIKE) line OCCURS 0 WITH HEADER LINE.
DATA: ITAB TYPE(LIKE) STANDARD TABLE OF line INITIAL SIZE 0 WITH HEADER LINE.
2>
DATA: BEGIN OF line,
field1 TYPE i,
field2 TYPE i,
END OF line.
* 声明一个line对象,该对象可以作为工作区使用
* 用DATA定义的line本身也是一个结构类型,也可再声明一个工作区
DATA: ITAB_WA TYPE(LIKE) line. “ 声明一个工作区
DATA: ITAB TYPE(LIKE) line OCCURS 0 WITH HEADER LINE. “ 声明一个带工作区的内表
DATA: ITAB TYPE(LIKE) STANDARD TABLE OF line INITIAL SIZE 0 WITH HEADER LINE . “ 声明一个带工作区的内表
3> 直接定义内表,这个内表是有工作区的
DATA: BEGIN OF ITAB OCCURS 0 ,
CARR1 LIKE SPFLI-CARRID,
CONN1 LIKE SPFLI-CONNID,
END OF ITAB.
* DATA: ITAB1 TYPE ITAB.(错误的,实践证明,定义出来的什么都不是)。
正确方法:ITAB1 TYPE ITAB OCCURS 0.(这样定义后的是一个无工作区的内表)。
DATA: ITAB1 LIKE ITAB OCCURS 0 WITH HEADER LINE. “定义一个带工作区内表
4> type ref to 定义内表
type ref to 属于ABAP中面向对象的编程。它是定义一个类的对象。
5>通过数据库表定义
data itab1 type table of sflight . “ 定义一个不带内表的工作区
data wa1 like line of sflgit . “ 定义一个内表工作区
data itab1 type table of sflight with header line . “定义一个带内表的工作区
-- 两种内表定义方式的主要区别在于是否有隐式表头行
内表是按行进行访问的,然而,程序对内表的行操作不能直接进行,必须使用一种接口来传输,这个接口就是工作区(Work Area)
--内表操作
填充内表行
append <wa> to <itab> “ 不带表头行的填充
append <itab> “ 带隐式表头行的填充
插入内表行
insert <wa> into <itab> [INDEX idx] “
insert <itab> [INDEX idx ] “ 隐式表头行插入内表
-- 如果没有指定INDEX ,则默认插入到内表最后一行
读取内表行
read <itab> into <wa> [INDEX idx]
read <itab> [INDEX IDX]
修改内表行
modify <itab> from <wa> [INDEX idx]
modify <itab> [INDEX idx]
-- read itab index 3 .
-- itab-XX = ‘xxx’ .
-- modify itab index 4 .
删除内表行
delete <itab> [INDEX idx] .
-- 带表头行和不带表头行语法一致 。
内表循环
Loop at <itab> into <wa> .
<statement block>
endloop. “ 带表头行的内表循环操作
Loop at <itab> .
<statement block>
endloop. “ 不带表头行内表操作
-- 循环体的MODIFY,DELETE等语句不必指定INDEX项,系统默认处理当前行 .
-- 如果不需要读取所有的内表行,可以使用WHERE选项进行限制
-- LOOP AT <itab> [WHERE <conditions>]
清空内表
clear <itab> . “清空不带表头行内表
clear<itab>[] . “清空带表头行内表
内表排序
SORT <itab> [ASCENDING | DESCENDING] [AS TEXT]
--ASCENDING和DESCENDING指定升序还是降序排列,如果不指定,缺省排序方式是升序
--AS TEXT影响字符字段的排序方式,如果不使用该选项,系统将按字符平台相应内部编码进行排序,否则,系统根据当前语言按字母顺序排序字符字段
删除重复行
DELETE ADJACENT DUPLICATES FROM <itab> [COMPARING <comp>].
-- 删除重复行之前须对内表进行排序
判断内表行数
DESCRIBE TALBE <itab> LINES <count>.
将内表中部分或全部的数据行整体插入另一内表
INSERT LINES OF <itab1> [FROM n1] [TO n2] INTO [TABLE] <itab2> [INDEX <idx>].
-- insert lines of itab1 from 1 to 100 into itab2 . “ 将内表1前100行数据附加到内表2 .
-- 两个内表必须具有相同的或可转换的行结构
将内表中部分或全部的数据行整体填充到另一内表
APPEND LINES OF <itab1> [FROM n1] [TO n2] TO <itab2>.
按照条件或者索引删除一组选定行
DELETE <itab> [FROM n1] [TO n2] [WHERE <condition>].
-- delete itab1 from 1 to 100 where age >30 . "删除内表前100行中年龄大于30 的记录 。
整体复制内表,目标内表原有内容被覆盖
MOVE <itab1> TO <itab2> 不带表头行的内表之间进行复制
MOVE <itab1>[] TO <itab2>[]. 带表头行的内表之间进行复制
MOVE <itab1> TO <itab2>[]. 不带表头行的内表复制到带表头行的内表
MOVE-CORRESPONDING <itab1> TO <itab2> 复制内表1中与内表2具有相同结构的字段进行复制,同样适用于工作区
参考技术A MOVE-CORRESPONDING itab1 to itab2.
以上是关于ABAP中,用Ranges定义的内表,由于数据量大导致运行错误的主要内容,如果未能解决你的问题,请参考以下文章