1、讀取內錶行新語法
740新語法中,對標READ,提出了新的語法,如下:
1.1、根據欄位值查詢
"-----------------------------@斌將軍----------------------------- "老語法 READ TABLE lt_acd INTO ls_acd WITH KEY rbukrs = gs_acd-rbukrs. IF sy-subrc EQ 0. ENDIF. "新語法 ls_acd = lt_acd[ rbukrs = gs_acd-rbukrs ]. "-----------------------------@斌將軍-----------------------------
1.2、按索引查詢
"-----------------------------@斌將軍----------------------------- "老語法 READ TABLE lt_acd INTO ls_acd INDEX 1. IF sy-subrc EQ 0. ENDIF. "新語法 ls_acd = lt_acd[ 1 ]. "-----------------------------@斌將軍-----------------------------
1.3、判斷記錄是否存在
"-----------------------------@斌將軍----------------------------- "老語法 READ TABLE lt_acd WITH KEY rbukrs = gs_acd-rbukrs TRANSPORTING NO FIELDS. IF sy-subrc EQ 0. ENDIF. "新語法 IF LINE_EXISTS( lt_acd[ rbukrs = gs_acd-rbukrs ] ). ENDIF. "-----------------------------@斌將軍-----------------------------
1.4、獲取行索引
"-----------------------------@斌將軍----------------------------- "老語法 READ TABLE lt_acd WITH KEY rbukrs = gs_acd-rbukrs TRANSPORTING NO FIELDS. IF sy-subrc EQ 0. WRITE:SY-TABIX. ENDIF. "新語法 LV_INDEX = LINE_INDEX( lt_acd[ rbukrs = gs_acd-rbukrs ] ). "-----------------------------@斌將軍-----------------------------
需要特別注意的是,新語法必須用TRY CATCH,或在查詢前,用LINE_EXISTS()判斷是否存在,否則將會導致DUMP
TRY . ls_acd = lt_acd[ rbukrs = '333' ]. CATCH cx_sy_itab_line_not_found . MESSAGE '未找到資料' TYPE 'E' . ENDTRY. "或 IF line_exists( lt_acd[ rbukrs = '333' ] ). ls_acd = lt_acd[ rbukrs = '333' ]. ELSE. MESSAGE '未找到資料' TYPE 'E' . ENDIF.
2.效率對比
由於老語法可以使用二分法查詢,因此在效率上將會有差異。
現編寫一個例項,迴圈2萬條資料GT_ACD,並迴圈查詢有14萬條資料的LT_ACD中對應的值。下邊測試各種情況下的查詢速度
2.1、新語法
"-----------------------------@斌將軍----------------------------- "1.測試新語法------------------------------------ GET TIME STAMP FIELD lv_current1. CLEAR:lv_index. LOOP AT gt_acd INTO gs_acd. lv_index = lv_index + 1. TRY . ls_acd = lt_acd[ rbukrs = gs_acd-rbukrs gjahr = gs_acd-gjahr belnr = gs_acd-belnr docln = gs_acd-docln ]. CATCH cx_sy_itab_line_not_found . MESSAGE '未找到資料' TYPE 'E' . ENDTRY. ENDLOOP. GET TIME STAMP FIELD lv_current2. "-----------------------------@斌將軍-----------------------------
結果:
2.2、老語法READ
"-----------------------------@斌將軍----------------------------- "2.測試老語法------------------------------------ GET TIME STAMP FIELD lv_current1. CLEAR:lv_index. LOOP AT gt_acd INTO gs_acd. lv_index = lv_index + 1. READ TABLE lt_acd INTO ls_acd WITH KEY rbukrs = gs_acd-rbukrs gjahr = gs_acd-gjahr belnr = gs_acd-belnr docln = gs_acd-docln. IF sy-subrc EQ 0. ENDIF. ENDLOOP. GET TIME STAMP FIELD lv_current2. "-----------------------------@斌將軍-----------------------------
結果:
2.3、老語法READ二分查詢
"-----------------------------@斌將軍----------------------------- GET TIME STAMP FIELD lv_current1. CLEAR:lv_index. SORT lt_acd BY rbukrs gjahr belnr docln. LOOP AT gt_acd INTO gs_acd. READ TABLE lt_acd INTO ls_acd WITH KEY rbukrs = gs_acd-rbukrs gjahr = gs_acd-gjahr belnr = gs_acd-belnr docln = gs_acd-docln BINARY SEARCH. IF sy-subrc EQ 0. lv_index = lv_index + 1. ENDIF. ENDLOOP. GET TIME STAMP FIELD lv_current2. "-----------------------------@斌將軍-----------------------------
結果:< 1S
2.4、新語法+排序表
"-----------------------------@斌將軍----------------------------- "4.測試新語法+排序表------------------------------------ lt_acd_sort = lt_acd. GET TIME STAMP FIELD lv_current1. CLEAR:lv_index. LOOP AT gt_acd INTO gs_acd. lv_index = lv_index + 1. TRY . ls_acd = lt_acd_sort[ rbukrs = gs_acd-rbukrs gjahr = gs_acd-gjahr belnr = gs_acd-belnr docln = gs_acd-docln ]. CATCH cx_sy_itab_line_not_found . MESSAGE '未找到資料' TYPE 'E' . ENDTRY. ENDLOOP. GET TIME STAMP FIELD lv_current2. "-----------------------------@斌將軍-----------------------------
結果:< 1S
綜上所述:不使用二分查詢,則新老語法都很慢。使用二分查詢或新語法搭配排序表,則速度都有非常明顯的提升