才高八斗的开水瓶 · “圆桌会议”的起源地,曾是英国古都,相当于中 ...· 7 月前 · |
礼貌的佛珠 · 天元公学一行到访钱学森学院-西安交通大学新闻网· 10 月前 · |
痴情的酸菜鱼 · 极氪X低价上市 ...· 1 年前 · |
呐喊的槟榔 · 8月十大城市终端销量榜:比亚迪秦PLUS ...· 1 年前 · |
zhoushqi · 免费分享3个不为人知的神秘网站· 3 年前 · |
内表是每个ABAP开发人员都必须懂的,数据从R3取出来后,就是放在内表里处理的,其实就是Java中的集合框架,只是没有那么多不同数据结构的内表,目前只有标准、排序、Hash三种,这还是新的语法,老的只有个标准的,关于内表这方面的定义、性能,以后我专贴一篇文章吧。这里只是对内表的常用操作,这也是项目中用得最多的点!
3.2. 在 LOOP AT 中修改当前内表行 ... 39
COLLECT [<wa> INTO ] < itab > 将具有相同关键字段值的行中同名的数字字段的值累计到一条记录上 , 只有非表关键字段被累加 ; 当在内表中找不到指定的被累加行时 , COLLECT 语句的功能与 APPEND 语句是一样的 , 即将一个工作区的内容附加到 itab 内表中。使用 COLLECT 操作的内表有一个限制,即该的行结构中, 除了表键字段以外的所有字段都必须是数字型( i 、 p 、 f )
INSERT <wa> INTO TABLE <itab>. " 单条插入
INSERT LINES OF <itab1> [ FROM <n1>] [ TO <n2>] INTO TABLE <itab2> " 批量插入
向 UNIQUE 的排序表或哈希表插入 重复的数据 时 , 不会抛异常 , 但数据 不会被插入进去 , 这与 APPEND 是不一样的
" 只要根据关键字或索引在内表中读取到相应数据,不管该数据行是否与 COMPARING 指定的字段相符,都会存储到工作区
READ TABLE <itab> WITH KEY {<k1> = <f1> ... <kn> = <fn>... [ BINARY SEARCH ] }
INTO <wa> [ COMPARING <f1><f2> ...|ALL FIELDS]
[ TRANSPORTING <f1><f2> ...|ALL FIELDS| NO FIELDS ]
READ TABLE <itab> FROM <wa>… 以表关键字为查找条件 , 条件值来自 <wa>
COMPARING : 系统根据 <k1>...<kn> ( 关键字段 ) 读取指定的单行与工作区 <wa> 中的相应组件进行比较。
如果系统找根据指定 <k1>...<kn> 找到了对应的条目,且进行比较的字段内容相同,则将 SY-SUBRC 设置为 0 ,如果进行比较的字段内容不同,则返回值 2 ;如果系统根据 <k1>...<kn> 找不到条目,则包含 4 。如果系统找到条目,则无论比较结果如何,都将其读入 wa 中
MODIFY TABLE <itab> FROM <wa> [ TRANSPORTING <f1> <f2> ...] " 修改单条 ( MODIFY TABLE < itab > 一般用在循环中 修改哈希表 ,且 itab 内表带表头) 。这里的 <wa> 扮演双重身份,不仅指定了要修改的行(条件),还包括要修改的新的值。系统以整个表的所有关键字段来搜索要修改的行; USING KEY :如果未使用此选项,则会使用默认的主键 primary table key 来修改相应的行;如果找到要修改的行,则将 <wa> 中所有非关键字段的内容拷贝到对应的数据行中对应的字段上;如果有多行满足条件时只修改第一条
MODIFY <itab> FROM <wa> TRANSPORTING<f1><f2>... WHERE <cond> " 修改多条
DELETE TABLE <itab> FROM <wa> " 删除单条 。多条时,只会删除第一条。条件为所有表关键字段,值来自 <wa>
DELETE TABLE <itab> WITH TABLE KEY <k1> = <f1> ... " 删除单条 。多条时只会删除第一条 , 条件为所有表关键字
DELETE itab WHERE ( col2 > 1 ) AND ( col1 < 4 ) " 删除多行
DELETE ADJACENT DUPLICATES FROM <itab> [ COMPARING <f1><f2> ... | ALL FIELDS ]
注,在未使用 COMPARING 选项时,要删除重复数据之前, 一定要按照内表关键字声明的顺序来进行排序,才能删除重复数据 ,否则不会删除掉;如果指定了 COMPARING 选项,则需要根据指定的比较字段顺序进行排序(如 COMPARING <F1><F2> 时,则需要 sort by <F1><F2> ,而不能是 sort by <F2><F1> ),才能删除所有重复数据
APPEND <wa> TO <itab>
APPEND LINES OF <itab1> [ FROM <n1>] [ TO <n2>] TO <itab2>
INSERT <wa> INTO <itab> INDEX <idx> " 如果不使用 INDEX 选项,则将新的行插入到当前行的前面,一般在 Loop 中可省略 INDEX 选项
INSERT LINES OF <itab1> [ FROM <n1>] [ TO <n2>] INTO <itab2> INDEX <idx>
APPEND/INSERT …INDEX 操作不能用于 Hash 表
APPEND/INSERT…INDEX 用于排序表时条件:附加 / 插入时一定要按照 Key 的升序来附加;如果是 Unique 排序表, 则不能附加 / 插入重附的数据 ,这与 INSERT…INTO TABLE 是不一样的
READ TABLE <itab> INDEX <idx>
INTO <wa> [ COMPARING <f1><f2> ...|ALL FIELDS]
[ TRANSPORTING <f1><f2> ...|ALL FIELDS| NO FIELDS ]
| ASSIGNING <fs>
MODIFY <itab> [ INDEX <idx> ] FROM <wa> [ TRANSPORTING <f1> <f2> ... ] " 如果没有 INDEX 选项,只能在 循环中使用该语句
DELETE <itab> [ INDEX <idx>] " 删除单条 。如果省略 <index> 选项,则 DELETE <itab> 语句只能用在循环语句中
DELETE <itab> [ FROM <n1>] [ TO <n2>] WHERE <condition> " 删除多条
LOOP AT
itab {
INTO
wa}
|
{
ASSIGNING
<fs> [
CASTING
]}
|
{
TRANSPORTING NO FILDS
}
[
[
USING
KEY
key_name|
(
name
)
] [
FROM
idx1] [
TO
idx2] [
WHERE
log_exp|
(
cond_syntax
)
]
]
.
ENDLOOP .
FROM … TO: 只适用于标准表与排序表 WHERE … : 适用于所有类型的内表
如果没有通过 USING KEY 选项的 key_name , 则循环读取的顺序与表的类型相关 :
l 标准表与排序表 : 会按照 primary table index 索引的顺序一条条的循环 , 且在循环里 SY-TABIX 为当前正在处理行的索引号
l 哈希表 : 由于表没有排序 , 所以 按照插入的顺序来循环处理 ,注,此时 SY-TABIX 总是 0
可以在循环内表时增加与删除当前行 : If you insert or delete lines in the statement block of a LOOP , this will have the following effects:
如果在 AT - ENDAT 块中使用 SUM , 则系统计算当前行组中 所有 行的数字字段之和并将其写入工作区域中相应的字段中
在使用 AT...... ENDAT 之前, 一这要先按照这些语句中的组件名进行排序,且排序的顺序要与在 AT...... ENDAT 语句中使用顺序一致 ,排序与声明的顺序决定了先按哪个分组,接着再按哪个进行分组,最后再按哪个进行分组,这与 SQL 中的 Group By 相似
用在 AT...... ENDAT 语句中的中的组件名不一定要是结构中的关键字段 ,但这些字段一定要按照出现在 AT 关键字后面的使用顺序在结构最前面进行声明,且 这些组件字段的声明之间不能插入其他组件的声明 。 如现在需要按照 <f1>, <f2>, .... 多个字段的顺序来使用在 AT...... ENDAT 语句中,则首先需要在结构中按照 < f1>, <f2>, ...., 多字段的顺序在结构最前面都声明,然后按照 <f1>, <f2>, ...., 多字段来排序的,最后在循环中按如下的顺序块书写程序(请注意书写 AT END OF 的顺序与 AT NEW 是相反 的,像下面这样):
LOOP AT <itab>.
AT FIRST. ... ENDAT.
AT NEW <f1>. ...... ENDAT.
AT NEW <f 2 >. ...... ENDAT.
.......
<single line processing>
.......
AT END OF <f2>. ... ENDAT.
AT END OF <f1>. ... ENDAT.
AT LAST. .... ENDAT.
ENDLOOP.
一旦进入到 AT...<f1>...ENDAT 块中时,当前工作区(或表头)中的从 <f1> 往后 ,但不包括 <f1> (按照在结构中声明的次序)所有字段的字符类型字段会以星号 (*) 号来填充,而数字字设置为初始值(注:在测试过程中发现 String 类型不会使用 * 来填充,而是设置成 empty String ,所以只有固定长度类型的非数字基本类型才设置为 * )。如果在 AT 块中使用了 SUM ,则会将所有数字类型字段统计出来将存入当前工作区(或表头);但一旦离开 AT....ENDAT 块后,又会将当前遍历的行恢复到工作区(或表头)中
DATA
:
BEGIN
OF
th_mseg
OCCURS
10
,
matnr
TYPE
mard-matnr,
werks
TYPE
mard-werks,
lgort
TYPE
mard-lgort,
shkzg
TYPE
mseg-shkzg,
menge
TYPE
mseg-menge, budat
TYPE
mkpf-budat,
LOOP
AT
th_mseg.
AT
END
OF
shkzg
.
"
会根据
shkzg
及前面所有字段来进行分组
sum
.
WRITE
: / th_mseg-matnr, th_mseg-werks,th_mseg-lgort,
th_mseg-shkzg,th_mseg-menge,th_mseg-budat.
ENDAT
.
ENDLOOP
.
AS-101 2300 0001 S 10.000 ****.**.**
AS-100 2300 0002 S 10.000 ****.**.**
AS-100 2300 0001 S 20.000 ****.**.**
上面由于没有根据 matnr + werks + lgort + shkzg 进行排序,所以结果中的第三行其实应该与第一行合并。 其实这个统计与 SQL 里的分组( Group By )统计原理是一样的, Group By 后面需要明确指定分组的字段,如上面程序使用 SQL 分组写法应该为 Group By matnr werks lgort shkzg ,但在 ABAP 里你只需要按照 matnr werks lgort shkzg 按照先后顺序在结构定义的最前面进行声明就可表达了 Group By 那种意义,而且不一定要将 matnr werks lgort shkzg 这四个字段全部用在 AT 语句块中 AT NEW 、 AT END OF shkzg 才正确,其实像上面程序一样,只写 AT END OF shkzg 这一个语句,前面三个字段 matnr werks lgort 都可以不用在 AT 语句中出现,因为 ABAP 默认会按照结构中声明的顺序将 shkzg 前面的字段也全都用在了分组中了
DATA
:
BEGIN OF line
,
"
C2
、
C3
组件名声明的顺序一定要与在
AT...... ENDAT
块中使用的次序一致,即这里不能将
C3
声明在
C2
之前,且不能在
C2
与
C3
之间插入其他字段的声明
c2
(
5
)
TYPE c
,
c3
(
5
)
TYPE c
,
c4
(
5
)
TYPE c
,
i1
TYPE i
,
i2
TYPE i
,
c1
(
5
)
TYPE c
,
END OF line
.
"
使用在
AT...... E
NDAT
语句中的
字段不一定要是关键字段
DATA
:
itab
LIKE TABLE OF line WITH HEADER LINE WITH NON-UNIQUE KEY
i1
.
PERFORM append USING
2
'b' 'bb' 'bbb' '2222'
22
.
PERFORM append USING
3
'c' 'aa' 'aaa' '3333'
33
.
PERFORM append USING
4
'd' 'aa' 'bbb' '4444'
44
.
PERFORM append USING
5
'e' 'bb' 'aaa' '5555'
55
.
PERFORM append USING
6
'f' 'bb' 'bbb' '6666'
66
.
PERFORM append USING
7
'g' 'aa' 'aaa' '7777'
77
.
PERFORM append USING
8
'h' 'aa' 'bbb' '8888'
88
.
SORT
itab
ASCENDING
BY
c2 c3
.
LOOP AT
itab
.
WRITE
:
/ itab
-
c2
,
itab
-
c3
,
itab
-
c1
,
itab
-
c4
,
itab
-
i1
,
itab
-
i2
.
ENDLOOP
.
SKIP
.
LOOP AT
itab
.
AT FIRST
.
WRITE
:
/
'>>>> AT FIRST'
.
ENDAT
.
AT NEW
c2
.
WRITE
:
/
' >>>> Start of'
,
itab
-
c2
.
ENDAT
.
AT NEW
c3
.
WRITE
:
/
' >>>> Start of'
,
itab
-
c2
,
itab
-
c3
.
ENDAT
.
"
只要一出
AT
块,则表头的数据又会恢复成当前被遍历行的内容
WRITE
:
/ itab
-
c2
,
itab
-
c3
,
itab
-
c1
,
itab
-
c4
,
itab
-
i1
,
itab
-
i2
.
AT END OF
c3
.
SUM
.
WRITE
:
/ itab
-
c2
,
itab
-
c3
,
itab
-
c1
,
itab
-
c4
,
itab
-
i1
,
itab
-
i2
.
WRITE
:
/
' <<<< End of'
,
itab
-
c2
,
itab
-
c3
.
ENDAT
.
AT END OF
c2
.
SUM
.
WRITE
:
/ itab
-
c2
,
itab
-
c3
,
itab
-
c1
,
itab
-
c4
,
itab
-
i1
,
itab
-
i2
.
WRITE
:
/
' <<<< End of'
,
itab
-
c2
.
ENDAT
.
AT LAST
.
SUM
.
WRITE
:
/ itab
-
c2
,
itab
-
c3
,
itab
-
c1
,
itab
-
c4
,
itab
-
i1
,
itab
-
i2
.
WRITE
:
/
'<<<< AT LAST'
.
ENDAT
.
ENDLOOP
.
TYPES
:
c5
(
5
)
TYPE c
.
FORM append USING value
(
p_i1
)
TYPE I
value
(
p_c1
)
TYPE
c5
value
(
p_c2
)
TYPE
c5
value
(
p_c3
)
TYPE
c5
value
(
p_c4
)
TYPE
c5
value
(
p_i2
)
TYPE i
.
itab
-
i1
=
p_i1
.
itab
-
c1
=
p_c1
.
itab
-
c2
=
p_c2
.
itab
-
c3
=
p_c3
.
itab
-
c4
=
p_c4
.
itab
-
i2
=
p_i2
.
APPEND
itab
.
ENDFORM
.
aa aaa c 3333 3 33
aa aaa g 7777 7 77
aa bbb d 4444 4 44
aa bbb h 8888 8 88
bb aaa a 1111 1 11
bb aaa e 5555 5 55
bb bbb b 2222 2 22
bb bbb f 6666 6 66
>>>> AT FIRST
>>>> Start of aa
>>>> Start of aa aaa
aa aaa c 3333 3 33
aa aaa g 7777 7 77
aa aaa ***** ***** 10 110
<<<< End of aa aaa
>>>> Start of aa bbb
aa bbb d 4444 4 44
aa bbb h 8888 8 88
aa bbb ***** ***** 12 132
<<<< End of aa bbb
aa ***** ***** ***** 22 242
<<<< End of aa
>>>> Start of bb
>>>> Start of bb aaa
bb aaa a 1111 1 11
bb aaa e 5555 5 55
bb aaa ***** ***** 6 66
<<<< End of bb aaa
>>>> Start of bb bbb
bb bbb b 2222 2 22
bb bbb f 6666 6 66
bb bbb ***** ***** 8 88
<<<< End of bb bbb
bb ***** ***** ***** 14 154
<<<< End of bb
***** ***** ***** ***** 36 396
<<<< AT LAST
如果循环的内表不是自己定义的 , 有时无法将分组的字段按顺序声明在一起 , 所以需要自己实现这些功能 , 下面是自己实现 AT NEW 与 AT END OF ( 另一好处是在循环内表时 可以使用 Where 条件语句 )( 注 : 使用这种只需要按照分组的顺序排序即可 , 如要分成 bukrs 与 bukrs anlkl 两组时 , 需要按照 BY bukrs anlkl 排序 , 而不能是 BYanlkl bukrs ):
DATA
:
lp_bukrs
TYPE
bukrs
,
"
上一行
bukrs
字段的值
lp_anlkl
TYPE
anlkl
.
"
上一行
anlkl
字段的值
"
下面假设按
bukrs
,
bukrs anlkl
分成两组
SORT
itab_data
BY
bukrs
anlkl.
DATA
:
i_indx
TYPE i
.
DATA
:
lwa_data
Like
itab_data
LOOP AT
itab_data
where
flg =
'X
'
.
i_indx
=
sy
-
tabix.
"
**********AT NEW
对当前分组首行进行处理
IF
itab_data
-
bukrs <> lp_bukrs
.
"Bukrs
组
".........
ENDIF
.
IF
itab_data
-
bukrs <> lp_bukrs
OR
itab_data
-
anlkl <> lp_anlkl
.
"bukrs anlkl
分组
".........
ENDIF
.
IF
itab_data
-
bukrs <> lp_bukrs
OR
itab_data
-
anlkl <> lp_anlkl
OR
itab_data
-
.
.
<> lp_
.
.
.
"bukrs anlkl ..
分组
".........
ENDIF
.
"**********
普通循环处理
".........
"**********AT END OF
对当前分组末行进行处理
DATA : l_nolast1 , l_nolast12 . " 不是分组中最末行
"
这里还是要清一下,以防该代码直接写在报表程序的事件里,而不是
Form
里(直接放在
Report
程序事件里时,
l_nolast1,l_nolast12
将会成为全局变量)
CLEAR: l_nolast1,l_nolast12,l_nolast...
DO
.
i_indx
=
i_indx +
1
.
READ TABLE
itab_data
INTO
lwa_data
INDEX
i_indx
.
"
尝试读取下一行
IF
sy
-
subrc <>
0
.
"
当前行已是内表中最后一行
EXIT
.
"
如果第一分组字段都发生了变化,则意味着当前行为所有分组中的最后行
"
注:即使有
N
个分组,这里也只需要判断第一分组字段是否发生变化,不
"
需要对其他分组进行判断,即这里不需要添加其他
ELSEIF
分支
ELSEIF
lwa_data
-
bukrs <> itab_data
-
bukrs
.
EXIT
.
ENDIF
.
********
断定满足条件的下一行不是分组最的一行
"
如果
Loop
循环中没有
Where
条件,则可以将下面条件
lwa_data-flg = 'X'
删除即可
IF
sy
-
subrc
=
0
AND
lwa_data
-
flg
=
'X'
.
IF
lwa_data
-
bukrs
=
itab_data
-
bukrs
.
"
判断当前行是否是
bukrs
分组最后行
l_nolast1
=
'1'
.
IF
lwa_data
-
nanlkl
=
itab_data
-
nanlkl
.
"
判断当前行是否是
bukrs nanlkl
分组最后行
l_nolast2
=
'1'
.
IF
lwa_data
-
.
. =
itab_data
-
.
.
.
"
判断当前行是否是
bukrs nanlkl ..
分组最后行
l_nolast
.
.
=
'1'
.
ENDIF
.
ENDIF
.
EXIT
.
"
只要进到此句所在外层
If
,表示找到了一条满
Where
条件的下一行数据,因此,只要找到这样的数据就可以判断当前分组是否已完,即一旦找到这样的数据就不用再往后面找了,则退出以防继续往下找
ENDIF
.
ENDIF
.
ENDDO .
IF
l_nolast
.
.
IS INITIAL
"
处理
bukrs nanlkl ..
分组
.
.
.
.
.
.
ENDIF
.
IF
l_nolast2
IS INITIAL
.
"
处理
bukrs nanlkl
分组
.
.
.
.
.
.
ENDIF
.
IF
l_nolast1
IS INITIAL
.
"
处理
bukrs
分组
.
.
.
.
.
.
ENDIF
.
lp_bukrs
=
itab_data
-
bukrs
.
lp_anlkl
=
itab_data
-
anlkl
.
lp_..
=
itab_data
-
..
.
ENDLOOP
.
TYPES
:
BEGIN OF
line
,
key
,
val
TYPE
i
,
END OF
line
.
DATA
:
itab1
TYPE line OCCURS
0
WITH HEADER LINE
.
DATA
:
itab2
TYPE line OCCURS
0
WITH HEADER LINE
.
itab1
-
key
=
1
.
itab1
-
val
=
1
.
APPEND
itab1
.
itab2
=
itab1
.
APPEND
itab2
.
itab1
-
key
=
2
.
itab1
-
val
=
2
.
APPEND
itab1
.
itab2
=
itab1
.
APPEND
itab2
.
LOOP AT
itab1
.
WRITE
:
/
'itab1 index: '
,
sy
-
tabix
.
READ TABLE
itab2
INDEX
1
TRANSPORTING NO FIELDS
.
"
试着读取其他内表
"READ TABLE itab1 INDEX 1 TRANSPORTING NO FIELDS."
读取本身也不会影响后面的
MODIFY
语句
WRITE
:
/
'itab2 index: '
,
sy
-
tabix
.
itab1
-
val
=
itab1
-
val +
1
.
"
在循环中可以使用下面简洁方法来修改内表,修改的内表行为当前正被循环的行,即使循环中使用了
"READ TABLE
语句读取了其他内表
(
读取本身也没有关系
)
而导致了
sy-tabix
发生了改变
,因为以下
"
语句不是根据
sy-tabix
来修改的
(
如果在前面读取内表导致
sy-tabix
发生了改变发生改变后,再使用
"
MODIFY itab1 INDEX sy-tabix
语句进行修改时,反而不正确。
而且该语句还适用于
Hash
内表,
需在
"MODIFY
后面加上
TABLE
关键字后再适用于
Hash
表
——请参见后面章节示例
)
MODIFY
itab1
.
ENDLOOP
.
LOOP AT
itab1
.
WRITE
:
/ itab1
-
key
,
itab1
-
val
.
ENDLOOP
.
TYPES
:
BEGIN OF
line
,
key
,
val
TYPE
i
,
END OF
line
.
DATA
:
itab1
TYPE
HASHED TABLE OF
line WITH HEADER LINE WITH UNIQUE KEY key
.
DATA
:
itab2
TYPE line OCCURS
0
WITH HEADER LINE
.
itab1
-
key
=
1
.
itab1
-
val
=
1
.
INSERT
itab1
INTO TABLE
itab1
.
itab2
=
itab1
.
APPEND
itab2
.
itab1
-
key
=
2
.
itab1
-
val
=
2
.
INSERT
itab1
INTO TABLE
itab1
.
itab2
=
itab1
.
APPEND
itab2
.
LOOP AT
itab1
.
WRITE
:
/
'itab1 index: '
,
sy
-
tabix
.
"
循环哈希表时
,
sy-tabix
永远是
0
READ TABLE
itab2
INDEX
1
TRANSPORTING NO FIELDS
.
WRITE
:
/
'itab2 index: '
,
sy
-
tabix
.
itab1
-
val
=
itab1
-
val +
1
.
MODIFY TABLE
itab1
.
"
注
:
该语句不一定在要放在循环里才能使用
——
循环外修改
Hash
也是一样的
,
这与上面的索引表循环修改是不一样的
,
并且修改的条件就是
itab1
表头工作区,
itab1
即是条件,也是待修改的值,修改时会
根据内表设置的主键来修改,而不是索引号
ENDLOOP
.
LOOP AT
itab1
.
WRITE
:
/ itab1
-
key
,
itab1
-
val
.
ENDLOOP
.
三种类型第二索引:
2 UNIQUE HASHED : 哈希算法第二索引
2 UNIQUE SORTED : 唯一升序第二索引
2 NON-UNIQUE SORTED : 非唯一升序第二索引
TYPES
sbook_tab
TYPE STANDARD TABLE
OF
sbook
"
主索引
:
如果要为主索引指定名称
,
则只能使用预置的
primary_key
,
但可以通过后面的
ALIAS
选项来修改
(
注
:
ALIAS
选项只能用于排序与哈希表
)
WITH NON-UNIQUE KEY
primary_key
"ALIAS my_primary_key
COMPONENTS
carrid connid fldate bookid
"
第一个第二索引
:
唯一哈希算法
WITH
UNIQUE HASHED
KEY
hash_key
COMPONENTS
carrid connid
"
第二第二索引
:
唯一升序排序索引
WITH
UNIQUE SORTED
KEY
sort_key1
COMPONENTS
carrid bookid
"
第三第二索引
:
非唯一升序排序索引
WITH
NON-UNIQUE SORTED
KEY
sort_key2
COMPONENTS
customid
.
1、 可以在 READ TABLE itab 、 MODIFY itab 、 DELETE itab 、 LOOP AT itab 内表操作语句中通过 WITH [TABLE] KEY key_name COMPONENTS K 1 = V 1 ... 或者 USING KEY key_name ,语句中的 key_name 为第二索引名:
READ TABLE itab WITH TABLE KEY [ key_name COMPONENTS ] {K 1 | ( K 1 ) } = V 1 ... INTO wa
READ TABLE itab WITH KEY key_name COMPONENTS {K 1 | ( K 1 ) } = V 1 ... INTO wa
READ TABLE itab FROM wa [ USING KEY key_name] INTO wa
READ TABLE itab INDEX idx [ USING KEY key_name] INTO wa
MODIFY TABLE itab [ USING KEY key_name] FROM wa
MODIFY itab [ USING KEY loop_key] FROM wa 此语句只能用在 LOOP AT 内表循环 语句中,并且此时 USING KEY loop_key 选项也可以省略(其实默认就是省略的),其中 loop_key 是预定义的,不能写成其他名称
MODIFY itab INDEX idx [ USING KEY key_name] FROM wa
MODIFY itab FROM wa [ USING KEY key_name] ... WHERE ...
DELETE TABLE itab FROM wa [ USING KEY key_name]
DELETE TABLE itab WITH TABLE KEY [ key_name COMPONENTS ] {K 1 | ( K 1 ) } = V 1 ...
DELETE itab INDEX idx [ USING KEY key_name| ( name ) ]
DELETE itab [ USING KEY loop_key]
DELETE itab [ USING KEY key_name ] ... WHERE ...
DELETE ADJACENT DUPLICATES FROM itab [ USING KEY key_name] [ COMPARING K1 K2 ...]
LOOP AT
itab
USING KEY
key_name
WHERE
...
.
ENDLOOP
.
2、 可以在 INSERT itab 与 APPEND 语句中通过 USING KEY 选项来使用第二索引
INSERT wa [ USING KEY key_name] INTO TABLE itab
APPEND wa [ USING KEY key_name] TO itab
DATA
itab
TYPE HASHED TABLE OF
dbtab
WITH UNIQUE KEY
col1 col2
...
"
向内表
itab
中添加大量的数据
...
READ TABLE
itab
"
使用
非
主键进行搜索,搜索速度将会很慢
WITH KEY
col3
= ...
col4
= ...
ASSIGNING
...
上面定义了一个哈希内表,在读取时未使用主键,在大数据量的情况下速度会慢,所以在搜索字段上创建第二索引:
DATA
itab
TYPE
HASHED TABLE OF
dbtab
WITH UNIQUE KEY
col1 col2
...
"
为非主键创建第二索引
WITH
NON-UNIQUE SORTED KEY
second_key
COMPONENTS
col3 col4
...
"
向内表
itab
中添加大量的数据
...
READ TABLE
itab
"
根据第二索引进行搜索,会比上面程序快
WITH TABLE KEY
second_key
COMPONENTS
col3
= ...
col4
= ...
ASSIGNING
...
"
在循环内表的
Where
条件中,如果内表不是排序内表,则不会使用二分搜索,如果使用
SORTED KEY
,则循环时,
会用到二分搜索?
LOOP AT
itab
USING KEY
second_key
where
col3 = ... col4 = ...
.
ENDLOOP
.
礼貌的佛珠 · 天元公学一行到访钱学森学院-西安交通大学新闻网 10 月前 |
痴情的酸菜鱼 · 极氪X低价上市 高性价比路线展露极氪的野心_腾讯新闻 1 年前 |
zhoushqi · 免费分享3个不为人知的神秘网站 3 年前 |