ABAP 語言特色


CD263
ABAP語言新特點
What is new in ABAP in NW 7.0, EhP2?
Jean Guo
Zhong Ba
Tao Xu
©2010 SAP AG. All rights reserved. / Page 2
Disclaimer
This presentation outlines our general product direction and should not be relied on in making a 
purchase decision. This presentation is not subject to your license agreement or any other 
agreement with SAP. SAP has no obligation to pursue any course of business outlined in this 
presentation or to develop or release any functionality mentioned in this presentation. This 
presentation and SAP's strategy and possible future developments are subject to change and 
may be changed by SAP at any time for any reason without notice. This document is provided 
without a warranty of any kind, either express or implied, including but not limited to, the implied  
warranties of merchantability, fitness for a particular purpose, or non-infringement. SAP 
assumes no responsibility for errors or omissions in this document, except if such damages 
were caused by SAP intentionally or grossly negligent.
©2010 SAP AG. All rights reserved. / Page 3
課程安排
1. 表達式
2. 內表
3. 基於類的異常處理
4. 十進制浮點數
5. 使用Locator和數據流讀寫數據庫
6. Boxed 組件
©2010 SAP AG. All rights reserved. / Page 4
運算表達式只能由COMPUTE命令完成
算術表達式(數字計算)
二進制表達式(位計算)
控制邏輯中只能使用純邏輯表達式
表達式–現狀
tmp1= n / i.
tmp2= ME->meth( tmp1 ) * i.
IF tmp2= n.
EXIT.
ENDIF.
過多的輔助變量給編程造成困難
一些內建方法(如strlen, lines)只能使用在非常特定的操作數位置,用途
很有限
©2010 SAP AG. All rights reserved. / Page 5
新的運算表達式類型:字符串表達式
支持運算表達式的地方:
邏輯表達式當中
IMPORTING參數中
ABAP語句中各種類型的操作數位置
擴展之后的表達式–主要功能
在方法調用時允許嵌套及鏈式調用
擴展內建方法集(如字符串處理內建方法)
通過內建方法的調用使編程更加緊湊高效
IF ME->meth( n / i ) * i = n.
EXIT.
ENDIF.
運算表達式作為方法實參
運算表達式作為邏輯表達式一個
操作數
©2010 SAP AG. All rights reserved. / Page 6
在邏輯表達式中使用計算表達式
CHECK sy-index > i + 1.
WHILE x1 BIT-AND x2 BYTE-CO
xs1 BIT-OR xs2. 位運算
LOOP AT tab INTO wa
WHERE c BETWEEN n – 10 AND n + 10.
在比較語句中的運算
IF sy-tabix MOD 10 = 0.
ULINE.
ENDIF.
算術運算
IF int / ( 4 * int ) = 0. 整型運算→ true
IF flt / ( 4 * flt ) = 0. 浮點型運算→ false
©2010 SAP AG. All rights reserved. / Page 7
在IMPORTING參數中使用運算表達式
o->m( abs( i * 2 ) + 1 ).
不指定參數名
cl=>m( p1 = i + 1  p2 = 2 ** j ).
指定參數名
o->m( pX10  = BIT-NOT x1 
pXStr = x1 BIT-OR x2 ).
任意二進制類型參數均接受二進制運算表達
式
cl=>m( pInt = 12 / 10 
pDec = 12 / 10 ).
任意數字類型的參數均接受算術運算表達式
形參的類型決定運算類型(pInt1, pDec
1.2)
CREATE OBJECT o EXPORTING p = i + 1 .
調用構造函數構建實例時的
參數
RAISE EXCEPTION TYPE lcx
EXPORTING p = i + 1 .
實例化異常時的參數
o->m( cl=>m( p1 = o->i~m( 7 ) ) ).
將方法調用作為參數
©2010 SAP AG. All rights reserved. / Page 8
其他ABAP語句中的運算表達式(輸入操作數)
READ TABLE itab
INDEX lines( itab ) …
APPEND LINES OF oref->tab( )
FROM i + 1 TO n – 1 TO t.
DO strlen( txt ) – 1 TIMES.
數字類型的輸入操作數
MOVE-CORRESPONDING o->struct( ) TO x.
在使用通用類型輸入操作數的
位置使用方法調用
也可用於WAIT,SET BIT,GET BIT,SHIFT,FIND,REPLACE,… 
也可用於其他使用內表操作索引的語句如LOOP,INSERT,DELETE,…
也可用於其他使用通用類型輸入操作數的語句(主要是字符類型操作語句)如
CLEAR, FIND, REPLACE,…
也可用於其他使用工作區/表的內表操作語句如LOOP, INSERT, DELETE, 
READ, MODIFY,…
©2010 SAP AG. All rights reserved. / Page 9
鏈式方法調用
cl=>get_instance( )->cleanup( ).
鏈式方法調用
IF oref->m1( )->intf~m2( )->a > 1.
以鏈式調用訪問實例的成員變
量
CASE cl=>m1( )->obj->m2( ) .
以鏈式調用訪問實例的成員方
法
©2010 SAP AG. All rights reserved. / Page 10
擴展之后的表達式應用–不足
lcl=>cm_ii( 1 + abs(
lcl=>factory2(
f_in1 = lcl=>factory0( )->m_lif( )->im_lif( )->im_ii( i )
f_in2 = lcl=>cm_ii( 2 ** i ) - 3
)->m_ii(
lcl=>factory1( f_in = j + 4
)->m_lif_i(
lcl=>cm_ii( 5 )
)->im_ii( 6 )
) ) ).
©2010 SAP AG. All rights reserved. / Page 11
擴展之后的表達式應用–不足
不支持編譯器優化,如
公共子表達式消去
循環不變式提取
編程人員應合理使用中間變量以使程序更清晰
ABAP變得容易混淆
但ABAP調試器可以支持復雜表達式
可以顯示方法返回值
可以顯示中間運算結果
px_width=px_width+
col->get_layout()->width * 
units->to_px_width(col->get_layout()->width_unit).
©2010 SAP AG. All rights reserved. / Page 12
字符串表達式
新的運算表達式: 字符串表達式
 串連 txt1 && txt2
 字符串模板 |…Text…{ expression format = …}…Text…|
字符串表達式
 用於方便地創建格式化的文本(如xml)
 同算術表達式和二進制表達式一樣可以用於很多位置
 可用於替換大量的:
WRITE TO語句及相應的輔助變量
CONCATENATE語句
新的內建方法
 用於字符串處理:23個
 用於非字符串處理:8個
 用於字符串斷言:4個
©2010 SAP AG. All rights reserved. / Page 13
DATA txt TYPE string.
CONCATENATE txt1 txt2 
INTO txt.
CONDENSE txt.
txt = condense( txt1 && txt2 ).
字符串連接
連接操作符
txt1 && txt2
替換CONCATENATE語句以及相應的輔助變量
©2010 SAP AG. All rights reserved. / Page 14
字符串模板
字符串模板能夠將表達式與文本字符結合起來
|…Text…{expression format = …}…Text…|
文本字符 內嵌表達式 格式選項 文本字符
do 20 times.
prog1 = |REP{ sy-index - 1 }TEST|.
prog2 = |/{ nspace }/REP{ sy-index - 1 zero = no }TEST|.
prog3 = |/{ nspace }/REP{ sy-index - 1 align = right
pad = '0'
width = 2 }TEST|.
enddo. 
字符串模板以| 作為開始和結束
©2010 SAP AG. All rights reserved. / Page 15
字符串模板的特點
字符串模板
 允許將動態及靜態文本相結合
 可使用字符轉換,格式化以及字符串連接
 支持控制字符(如“\n” 可以新起一行)
 不能跨越多行(需要使用„&‟ 來連接多行)
 可用於替換WRITE TO 語句及輔助變量
 對於技術性文本(如code/xml/html) 進行了優化
 不支持語言相關的模板
s = |Hello, \n| &
|today is { sy-datum date = iso } \n| &
|now is { sy-uzeit time = iso }|.
©2010 SAP AG. All rights reserved. / Page 16
字符串模板中的內嵌表達式
內嵌表達式
 以„{„ 和„}‟ 作為開始和結束
 表達式結果會被轉換為字符串
 格式選項可用於定義字符串格式
 在內嵌表達式中使用的換行沒有意義
s = |<line index=“{ sy-tabix }” | &
|kind=“{ o->get_kind( ) }”>|.
s = |timestamp=“{ sy-datum date = iso }T| &
|{ sy-uzeit time = iso }”|.
格式選項
©2010 SAP AG. All rights reserved. / Page 17
常用格式選項
可用於所有類型
width [integer number] 總輸出寬度
align {left|right|center} 對齊方式(默認為左對齊)
pad [character] 填充字符
case {raw|upper|lower} 大小寫
©2010 SAP AG. All rights reserved. / Page 18
可用於數字類型的格式選項
可用於數字類型
sign
{left|leftplus|leftspace|
right|rightplus|rightspace}
正負號位置(默認左側)
exponent [integer number] 指數
decimals [integer number] 小數位數
zero {yes|no} 消零處理
number  {raw|user|environment} 小數格式(默認raw)
style CL_ABAP_FORMAT中的常量 浮點數格式
currency 數據庫表TCURC中的值 貨幣代碼
©2010 SAP AG. All rights reserved. / Page 19
可用於日期時間類型的格式選項
可用於日期和時間
date
raw (“20080906”)
user 使用自定義設置
iso (“2008-09-06”)
environment  使用區域設置
日期格式
(默認為raw)
time
raw “182504”
user 使用自定義設置
iso “18:25:04”
environment 使用區域設置
時間格式
(默認為raw)
timestamp
space 日期時間
user 使用自定義設置
iso 日期„T‟ 時間
environment 使用區域設置
時間戳格式
timezone 數據庫表TTZZ-TZONE中的值 時區
©2010 SAP AG. All rights reserved. / Page 20
7.0 EhP2之前的字符串處理
ABAP命令集, 如:
 CONCATENATE
 SPLIT
 CONDENSE
 FIND SUBSTRING | REGEX
 REPLACE SUBSTRING | REGEX
邏輯操作符集, 如:
 CS, NS
 CA, NA 
 CP, NP
內建方法集, 如:
 strlen( ... )
 charlen( ... )
字符串子串操作:
 ... text+off(len) ...
©2010 SAP AG. All rights reserved. / Page 21
字符串操作可在表達式中直接使用
新的字符串操作內建方法
text= 'Product description: Superdooper smartphone'.
desc= to_upper( condense(
substring_after( val = textsub = `description:`
occ = 1 len = 18 ) ) ).
text= `... use product no. &prod-id& (&prod-desc&).`.
LOOPAT replacementsASSIGNING <repl>.
text = replace( val = text
sub = '&' && <repl>-repl && '&'
with = <repl>-content ).
ENDLOOP. 
結果:"SUPERDOOPER SMART" 
結果:"... use product no. XY007 (SUPERDOOPER SMART)." 
'prod-id‘ `XY007`
'prod-desc‘ desc
參數替換= 
©2010 SAP AG. All rights reserved. / Page 22
返回值為字符串的方法(1)
提取子串
substring( val = s [off = i1] [len = i2] )
substring_after( val = s (sub|regex) = s1 [occ = i1] [len = i2] )
substring_from( val = s (sub|regex) = s1 [occ = i1] [len = i2] )
substring_before( val = s (sub|regex) = s1 [occ = i1] [len = i2] )
substring_to( val = s (sub|regex) = s1 [occ = i1] [len = i2] )
segment( val = s index = i [sep = s1] )
match( val = text regex = regex [case = case] [occ = occ] )
字符串移位
shift_left( [val =] s [places = i1 | circular = i2 | sub = s1] )
shift_right( [val=] s [places = i1 | circular = i2 | sub = s1] )
©2010 SAP AG. All rights reserved. / Page 23
返回值為字符串的方法(2)
字符串轉化
replace( val = s (sub|regex) = s1 with = s2 [occ = i1] [case = c] )
insert( val = s sub = s1 [off = i] )
repeat( val = s occ = i )
condense( [val =] s [del = s1] [from = s2] [to = c] )
reverse( [val =] s )
escape( val = s format = f )
translate( val = s from = s1 to = s2 )
to_upper([val =] s )
to_lower([val =] s )
to_mixed( [val =] s [sep = c1] [case = c2] [min = i] )
from_mixed( [val =] s [sep = c1] [case = c2] [min = i] )
©2010 SAP AG. All rights reserved. / Page 24
返回值為字符串的方法(3)
oref->meth( 
boolc( …condition… )  
).
if …condition… .
temp_flag = 'X'.
else.
temp_flag = ' '.
endif. 
oref->meth( temp_flag ).
連接內表各行
concat_lines_of( [table =] t [sep = s] ) 將內表<t> 各行以<s>為分隔符連接
布爾運算
boolc( logical-expression) 如邏輯表達式為真,返回„X‟ 否則返回„ ‟
boolx( bit = i bool = logical-expression)
返回值為一個Byte, 如果邏輯表達式結果為真,
則此Byte第i位置1,否則置0
©2010 SAP AG. All rights reserved. / Page 25
可在邏輯表達式中直接使用字符串內建方法
新的用於字符串描述的內建方法
IF not matches( val = email
regex = `\w+(\.\w+)*@(\w+\.)+(\w{2,4})` ).
* Email format is not valid
…
如果email格式合法,則match方法返回真值
text= `... use product no. XY007 (SUPERDOOPER SMART).`.
IF find( val = text sub = 'XY'case= abap_true
occ = 1
off = 10 len = 20 ) <> -1.
* Substring found
…
find方法給出子串’XY‘在text中從11位到31位的位移量
如果找不到子串,則返回-1
©2010 SAP AG. All rights reserved. / Page 26
字符串描述方法
搜索子串(返回所找到位置的位移量)
find( val= s (sub|regex) = s1 [off = i1] [len = i2] [occ= i3] [case = c] )
find_end( val = s (sub|regex) = s1 [off = i1] [len = i2] [occ = i3] [case = c] )
find_any_of( val= s sub = s1 [off = i1] [len = i2] [occ= i3] )
find_any_not_of( val = s sub = s1 [off = i1] [len = i2] [occ = i3] )
子串計數(返回所找到的子串數量)
count( val = s (sub|regex) = s1 [off = i1] [len = i2] [occ = i3] [case = c] )
count_any_of( val = s sub = s1 [off = i1] [len = i2] [occ = i3] )
count_any_not_of( val = s sub = s1 [off = i1] [len = i2] [occ = i3] )
字符串相似度(返回兩個字符串的LevenshteinDistance值)
distance( val1 = s1 val2 = s2 [max = i] )
©2010 SAP AG. All rights reserved. / Page 27
字符串斷言方法
包含子串或字符
contains( val = s (sub|start|end|regex) = s1 [off = i1] [len = i2] [occ = i3] [case = c] )
contains_any_of( val = s (sub|start|end) = s1 [off = i1] [len = i2] [occ = i3])
contains_any_not_of( val = s (sub|start|end) = s1 [off = i1] [len = i2] [occ = i3] )
匹配正則表達式
matches( val = text regex = regex [case = case] [off = off] [len = len] )
©2010 SAP AG. All rights reserved. / Page 28
總結–擴展后的表達式
擴展了表達式的用途
 支持了更多的操作數位置,特別是一些內表相關的ABAP語句
 與面向對象無縫集成(嵌套調用,鏈式調用)
字符串表達式
 簡單實用
 可以像算術表達式一樣直觀地使用
 豐富的格式選項
 豐富的內建方法
想了解更多?
 運行ABAP report程序:DEMO_EXPRESSIONS
 查看ABAP在線文檔
Demo 演示& 練習
©2010 SAP AG. All rights reserved. / Page 30
課程安排
1. 表達式
2. 內表
3. 基於類的異常處理
4. 十進制浮點數
5. 使用Locator和數據流讀寫數據庫
6. Boxed 組件
©2010 SAP AG. All rights reserved. / Page 31
為什么在內表中使用次鍵(Secondary Keys)?
有鍵值的內表的優點(自4.0起支持) 
對哈希表的鍵值快速訪問,時間復雜度:O(1)
Time
Table Size
Hashed
©2010 SAP AG. All rights reserved. / Page 32
為什么在內表中使用次鍵(Secondary Keys)?
有鍵值的內表的優點(自4.0起支持) 
對哈希表的鍵值快速訪問,時間復雜度:O(1)
對排序表的鍵值快速訪問,時間復雜度:O(log n)
對排序表的部分連續快速處理(LOOP … WHERE 優
化)
Time
Table Size
Hashed
Sorted
©2010 SAP AG. All rights reserved. / Page 33
為什么在內表中使用次鍵(Secondary Keys)?
有鍵值的內表的優點(自4.0起支持) 
對哈希表的鍵值快速訪問,時間復雜度:O(1)
對排序表的鍵值快速訪問,時間復雜度:O(log n)
對排序表的部分連續快速處理(LOOP … WHERE 優
化)
非主鍵訪問
緩慢的性能,時間復雜度:O(n)
可能會導致整體性能問題
需要由手工實現的次鍵訪問來進行性能優化,而
這種手工實現很容易出錯
提供像數據庫表一樣的次鍵
在添加次鍵的同時保留兼容性
(不會自動隱式使用次鍵)
編譯器提示正確用法
Time
Table Size
Hashed
Sorted
Standard
實際應用中的低性
能
數據量小的情
況下性能不錯
©2010 SAP AG. All rights reserved. / Page 34
內表的屬性
LH 0400 4.167              A380-800
SQ 0866 1.625  A340-600
UA 0007 2.572              767-200  
CARRID CONNID DISTANCE      PLANETYPE
行類型:
t_flight
主鍵
QF 0005 1.000              747-400   索引訪問
4
次鍵訪問
A340-600
次鍵: 
plane
唯一性檢查
AA 0017 2.572          737-800
主鍵訪問
UA 0007
LH 0400 6.162              A340-600
data flights type sorted table of t_flight
with unique key carrid connid
with non-unique sorted key plane components planetype.
©2010 SAP AG. All rights reserved. / Page 35
定義次鍵
次鍵是內表類型定義的一部分,即靜態定義
但在一些ABAP語句中(如READ, LOOP, …)次鍵以及組件可以動態指定
次鍵定義必須完整, 也就是說如下屬性必須全部指定
定義次鍵名稱(Keyname) , 系統保留字: PRIMARY_KEY,LOOP_KEY
訪問類型(Access kind): HASHED或SORTED
唯一性(Uniqueness): UNIQUE或NON-UNIQUE,哈希值必須唯一(UNIQUE)
組件(Key components): 可以使用自定義的組件列表或者使用TABLE_LINE
最多支持15個次鍵
DATA <Well-known table definition>
WITH
KEY 
COMPONENTS
<Uniqueness> <Access Kind>
<Components>
<Keyname>
©2010 SAP AG. All rights reserved. / Page 36
非唯一性次鍵vs. 唯一性次鍵
非唯一性(排序)次鍵
懶惰索引更新(Lazy index update), 即:索引在被用到之前不會自動更新
如果沒有使用該索引,則不會消耗相應的內存空間
因此,非常適合用於調整既有程序
唯一性次鍵
唯一性是一個語義上的約束, 也就是對於違反約束的原子操作(INSERT, MOVE, 
SELECT, …)即刻做出反應(異常/運行時錯誤)
©2010 SAP AG. All rights reserved. / Page 37
定義次鍵–實例
©2010 SAP AG. All rights reserved. / Page 38
定義次鍵–ABAP字典
ABAP 字典
(SE11)
新的標簽項
„Secondary Key“
最多支持15個次鍵
©2010 SAP AG. All rights reserved. / Page 39
數據庫表中的次鍵vs. 內表中的次鍵
數據庫表
優化器判定選擇哪一個鍵
一般情況下,結果集可按任意次序返回,  次序由SELECT語義決定
內表
定義好的內表條目次序
標准表/哈希表:插入次序
排序表:插入位置
無法采用基於優化器的判定
因此,需要顯式指定要使用哪一個鍵
©2010 SAP AG. All rights reserved. / Page 40
在有次鍵的內表上INSERT
ABAP在內表插入語句(INSERT, SELECT … INTO, MOVE, …)中並沒有針對次鍵的語
法擴展
由應用次鍵帶來的性能提升是以適度增加內存消耗和鍵值更新為代價的:
主鍵立即更新
如果一個鍵值已經存在,則在向排序表和哈希表插入一條重復數據時並不更新主鍵
(但語句返回值會置為非0)
在批量重復插入時會產生運行時錯誤
唯一性次鍵也會立即更新
如果一個鍵值已經存在,則在向排序表和哈希表插入一條重復數據時會拋出可捕獲的異常
在批量重復插入時會產生運行時錯誤
非唯一性次鍵采用懶惰更新(lazy update)
只有當用該次鍵訪問內表時,這些鍵才會被更新
在使用該鍵之前沒有額外的內存開銷(除一些基本的程序管理開銷)
要避免使用不必要的次鍵
©2010 SAP AG. All rights reserved. / Page 41
在有次鍵的內表上READ
新的語法擴展… USING KEY KeyName…
新的語法擴展… KeyNameCOMPONENTS …針對WITH從句
在WITH從句中的次鍵組件須注意恰當使用
對唯一性鍵值所有組件都必須指定
對非唯一性鍵值必須指定其引導部分
©2010 SAP AG. All rights reserved. / Page 42
在有次鍵的內表上LOOP
新的語法擴展… USING KEY KeyName…
新的語法擴展… USING KEY KeyName…針對WHERE從句
在WHERE條件中指定次鍵的組件:
comp
1
= val
1
AND … AND comp
n
= val
n
在WHERE從句中的次鍵組件須注意恰當使用(同READ WITH)
其他的非鍵值組件可以由AND進行連接
©2010 SAP AG. All rights reserved. / Page 43
其他支持次鍵的ABAP語句
新的語法擴展… USING KEY KeyName…針對DELETE和MODIFY
©2010 SAP AG. All rights reserved. / Page 44
主動鍵值保護
主鍵:寫保護
排序表和哈希表的鍵組件是受到寫保護的,不允許通過指針或引用更改鍵組件的值
次鍵:
在針對一個指定次鍵的loop當中,相關的鍵組件均被寫保護
在嵌套loop中, 所有主鍵及當前使用的相關次鍵的組件均被寫保護
技術上講,這需要在所有寫操作時對鍵組件進行監控
當前沒有使用的鍵的組件將會被覆蓋(索引更新延遲進行)
否則,如果所有次鍵的所有組件均處於寫保護狀態,則在向內表添加新的鍵值的時候會產生
不兼容的后果
©2010 SAP AG. All rights reserved. / Page 45
可應用次鍵的業務場景
適合使用次鍵的業務場景
 超大表
 在最初表創建之后,沒有或只有少量的表更新操作
 程序管理開銷主要集中在創建表的階段
 在使用次鍵之后性能提升顯著
使用唯一性次鍵的特殊應用場景
 需要重視數據完整性(唯一性)的程序
 小型內表
以下情況不應使用次鍵
 小型內表(少於50條記錄),系統開銷和內存消耗另其得不償失
 內表經常性地需要更新
©2010 SAP AG. All rights reserved. / Page 46
總結–內表次鍵
次鍵可以非常容易地與已有程序進行集成或在新程序當中應用以提高程序性能
 ABAP定義了一些語法擴展(USING KEY, COMPONENTS)以使用次鍵
 ABAP語法檢查會對冗余及性能進行提示
 通過添加次鍵,既有程序的性能可以有效地提高,並且這些改動是上下兼容的
 懶惰更新(lazy update)及延遲更新處理提供了強大的增量處理能力
©2010 SAP AG. All rights reserved. / Page 47
data:
condition typestring.
* construct condition string dynamically
condition = |{ cname1 } >= { start } and | &
|{ cname2 } <= { start } + { delta }|.
* evaluateloopcondition completely at runtime
loop at <itgeneric> assigning <line>
where (condition).
…
endloop.
另一些不同的情況…
LOOP AT <itab> with dynamic WHERE condition
動態工作
區
動態WHERE 條
件
通用內表
如對數據庫表操作的讀取中所用到的動態WHERE條件一樣, 這里我們需要:

ABAP提供了非常廣泛的通用及動態編程技術,但是有一個功能之前並未提供:
©2010 SAP AG. All rights reserved. / Page 48
支持動態WHERE條件的LOOP語句
動態WHERE條件與靜態WHERE條件遵循同樣的規則:
 操作符左邊的操作數必須是內表行的一個組件
 操作符右邊的操作數在LOOP到某一條記錄時判定
動態WHERE條件也可用於以下語句:
 MODIFY ... WHERE
 DELETE ... WHERE
(規則同上)
©2010 SAP AG. All rights reserved. / Page 49
data:
condition typestring.
* construct condition dynamically
condition = |comp1 cp { val1} and | &
|not comp2 < { val2 } or | &
|comp3 = { val3} equiv comp4 = { val4}|.
loop at <itgeneric> assigning <line>
where (condition). 
…
endloop.
動態WHERE條件的構造
一個合法的條件構造如下:
所有類型的算術和字
符串操作
布爾操作符:
and, or, not, equiv
©2010 SAP AG. All rights reserved. / Page 50
錯誤處理
如果使用了不正確的WHERE條件,程序會在運行時拋出
CX_SY_ITAB_DYN_LOOP異常:
data:
condition type string,
excptype ref to cx_sy_itab_dyn_loop.
* construct condition dynamically
condition = |comp1 = { val1} ant | &
|comp2 = { val2}|.
try.
loopat <itgeneric> assigning <line>
where (condition).
...
endloop.
catch cx_sy_itab_dyn_loop intoexcp.
" error handling
endtry.
條件不能正常解析: 
unknown operator 
ant
©2010 SAP AG. All rights reserved. / Page 51
總結–動態WHERE條件
動態WHERE條件可以使用以下結構條件:
 方法調用和成員變量
 運算表達式
 預定義方法
 數據引用
 動態WHERE支持次鍵
性能表現:
 為避免內部類型轉換問題,組件部分和值部分應使用相同數據類型.
 如果在WHERE條件當中恰當地使用了內表的鍵(排序鍵的第一個組件, 哈希鍵的所有
組件),則該WHERE條件可以被優化
 作為一個內部優化,ABAP使用了緩存使得表的靜態信息可以重用
Demo 演示& 練習
©2010 SAP AG. All rights reserved. / Page 53
課程安排
1. 表達式
2. 內表
3. 基於類的異常處理
4. 十進制浮點數
5. 使用Locator和數據流讀寫數據庫
6. Boxed 組件
©2010 SAP AG. All rights reserved. / Page 54
基於類的異常處理的幾條原則
將軟件看成是(分層的)服務的集合
服務發生錯誤時:
沒有程序上下文,並且可能無法糾正錯誤
因此,只能發出錯誤標志,並且給出部分額外的錯誤信息
中止程序並且把控制流交給合適的能夠處理這種特殊情況的處理程序
RAISE EXCEPTION TYPE CX_ORDER_LOCKED EXPORTING TEXTID = …
靜態地通知調用者可能要處理的異常
METHODS readOrder … RASING CX_ORDER_LOCKED.
將普通代碼和錯誤處理程序分開: 分開定義異常處理程序
TRY.
order = readOrder( orderId ).
CATCH CX_ORDER_LOCKED into excpobj.
“ handle locked order situation
ENDTRY.
異常處理程序可以:
停止操作
繼續操作, e.g. restart the service from the beginning RETRY
©2010 SAP AG. All rights reserved. / Page 55
異常處理的例子
METHOD a.
TRY.
b( ).
CATCH cx.
…
ENDTRY.
ENDMETHOD.
METHOD b.
TRY.
c( ).
CLEANUP.
…
ENDTRY.
ENDMETHOD.
METHOD c.
…
RAISE
EXCEPTION
TYPE cx.
…
ENDMETHOD.
c
b
a
b
a
a
堆棧
代碼
1
2
3 4
1
2
4
cx的異常處理程序在方法a的執行上下文中調用!
3

©2010 SAP AG. All rights reserved. / Page 56
標准異常處理的局限
以下幾種情況下很難使用典型的異常
 處理大量數據: 子任務中的異常不能夠終止整個任務
 收集錯誤: 捕獲異常的方法必須捕獲所有的錯誤
 糾正錯誤后重新啟動: 繼續正常的后續程序
 錯誤已經糾正(比如通過用戶的交互)
 找到一個基於當前上下文的臨時解決方案
解決方案
 簡單重試服務
 不自動終止服務
 從技術角度:不可以立刻退棧
可恢復的異常
 拋出的異常必須是定義為“可恢復”的
 異常處理程序能決定是終止服務還是恢復服務
 服務必須是預定義為“可恢復”的
 分層的架構:所有的層都必須預定義為可傳遞“可恢復”的異常
©2010 SAP AG. All rights reserved. / Page 57
在異常處理程序中使用RETRY
一種可能的處理異常的辦法就是重試...
TRY.   
CATCH cx_sy_file_access_error.
ENDTRY.
OPEN DATASET file FOR OUTPUT IN BINARY MODE.
TRANSFER xbuffer TO file.
CLOSE DATASET file.
WRITE: 'Buffer successfully written'.
IF ui->ask_for_retry(
msg = 'No memory stick in port' )
IS NOT INITIAL.
RETRY.
ELSE.
WRITE: ‘Could not write buffer’.
ENDIF.
將控制交給定義當
前異常處理程序的
TRY模塊
©2010 SAP AG. All rights reserved. / Page 58
可保留上下文的異常處理程序: CATCH BEFORE 
UNWIND
恢復服務的前提: 必須保留上下文
 異常發生時不立即退棧
 沒有執行CLEANUP的程序塊
新的CATCH 子句:
 異常發生時,退棧動作和CLEANUP程序塊的執行將被推遲,直到異常處理程序執行
完成
 因此,調用異常處理程序的時候需要保留原程序執行的上下文
 原程序的堆棧還包括所有有效的局部變量
 和在TRY…ENDTRY 里使用普通CATCH一樣,使用相同的語法檢查規則
TRY.
…
CATCH BEFORE UNWINDcx_file_too_large INTO ex.
msg = …   
ENDTRY.
©2010 SAP AG. All rights reserved. / Page 59
使用Catch Before Unwind的異常處理
METHOD a.
TRY.
b( ).
CATCH BEFORE
UNWIND cx.
... 
ENDTRY.
ENDMETHOD.
METHOD b.
TRY.
c( ).
CLEANUP.
... 
ENDTRY.
ENDMETHOD.
METHOD c.
... 
RAISE
EXCEPTION
TYPE cx.
... 
ENDMETHOD.
c
b
a
b
a
a
堆棧
代碼
1
2
1
2
©2010 SAP AG. All rights reserved. / Page 60
使用Catch Before Unwind的異常處理
METHOD a.
TRY.
b( ).
CATCH BEFORE
UNWIND cx.
...
ENDTRY.
ENDMETHOD.
METHOD b.
TRY.
c( ).
CLEANUP.
...
ENDTRY.
ENDMETHOD.
METHOD c.
...
RAISE
EXCEPTION 
TYPE cx.
...
ENDMETHOD.
c
b
a
b
a
a
c
b
a
1
2
3
1
2
3
堆棧
代碼
©2010 SAP AG. All rights reserved. / Page 61
使用Catch Before Unwind的異常處理
METHOD a.
TRY.
b( ).
CATCH BEFORE
UNWIND cx.
...
ENDTRY.
ENDMETHOD.
METHOD b.
TRY.
c( ).
CLEANUP.
...
ENDTRY.
ENDMETHOD.
METHOD c.
...
RAISE
EXCEPTION
TYPE cx.
...
ENDMETHOD.
c
b
a
b
a
a
c
b
a
1
2
3
4
5
1
2
3
4
5
堆棧
代碼
©2010 SAP AG. All rights reserved. / Page 62
可恢復的異常
拋出可恢復的異常:
RAISE RESUMABLE EXCEPTION TYPE cx [ EXPORTING … ]
RAISE RESUMABLE EXCEPTION object
和RAISE EXCEPTION一樣的語法規則
拋異常的原程序需允許重啟(恢復)
Statement might or might not return
定義為可恢復的處理程序:
RESUME
語法檢查: 只可用在定義在CATCH BEFORE UNWIND里的處理程序
不可恢復的異常使用RESUME會拋運行時錯誤(no-check exception 
CX_SY_ILLEGAL_HANDLER with text id NOT_RESUMABLE)
檢查異常是否可恢復: ABAP_BOOL類型的屬性IS_RESUMABLE
如果控制流離開原處理程序而沒有執行RESUME , 那么認為處理程序選擇了“終止”,即執
行退棧動作
檢查一個異常是否是可恢復的:
IS_RESUMABLE
這是異常根類CX_ROOT的成員變量, ABAP_BOOL類型, 只讀
©2010 SAP AG. All rights reserved. / Page 63
向上傳遞可恢復的異常
讓使用者知道可能發生的可恢復的異常:
RAISING cx_1 | RESUMABLE(cx_1) …
cx_n| RESUMABLE(cx_n) 
此子句可用於methods, function modules 和forms 的定義
CX_STATIC_CHECK 和CX_DYNAMIC_CHECK 類型的異常可向上傳遞,
CX_NO_CHECK 不允許向上傳遞
如果可恢復的異常沒有在RAISING語句中的RESUMABLE關鍵字后列出,將會被作
為普通(不可恢復)的異常拋出
RESUMABLE(cx) 的含義為:當前異常可以被當作可恢復異常拋出,但不是強制的。
在se24中的定義如圖:
©2010 SAP AG. All rights reserved. / Page 64
使用Resume的異常處理
METHOD a.
TRY.
b( ).
CATCH BEFORE
UNWIND cx.
RESUME.
ENDTRY.
ENDMETHOD.
METHOD b.
TRY.
c( ).
CLEANUP.
...
ENDTRY.
ENDMETHOD.
METHOD c.
...
RAISE RESUMABLE
EXCEPTION
TYPE cx.
...
ENDMETHOD.
c
b
a
b
a
a
1
2
1
2
堆棧
代碼
©2010 SAP AG. All rights reserved. / Page 65
使用Resume的異常處理
METHOD a.
TRY.
b( ).
CATCH BEFORE
UNWIND cx.
RESUME.
ENDTRY.
ENDMETHOD.
METHOD b.
TRY.
c( ).
CLEANUP.
...
ENDTRY.
ENDMETHOD.
METHOD c.
...
RAISE RESUMABLE
EXCEPTION
TYPE cx.
...
ENDMETHOD.
c
b
a
b
a
a
c
b
a
1
2
3
1
2
3
堆棧
代碼
©2010 SAP AG. All rights reserved. / Page 66
使用Resume的異常處理
METHOD a.
TRY.
b( ).
CATCH BEFORE
UNWIND cx.
RESUME.
ENDTRY.
ENDMETHOD.
METHOD b.
TRY.
c( ).
CLEANUP.
...
ENDTRY.
ENDMETHOD.
METHOD c.
...
RAISE RESUMABLE
EXCEPTION
TYPE cx.
...
ENDMETHOD.
c
b
a
b
a
a
c
b
a
1
2
3
1
2
3
4
4 堆棧
代碼
©2010 SAP AG. All rights reserved. / Page 67
總結–
基於類的異常的新特性
RETRY –有點小用
CATCH BEFORE UNWIND
本身自有的作用(用於檢查堆棧,比如debug的時候)
是使用可恢復的異常的前提
可恢復的異常的三要素
RAISE RESUMABLE EXCEPTION: service must allow resumption, and
…RAISING(…): intermediate procedure must allow resumption, and
RESUME: exception handler must choose resumption
使用可恢復異常可以避免容易引起問題的異常處理方式,比如:
使用標志位決定忽略錯誤,或者使用內表記錄錯誤信息
使用如logging的方式記錄錯誤
使用事件(event )報告錯誤
Demo 演示& 練習
©2010 SAP AG. All rights reserved. / Page 69
課程安排
1. 表達式
2. 內表
3. 基於類的異常處理
4. 十進制浮點數
5. 使用Locator和數據流讀寫數據庫
6. Boxed 組件
©2010 SAP AG. All rights reserved. / Page 70
二進制浮點數小數的問題(F)
ABAP                   Type F
Kernel (C/C++)    Type double
輸入 用F 類型表示
(顯示16位小數)
保留小數點后2
位數(四舍五入)
期望值
0.805 8.0500000000000005E-01 0.81 0.81
0.815 8.1499999999999995E-01  0.81 0.82
4.805  4.8049999999999997E+00 4.80 4.81
4.815  4.8150000000000004E+00  4.82 4.82
 以2為底的小數如0.5, 0.25, 0.125, … 及其和可以被精確表示。
 大多以10為底的小數不可以被精確表示。
©2010 SAP AG. All rights reserved. / Page 71
ABAP P 類型: 定點小數(BCD 數字)
例子: 毫升和桶的相互轉換
使用6位小數: 
1500.000000  ml
0.009435  bbl.
1500.045128 ml         5 位小數不精確
使用最大14位小數:
1500.00000000000000  ml
0.00943471615138  bbl.
1500.00000000071672 ml 依舊有5位小數不精確
定點小數的問題(P)
1 桶= 42 加侖= 9702立方英寸= 158.987295 升
©2010 SAP AG. All rights reserved. / Page 72
ABAP中新的小數浮點類型
基本類型: DECFLOAT
此類型的實現使用了IBM‟s decNumber庫。
IBM 提供硬件支持。
沒有硬件的特殊支持,此類型的性能和類型P相近。
此類型需要數據庫提供商實現。
類型 大小 十進制數位數 最小冪指
數
最大冪指
數
DECFLOAT16 8 Bytes 16 -383 384
DECFLOAT34 16 Bytes 34 -6143 6144
©2010 SAP AG. All rights reserved. / Page 73
可用十進制浮點數的服務
DDIC, 可以和UNIT 和CUKY 類型配套使用.
序列化(CALL TRANSFORMATION) 
RFC / ALV / Web DynproABAP 
©2010 SAP AG. All rights reserved. / Page 74
如何在數據庫中存儲Decfloat類型
DF16_RAW / DF34_RAW
SAP-proprietary format  
序列化,SAP專有格式
DB
AppServer
DECFLOAT16 / DECFLOAT34
IEEE format
數據庫尚不支持新的IEEE 754-2008 
類型.
有三個可能解決方案(DDIC types). 
DF16_DEC / DF34_DEC
Fixed-point decimal format 使
用定點小數存儲
DECFLOAT16 / DECFLOAT34
IEEE format, NOT YET AVAILABLE 
直接使用新標准數據類型尚不可行
©2010 SAP AG. All rights reserved. / Page 75
如何在數據庫中存儲Decfloat類型
--使用DF16_RAW / DF34_RAW
將Decfloat16/Decfloat34 映射到RAW 類型
SAP專有格式
支持保留所有取值范圍
在DB中: 可以排序,可以比較
在DB中: 可以作為鍵值數據類型
不能保留Scale信息,尾部0會被刪除
不支持數據庫大量數據集合處理:
select sum(..)
update tab set col= col+ val
©2010 SAP AG. All rights reserved. / Page 76
如何在數據庫中存儲Decfloat類型
--使用DF16_DEC / DF34_DEC
將Decfloat16/Decfloat34 映射到DEC 類型
(定點小數), 因此需要指定長度和小數位數
在DB中:可以作為鍵值數據類型(包括緩沖區中的表)
支持數據庫大量數據集合處理
select sum(..)
update tab set col= col+ val
不支持寫入DB時對value range和value的約去
可能導致寫入時推遲溢出發生
在where子句里使用有問題:
10.00 <= 9.995
可能導致溢出
不保留尾數0
©2010 SAP AG. All rights reserved. / Page 77
Round –約去方法
新的內建方法round
指定需要保留的小數尾數:
round( val = my_value dec = my_dec ). 
指定需要保留的十進制位數:
round( val = my_value prec= my_prec ).
dec和prec不可以同時指定.
使用round 則意味着是使用類型DECFLOAT34 進行運算的.
©2010 SAP AG. All rights reserved. / Page 78
Rescale –精確度調整方法
例程 輸出
df = '12.3'.  df = rescale( val = df dec = 3 ).  12.300 
df = '12.3005'. df = rescale( val = df dec = 3 ).  12.301 
df = '12.3005'. df = rescale( val = df dec = 3
mode = cl_abap_math=>round_half_even ). 
12.300 
df = '-2.3005'. df = rescale( val = df  dec = 3 ).  -2.301 
df = '1.25005E-2'. df = rescale( val = df  dec = 3 ).  0.013 
新的內置function rescale
rescale function 可以約去尾數,也可以添加尾數0。
roundfunction 只可以約去尾數。
如果計算結果超出34個數字,rescale 將會拋異常
cx_sy_operation_failure
©2010 SAP AG. All rights reserved. / Page 79
輸入的轉換
讀取decfloat類型的值(WRITE TO 的反向操作):
DATA:
df TYPE DECFLOAT34,
ex TYPE REF TO cx_abap_decfloat_parse_err.
TRY.
cl_abap_decfloat=>read_decfloat34(
EXPORTING string = `-1,234,567.89`
IMPORTING value = df ).
CATCH cx_abap_decfloat_parse_err INTO ex.
MESSAGE ex TYPE 'E'.
ENDTRY. 
Note: 讀出數字的字符串格式由用戶的設置決定
©2010 SAP AG. All rights reserved. / Page 80
計算的精確度
COMPUTE 語句的新附加關鍵字EXACT
諸如+, -*, / 的運算符和諸如SQRT的內建方法在處理十進制浮點小數時幾乎肯定會做約去操作:
誤差范圍最多為0.5ULP(unit in the last place)
相對誤差最多為5E-34
大多數情況下,約去操作是悄悄進行的。
The EXACT 關鍵字使得用戶可以偵查到一個語句是否可以被精確運算,約去操作是否是必須的。
當語句不可以被精確運算,將拋出異常:
TRY.
COMPUTE EXACT result = 3 * ( 1 / 3 ).
... 
CATCH cx_sy_conversion_rounding INTO exception.
...
result = exception->value.
ENDTRY.
0.9999999999999999999999999999999999
©2010 SAP AG. All rights reserved. / Page 81
性能
類型decfloat的性能和類型P 的性能相近
其實現基於IBM的decNumber庫。
IBM Power 6 processor has hardware support.
類型F 由硬件支持,但是F <-> P 和F <-> C/String 的類型轉換非常消耗資
源。
©2010 SAP AG. All rights reserved. / Page 82
ABAP數字類型的使用貼士
1. 類型I
適用於整數。如果類型I的取值范圍不夠,可以使用不帶小數位的類型P 。如果還不
夠,可以使用十進制浮點小數。
2. 類型P
適用於小數數位固定的小數。如果取值范圍不夠,可以使用十進制浮點小數。
3. 類型DECFLOAT16 和DECFLOAT34
適用於小數數位不固定的小數或者取值范圍很大的數字。類型decfloat16  使用的內
存較少,但是運行時間和類型decfloat34 差不多。對於數據庫訪問,根據需要選擇類
型DFn_RAW或者類型DFn_DEC。
4. 類型F
僅僅適用於對精度要求不高,並且對性能有很高要求的算法。
©2010 SAP AG. All rights reserved. / Page 83
總結
Decfloat數據類型
新的內建方法round和rescale
使用cl_abap_decfloat 對輸入進行轉換
使用由類cl_abap_math提供的輔助方法
Decfloats可以用於
Web DynproABAP
Classic Dynpro
ALV
數據庫中的Decfloat
條件允許的情況下可以使用DF16_RAW / DF34_RAW
(比如沒有大數據量的數據庫訪問)
有大數據量的數據庫訪問時,使用DF16_DEC / DF34_DEC 
(使用此類型,取值范圍會比較小)
Demo 演示& 練習
©2010 SAP AG. All rights reserved. / Page 85
課程安排
1. 表達式
2. 內表
3. 基於類的異常處理
4. 十進制浮點數
5. 使用Locator和數據流讀寫數據庫
6. Boxed 組件
©2010 SAP AG. All rights reserved. / Page 86
動機
以前的Open SQL for ABAP支持LOB列
DATA: my_string TYPE STRING.
SELECT SINGLE content FROM dbtable_xxl
INTO my_string
WHERE id = 1.
數據庫對LOB提供更好的支持:Locators & Streams
©2010 SAP AG. All rights reserved. / Page 87
Locators –概念
Locator = 指向LOB列的值
好處:避免或者減少實例化
SELECT語句創建
 INSERT、UPDATE和MODIFY語句使用
在一個DB事務結束的時候所有的Locator都會自動結束
©2010 SAP AG. All rights reserved. / Page 88
讀取一個LOB值
1. 創建一個locator
DATA: my_locator TYPE REF TO cl_abap_db_c_locator.
SELECT SINGLE content FROM dbtable_xxl
INTO my_locator
WHERE key = 1.
2. 在UPDATE SET語句中使用這個locator
UPDATE dbtable_xxl
SET content = my_locator
WHERE key = 111.
Locators –例子I
©2010 SAP AG. All rights reserved. / Page 89
Locators –例子II
Locator的方法:
GET_LENGTH, FIND, GET_SUBSTRING, CLOSE
DATA: clob_lng TYPE abap_msize,
search_str TYPE string VALUE 'Read from here',
found_pos TYPE abap_msize,
result_str TYPE string.
* Get length of the CLOB value
clob_lng = my_locator->get_length( ).
* Find start position of substring
found_pos = my_locator->find( pattern = search_str ).
* Read substring of CLOB value
result_str = my_locator->get_substring(
offset = found_pos
length = clob_lng – found_pos ).
* Close locator (and free associated DB resources)
my_locator->close( ).
©2010 SAP AG. All rights reserved. / Page 90
Streams –概念
兩個:Reader和writer Streams可以處理序列化數據
數據可以根據需要部分讀寫
由包含Streams的SQL語句產生的底層數據庫操作,將會在所有
Streams被顯性關閉后才會結束
一定要盡快的關閉Streams!
©2010 SAP AG. All rights reserved. / Page 91
Streams –例子I
從數據庫到文件系統傳輸數據
使用一個reader stream將一個LOB列的內容寫到一個文件中去
DATA: my_reader TYPE REF TO cl_abap_db_x_reader,
my_size TYPE I VALUE 1024.
* Create reader object
SELECT SINGLE picture FROM lob_table
INTO my_reader
WHERE KEY = 1.
* Open file
OPEN DATASET 'my_file' FOR OUTPUT IN BINARY MODE.
* Transfer data
WHILE my_reader->data_available( ) = ABAP_TRUE.
TRANSFER my_reader->read( my_size ) TO 'my_file'.
ENDWHILE.
* Close stream
my_reader->close( ).
©2010 SAP AG. All rights reserved. / Page 92
Streams –例子II
從文件系統向數據庫傳輸數據
使用一個writer stream將一個文件寫進一個LOB列
DATA: my_writer TYPE REF TO cl_abap_db_x_writer,
length TYPE I.
container TYPE X LENGTH 1024.
* Open file
OPEN DATASET 'my_file' FOR INPUT IN BINARY MODE.
* Create writer stream
UPDATE lob_table SET picture = my_writer
WHERE key= 1.
* Transfer data
DO.
READ DATASET 'my_file' INTO container ACTUAL LENGTH length.
IF SY_SUBRC <> 0. EXIT. ENDIF.
my_writer->write( container ).
ENDDO.
my_writer->write( container(length) ).
* Close stream
my_writer->close( ).
COMMIT WORK.
©2010 SAP AG. All rights reserved. / Page 93
如果數據庫表有許多LOB列,那么定義一個包含Streams和Locators的工作區域是非常費
力的
LOBHANDLE結構體
TYPES wa_type TYPE lob_struct LOCATOR FOR COLUMNS lob1 lob2
READER FOR COLUMNS lob3 lob4 lob5.
WRITER和READER不能同時使用
可以給數據庫表和視圖使用
根據ABAP數據字典里的原表的描述,是可以生成相應的LOB HANDLE結
構體
STRING和RAWSTRING列可以更改成locators、readers或者writers.
當ABAP數據字典里的原表的定義變化被激活的時候,LOB HANDLE結構
體會自動更新
©2010 SAP AG. All rights reserved. / Page 94
PK: Locators vsDB Streams
用例 Locators Database Streams 
讀取
搜索
序列化處理
讀取子字符串
讀取整個內容
降低內存
©2010 SAP AG. All rights reserved. / Page 95
總結
只有一個數據庫服務器
充分利用數據庫表的緩存和索引
通過跟蹤SQL語句來檢查他們的使用
盡量堅持以下規則:
減少Round Trips的次數
通過好的索引來提高搜索命中率
盡量使用精確查找
降低傳輸數據量
降低數據庫負載
Demo 演示& 練習
©2010 SAP AG. All rights reserved. / Page 97
課程安排
1. 表達式
2. 內表
3. 基於類的異常處理
4. 十進制浮點數
5. 使用Locator和數據流讀寫數據庫
6. Boxed 組件
©2010 SAP AG. All rights reserved. / Page 98
動機
問題:
內存浪費在
填充稀疏結構
具有相同值的子結構
結構的大小限制在512K
需求:
為相同值子結構和空的子結構進行內存優化
解決方案:
分開存儲子結構
按需分配內存
©2010 SAP AG. All rights reserved. / Page 99
例子
安全協議結構:

Security Officer:
Date:
Incidents:
If Yes:
Room:
Time:
Description:
Paul Safe
Sep. 4
th
2008
Yes
12 A 5
8:45 pm
Window not closed
ABAP里面的結構:
TYPES:
BEGIN OF security_struc,
officer   TYPE C LENGTH 30,
date      TYPE D,
incidents TYPE ABAP_BOOL,
room      TYPE C LENGTH 10,
time      TYPE T,
descr TYPE C LENGTH 200,
END OF security_struc.
©2010 SAP AG. All rights reserved. / Page 100
結構體的內存分布
TYPES:
BEGIN OF security_struc,
officer   TYPE C LENGTH 30,
date      TYPE D,
incidents TYPE ABAP_BOOL,
room      TYPE C LENGTH 10,
time      TYPE T,
descr TYPE C LENGTH 200,
END OF security_struc.
Officer D
Room
T
Incidents
Descr
通常沒有用到
(if incidents = abap_false)
每條記錄存在216個空字符!
©2010 SAP AG. All rights reserved. / Page 101
想法:通過數據引用來訪問子結構
TYPES:
BEGIN OF security_struc,
officer   TYPE C LENGTH 30,
date      TYPE D,
incidents TYPE ABAP_BOOL,
details   TYPE REF TO detail_struc,
END OF security_struc.
Officer D
Room Incidents
每條記錄只有一個空的數據引用!
TYPES:
BEGIN OF detail_struc,
room  TYPE C LENGTH 10,
time  TYPE T,
descr TYPE C LENGTH 200,
END OF detail_struc.
T Descr
©2010 SAP AG. All rights reserved. / Page 102
數據引用中的字段不能成為內表的主鍵:
... TYPE SORTED TABLE OF security_struc
WITH UNIQUE KEY details->time.
笨重的數據引用操作:
IF security_entry-details IS INITIAL.
CREATE DATA security_entry-details.
ENDIF.
ASSIGN security_entry-details->* TO <details>.
垃圾收集器處理無用的數據對象(不是立即清除)
帶數據引用的數據結構不能在RFC里面使用,也不能在EXPORT功能里面使用
數據引用的缺點
語法錯誤
TYPES:
BEGIN OF security_struc,
officer   TYPE C LENGTH 30,
date      TYPE D,
incidents TYPE ABAP_BOOL,
details   TYPE REF TO detail_struc,
END OF security_struc.
TYPES:
BEGIN OF detail_struc,
room  TYPE C LENGTH 10,
time  TYPE T,
descr TYPE C LENGTH 200,
END OF detail_struc.
©2010 SAP AG. All rights reserved. / Page 103
解決方案:Boxed 組件
Officer D
Room Incidents
每條記錄只有一個空的數據引用!
T Descr
TYPES:
BEGIN OF security_struc,
officer   TYPE C LENGTH 30,
date      TYPE D,
incidents TYPE ABAP_BOOL,
details   TYPE detail_struc BOXED,
END OF security_struc.
TYPES:
BEGIN OF detail_struc,
room  TYPE C LENGTH 10,
time  TYPE T,
descr TYPE C LENGTH 200,
END OF detail_struc.
©2010 SAP AG. All rights reserved. / Page 104
結構體中Boxed 組件的定義
TYPES:
BEGIN OF my_struct,
...
boxed_component TYPE structure_type BOXED,
...
END OF my_struct.
必須是在TYPES語法里面定義
Boxed類型必須是結構體的一部分、
或者類的成員變量或者靜態成員變
量的一部分
只有結構類型可用聲明成為
BOXED
©2010 SAP AG. All rights reserved. / Page 105
類中Boxed 組件的定義
CLASS lcl_my_classDEFINITION.
PUBLIC SECTION.
CLASS DATA:
boxed_class_attribute TYPE structure_type BOXED.
DATA:
boxed_instance_attribute TYPE structure_type BOXED.
ENDCLASS.
Boxed類型必須是結構體的一部分、
或者類的成員變量或者靜態成員變
量的一部分
只有結構類型可用聲名為BOXED
©2010 SAP AG. All rights reserved. / Page 106
訪問Boxed 組件
Boxed Components可以象普通的結構一樣訪問:
sec-details-time = sy-uzeit.
lcl_security=>details-room = ’12 A 5’.
Boxed Components可以提供類似普通結構一樣有語義的值:
lcl_security=>details-room = ’12 A 5’.
sec-details = lcl_security=>details.
lcl_security=>details-room = ’24 C 3’.
sec-details-roomstill contains ’12 A 5’
Boxed組件可以做為內表的主鍵
Boxed組件可以在EXPORT功能和RFC中使用(必須使用basXML)
TYPES:
BEGIN OF security_struc,
...
details TYPE
detail_struc BOXED,
END OF security_struc.
DATA sec TYPE security_struc.
CLASS lcl_security DEFINITION,
PUBLIC SECTION.
CLASS-DATA:
details TYPE
detail_struc BOXED.
ENDCLASS.
©2010 SAP AG. All rights reserved. / Page 110
Boxed結構的內容
讀取類型時初始化記錄
內存分配
不會分配內存給boxed結構的語句:
讀:
time = sec-details-time.
引用根節點結構:
ASSIGN sec TO <fs>.
GET REFERENCE OF sec TO ref.
會分配內存給boxed結構的語句:
寫:
sec-details-time = sy-uzeit.
引用boxed結構:
ASSIGN sec-details TO <fs>.
GET REFERENCE
OF sec-details TO ref.
參數傳遞:
obj->meth( CHANGING
details = sec-details ).
初始化boxed 引
用
根結構
Boxed 引用
根結構
初始化box:
已分配的box:
©2010 SAP AG. All rights reserved. / Page 111
總結
如下情況不要使用boxed組件:
結構中某一字段使用頻率很高
該結構長度小於100個Byte
根結構被數據庫表重用
如下情況請使用boxed組件:
結構中的字段通常不被使用,比如:
存儲下列情形的詳細信息的時候
–出錯的時候
–在給定某些可選參數的時候
為某些很少使用的信息做緩存的時候
為某個特定請求而使用的時候
結構長度大於100個Byte
Demo DEMO& EXERCISE 演示& 練習

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM