ABAP New Features - Internal Tables
Using Secondary keys to Access the Same Internal Table in Different Ways
如下面程式碼中,我們需要根據number或name讀取資料,number定義成hash表的key,因此如果有值將採用number 作為primary key讀取,如果number為空將採用name作為second key讀取。
DATA:
table_of_monsters TYPE HASHED TABLE OF ztsm_monsters WITH UNIQUE KEY monster_number
WITH NON-UNIQUE SORTED KEY sort COMPONENTS name .
IF id_monster_number IS NOT INITIAL.
READ TABLE table_of_monsters INTO es_monsters
WITH TABLE KEY monster_number = id_monster_number.
ELSE.
READ TABLE table_of_monsters INTO es_monsters
WITH KEY sort COMPONENTS name = id_name ##primkey[sort].
ENDIF.
如下程式碼將monster_number bed_number定義為hash key並將monster_number 定義為second key,如果只有monster_number,首先通過read table TRANSPORTING NO FIELDS 檢查是否存在,由於定義了second key,內表將可以根據second key做LOOP及read binary search。monster_beds可以作為hash table也可以作為sorted table。
DATA:
monster_beds TYPE HASHED TABLE OF ztvc_monstr_beds
WITH UNIQUE KEY monster_number bed_number
WITH NON-UNIQUE SORTED KEY sort COMPONENTS monster_number,
start_point TYPE sy-tabix.
IF id_bed_number IS NOT INITIAL.
READ TABLE monster_beds INTO es_beds
WITH TABLE KEY monster_number = id_monster_number
bed_number = id_bed_number.
ELSE.
"No bed, return all bed data for monster
READ TABLE monster_beds TRANSPORTING NO FIELDS
WITH KEY sort COMPONENTS monster_number = id_monster_number ##primkey[sort].
CHECK sy-subrc = 0.
start_point = sy-tabix.
LOOP AT monster_beds INTO DATA(monster_bed_record)
USING KEY sort FROM start_point.
IF monster_bed_record-monster_number GT id_monster_number.
EXIT."From Inner Loop
ENDIF.
CHECK monster_bed_record-monster_number = id_monster_number.
APPEND monster_bed_record TO et_monster_beds.
ENDLOOP.
SORT et_monster_beds BY monster_number bed_number.
ENDIF.
Table Work Areas
以前我們一般先定義internal table與work area,7.4以後,我們可以在對內表的操作過程中定義work area及field symbol。
DATA: monster_number TYPE zde_monster_number VALUE '000000001',
table_of_monsters TYPE STANDARD TABLE OF ztsm_monsters.
READ TABLE table_of_monsters WITH KEY monster_number = monster_number
INTO DATA(monster_details).
LOOP AT table_of_monsters INTO DATA(monster_details2).
ENDLOOP.
READ TABLE table_of_monsters WITH KEY monster_number = monster_number
ASSIGNING FIELD-SYMBOL(<monster_details>).
LOOP AT table_of_monsters ASSIGNING FIELD-SYMBOL(<monster_details2>).
ENDLOOP.
Reading from a Table
7.4以前Read Table的形式如下
READ TABLE table_of_monsters INTO monster_details
WITH KEY name = monster_name.
monster = zcl_monster=>factory( monster_details-monster_number ).
7.4以後可以內表後面跟[]來替代關鍵字read table與with key
monster = zcl_monster=>factory( table_of_monsters[ monster_name ]-monster_number ).
我們可以結合string如下使用程式碼,但這裡有個問題,如果訪問內表沒取到值,將會有異常出現。
zcl_bc_screen_message=>output(
|{ monster_name } s Monster Number is { table_of_monsters[ monster_name ]-monster_number }| ).
可以用如下程式碼來改善,新增OPTIONAL或DEFAULT來避免異常產生。此時如果為空將返回空值。
zcl_bc_screen_message=>output(
|{ monster_name } s Monster Number is { VALUE #( table_of_monsters[ monster_name ]-monster_number OPTIONAL ) }| ).
zcl_bc_screen_message=>output(
|{ monster_name } s Monster Number is { VALUE #( table_of_monsters[ monster_name ]-monster_number DEFAULT '9999999999' ) }| ).
CORRESPONDING for Normal Internal Tables
通常我們用MOVE-CORRESPONDING來將結構賦值到另一個結構,當對內表賦值時,程式碼如下
DATA: green_monsters TYPE STANDARD TABLE OF ztsm_monsters,
blue_monsters TYPE STANDARD TABLE OF ztsm_monsters.
FIELD-SYMBOLS:
<green_monsters> LIKE LINE OF green_monsters,
<blue_monsters> LIKE LINE OF blue_monsters.
LOOP AT green_monsters ASSIGNING <green_monsters>.
APPEND INITIAL LINE TO blue_monsters
ASSIGNING <blue_monsters>.
MOVE-CORRESPONDING <green_monsters> TO <blue_monsters>.
CLEAR <blue_monsters>-evilness.
<blue_monsters>-people_scared =
<green_monsters>-most_peasants_scared.
ENDLOOP.
7.4後可以用CORRESPONDING來對內表賦值,後面跟的#表示建立的目標表與原始表列相同,Except及Mapping修改了相關的欄位。
green_monsters = CORRESPONDING #(
blue_monsters
MAPPING people_scared = most_peasants_scared
EXCEPT evilness ).
MOVE-CORRESPONDING for Internal Tables with Deep Structures
如下定義內表,european_result 與 us_result都是一個欄位加一個內表結構欄位,當進行賦值時,雖然內欄位的結構不一樣,但因為都叫t_result,因此us中lockbox將被賦值上iban的值。
TYPES: BEGIN OF l_typ_european_monsters,
monster_name TYPE string,
monster_iban_code TYPE string,
END OF l_typ_european_monsters.
TYPES: l_tt_european_monsters TYPE HASHED TABLE OF l_typ_european_monsters
WITH UNIQUE KEY monster_name.
DATA: iban_code_record TYPE l_typ_european_monsters.
TYPES: BEGIN OF l_typ_european_results,
laboratory TYPE string,
t_result TYPE l_tt_european_monsters,
END OF l_typ_european_results.
TYPES: l_tt_european_results TYPE STANDARD TABLE OF l_typ_european_monsters.
DATA: european_result TYPE l_typ_european_results,
european_results TYPE l_tt_european_results.
TYPES: BEGIN OF l_typ_us_monsters,
monster_name TYPE string,
monster_lockbox_code TYPE string,
END OF l_typ_us_monsters.
TYPES: l_tt_us_monsters TYPE HASHED TABLE OF l_typ_us_monsters
WITH UNIQUE KEY monster_name.
TYPES: BEGIN OF l_typ_us_results,
laboratory TYPE string,
t_result TYPE l_tt_us_monsters,
END OF l_typ_us_results.
TYPES: l_tt_us_results TYPE STANDARD TABLE OF l_typ_us_results.
DATA: us_result TYPE l_typ_us_results,
us_results TYPE l_tt_us_results.
*--------------------------------------------------------------------*
* Listing 2.60 Attempt at MOVE-CORRESPONDING
*--------------------------------------------------------------------*
european_result-laboratory = 'SECRET LABORATORY 51'.
iban_code_record-monster_name = 'FRED'.
iban_code_record-monster_iban_code = 'AL47212110090000000235698741'.
INSERT iban_code_record INTO TABLE european_result-t_result.
MOVE-CORRESPONDING european_result TO us_result.
當兩個內表結構的欄位不一致時,以前我們賦值要用Loop,MOVE-CORRESPONDING結構
LOOP AT european_results ASSIGNING FIELD-SYMBOL(<european_result>).
APPEND INITIAL LINE TO us_results ASSIGNING FIELD-SYMBOL(<us_result>).
MOVE-CORRESPONDING <european_result> TO <us_result>.
ENDLOOP.
7.4後可以直接MOVE-CORRESPONDING內部操作MOVE-CORRESPONDING european_results TO us_results.
,但這個還是沒解決上面t_result內表結構欄位不同賦值問題。因此7.4引入了MOVE -CORRESPONDING EXPANDING NESTED TABLES
,該語句賦值時,首先刪除目標表的記錄,然後賦值時會校驗t_result內表結構欄位,如果該欄位不同則該欄位將不賦值。MOVE-CORRESPONDING KEEPING TARGET LINES
可以保留原內表的記錄,類似於APPEND LIN ES OF table1 TO table2
,MOVE -CORRESPONDING EXPANDING NESTED TABLES KEEPING TARGET LINES
可以將兩者結合起來。
Dynamic MOVE-CORRESPONDING
7.4後不推薦用MOVE-CORRESPONDING,尤其是HANA資料庫,可以用如下方法動態匹配。LEVEL引數用在匹配deep structure,kind引數可以填EXCEPT等選項,dstname為目標表的欄位,srcname為相應的值,通過cl_abap_corresponding的create及execute方法執行。
DATA: mapping_record TYPE cl_abap_corresponding=>mapping_info,
mapping_table TYPE cl_abap_corresponding=>mapping_table.
mapping_record-level = 0.
mapping_record-kind = cl_abap_corresponding=>mapping_component.
mapping_record-dstname = 'BEST_BRAIN_01'.
IF is_monster_header-hat_size > 5.
mapping_record-srcname = 'BIGGEST_BRAIN'.
ELSE.
mapping_record-srcname = 'SMALLEST_BRAIN'.
ENDIF.
APPEND mapping_record TO mapping_table.
mapping_record-dstname = 'BEST_BRAIN_02'.
IF id_monster_usage = 'MORTGAGE_SALESMAN'.
mapping_record-srcname = 'EVILEST_BRAIN'.
ELSEIF id_monster_usage = 'MORRIS_DANCER'.
mapping_record-srcname = 'WEIRDEST_BRAIN'.
ENDIF.
APPEND mapping_record TO mapping_table.
TRY.
DATA(dynamic_mapper) =
cl_abap_corresponding=>create(
source = is_possible_brains
destination = rs_best_brains
mapping = mapping_table ).
dynamic_mapper->execute(
EXPORTING source = is_possible_brains
CHANGING destination = rs_best_brains ).
CATCH cx_corr_dyn_error.
"Fatal Error
ENDTRY.
New Functions for Common Internal Table Tasks
以前我們獲取行數通過sy-tabix。
READ TABLE table_of_monsters WITH KEY monster_number = monster_number
TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
start_row = sy-tabix.
ENDIF.
現在可以用line_index來獲取
DATA(start_row2) = line_index( table_of_monsters[ monster_number = monster_number ] ).
直接作為放回值使用
LOOP AT table_of_monsters FROM line_index( table_of_monsters[ monster_number = monster_number ] )
ASSIGNING FIELD-SYMBOL(<monster_details2>).
ENDLOOP.
判斷是否存在也可以用line_exists來替代。
*--------------------------------------------------------------------*
* Listing 2.67 Seeing Whether an Internal Table Line Exists before 7.4
*--------------------------------------------------------------------*
READ TABLE table_of_monsters ASSIGNING <monster_details>
WITH KEY monster_number = monster_number.
IF sy-subrc NE 0.
APPEND INITIAL LINE TO table_of_monsters ASSIGNING <monster_details>.
ENDIF.
ADD 1 TO <monster_details>-sanity.
*--------------------------------------------------------------------*
* Listing 2.68 Seeing Whether an Internal Table Line Exists in 7.40
*--------------------------------------------------------------------*
IF line_exists( table_of_monsters[ monster_number = monster_number ] ).
READ TABLE table_of_monsters ASSIGNING <monster_details>
WITH KEY monster_number = monster_number.
ELSE.
APPEND INITIAL LINE TO table_of_monsters ASSIGNING <monster_details>.
ENDIF.
Internal Table Queries with REDUCE
REDUCE可以處理內表並放回一個結果,如下程式碼,reduce後面跟返回結果的型別,init定義了一個臨時變數,FOR迴圈結束後,result將會被賦值給mad_monsters_count。
DATA: neurotic_monsters TYPE STANDARD TABLE OF ztsm_monsters.
DATA(monster) = NEW zcl_monster( ).
DATA(mad_monsters_count) = REDUCE sy-tabix(
INIT result = 0
FOR monster_details IN neurotic_monsters
NEXT result = result +
monster->is_it_mad( monster_details-monster_number ) ).
Grouping Internal Tables
7.4在Loop中引進了Group BY選項,如下程式碼,根據Main table中的記錄,取出每個type下people scared總人數,並做附加條件判斷。在外層loop中,Group有兩條記錄,vamp/x 與 zomb/x,通過debug可以看到外層loop只迴圈兩次,monster->is_it_mad被呼叫了5次,在迴圈內,可以通過LOOP AT GROUP <monster_group_record> ASSIGNING FIELD-SYMBOL(<bonkers_monsters>)
來取出該group組合下Main table中的原始資料,然後進行相應的操作。
TYPES: tt_monsters TYPE STANDARD TABLE OF ztsm_monsters
WITH DEFAULT KEY.
DATA: monster_sub_set TYPE tt_monsters,
total_scared TYPE i.
DATA(monster) = NEW zcl_monster( ).
DATA(table_of_monsters) = VALUE tt_monsters(
( monster_number = '1' monster_type = 'VAMP' people_scared = 3 )
( monster_number = '2' monster_type = 'VAMP' people_scared = 4 )
( monster_number = '3' monster_type = 'VAMP' people_scared = 2 )
( monster_number = '4' monster_type = 'ZOMB' people_scared = 1 )
( monster_number = '5' monster_type = 'ZOMB' people_scared = 1 )
).
LOOP AT table_of_monsters INTO DATA(monster_details)
GROUP BY ( monster_type = monster_details-monster_type
is_it_crackers = monster->is_it_mad( monster_details-monster_number ) )
ASSIGNING FIELD-SYMBOL(<monster_group_record>).
CHECK <monster_group_record>-is_it_crackers = abap_true.
CLEAR monster_sub_set.
LOOP AT GROUP <monster_group_record> ASSIGNING FIELD-SYMBOL(<bonkers_monsters>).
monster_sub_set = VALUE #( BASE monster_sub_set ( <bonkers_monsters> ) ).
ENDLOOP.
CLEAR total_scared.
LOOP AT monster_sub_set INTO DATA(sub_set_record).
ADD sub_set_record-people_scared TO total_scared.
ENDLOOP.
WRITE:/ 'Bonkers Monsters of Type',<monster_group_record>-monster_type,' scared ',total_scared,' people'.
ENDLOOP.
Extracting One Table from Another
7.4以前我們過濾一個內表的資料到另一個時,只能通過Loop來做,7.4後引入了FILTER。但注意FILTER的內表必須有一個hash key或sorted key。
*--------------------------------------------------------------------*
* Listing 2.72 Extracting One Table from Another before 7.4
*--------------------------------------------------------------------*
DATA: all_monsters TYPE SORTED TABLE OF ztsm_monsters
WITH NON-UNIQUE KEY monster_number
WITH NON-UNIQUE SORTED KEY bonkers_ness
COMPONENTS sanity,
averagely_mad_monsters TYPE STANDARD TABLE OF ztsm_monsters,
an_averagely_mad_monster LIKE LINE OF averagely_mad_monsters.
LOOP AT all_monsters INTO DATA(monster_record)
WHERE sanity < 75.
CLEAR an_averagely_mad_monster.
MOVE-CORRESPONDING monster_record TO an_averagely_mad_monster.
APPEND an_averagely_mad_monster TO averagely_mad_monsters.
ENDLOOP."All Monsters
*--------------------------------------------------------------------*
* Listing 2.73 Extracting One Table from Another in 7.40
*--------------------------------------------------------------------*
DATA(averagely_mad_monsters2) =
FILTER #( all_monsters USING KEY bonkers_ness
WHERE sanity < 75 ).
以前我們取一些複雜組合時,經常在SELECT中用FOR ALL ENTRIES IN,現在,如果程式中前面已經讀取了整的pets_of_our_monsters,然後要進行all_monsters的過濾,可以採用下面的方法。同樣注意all_monsters有一個hash key或sorted key
*--------------------------------------------------------------------*
* Listing 2.74 FOR ALL ENTRIES during a Database Read
*--------------------------------------------------------------------*
DATA: monster_pets TYPE SORTED TABLE OF ztmonster_pets
WITH NON-UNIQUE KEY owner pet_number.
SELECT *
FROM ztmonster_pets
INTO CORRESPONDING FIELDS OF TABLE monster_pets
FOR ALL ENTRIES IN all_monsters
WHERE owner = all_monsters-monster_number.
*--------------------------------------------------------------------*
* Listing 2.68 FOR ALL ENTRIES on an Internal Table
*--------------------------------------------------------------------*
DATA(pets_of_our_monsters) =
FILTER #( monster_pets IN all_monsters
WHERE owner = monster_number ).
相關文章
- GNU grep's new features
- Some new features in 11g
- Oracle SQL Developer New Features in Release 4OracleSQLDeveloper
- what is the new features of Flash CS5?
- Oracle10g New Features(1)Oracle
- Keep an eye on these 5 new features in RHEL 7
- 1 Oracle Database Release 20c New FeaturesOracleDatabase
- PostgreSQL DBA(4) - PG 11 New Features#1SQL
- PostgreSQL DBA(5) - PG 11 New Features#2SQL
- PostgreSQL DBA(6) - PG 11 New Features#3SQL
- Flashback New Features and Enhancements in Oracle Database 10gOracleDatabase
- Oracle 11gR2 New Features Oracle RestartOracleREST
- DB2 V10 LUW new featuresDB2
- 11g Dataguard New Features. [ID 443540.1]
- Top 10 Oracle 11gR2 New Features ztOracle
- SAP Integrated Business Planning 1805 New Features
- ASM 11g New Features - How ASM Disk Resync WorksASM
- Dynamics 365(online) V9.0 new features(五:sitemap)
- 1 Oracle Database 11g Release 2 (11.2.0.4) New FeaturesOracleDatabase
- Dynamics 365(online) V9.0 new features(八:虛擬實體)
- 22New Cascalog features: outer joins, combiners, sorting, and more
- Dynamics 365(online) V9.0 new features for developers(四:自動編號)Developer
- Dynamics 365(online) V9.0 new features(四:多選選項集)
- Dynamics 365(online) V9.0 new features for developers(三:Web 資源本地化)DeveloperWeb
- Dynamics 365(online) V9.0 new features(三:新增兩個系統主題)
- dba_tables,dba_all_tables,user_tables,all_tables有什麼區別
- Dynamics 365(online) V9.0 new features for developers(二:JavaScript Web 資源依賴性)DeveloperJavaScriptWeb
- Dynamics 365(online) V9.0 new features for developers(一:客戶端 API 增強功能)Developer客戶端API
- Read Book "McGraw.Hill.Oracle.Database.11g.New.Features.Nov.2007.pdf"OracleDatabase
- Dynamics 365(online) V9.0 new features(六:移動端支援 iFrame 和 Web 資源)Web
- Oracle TablesOracle
- The Main Features of MySQLAIMySql
- OCP Oracle Database 11g: New Features for Administrators Exam Guide (Exam 1Z0-050) errataOracleDatabaseGUIIDE
- Oracle Externale TablesOracle
- Oracle - Tables/IndexesOracleIndex
- Oracle X$TablesOracle
- Oracle X$ TablesOracle
- Edit SAP tables