CDS view是SAP目前推出的下一代database views,SAP認為傳統(tǒng)的database view只是將多張表進行關聯(lián),CDS View是一個成熟的Data Model,它有很多SE11中所沒有的新特性,并且可以被SAP產(chǎn)品外的Application使用。
1 在Eclipse中創(chuàng)建CDS View
右擊新建ABAP Object,選擇CSD->Data Definition

點擊下一步往后,在此頁面可以選擇模板,其中
${sql_view_name}是將來在SE11中生成的view的名稱
2 CDS View代碼
2.1 Define View / Define View with Join
使用模板生成的代碼如下
@AbapCatalog.sqlViewName: 'ZV_MONSTERS'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Monster CDS views'
define view zcds_monsters as select from ztmonster_header as
monster_header
inner join ztmonster_items as monster_items
on monster_header.db_key = monster_items.db_key
left outer join ztmonster_pets as monster_pets
on monster_header.monster_number = monster_pets.owner
{
key monster_header.monster_number as monster_number ,
monster_header.name as monster_name ,
LPAD ( monster_header.tax_number, 10 , '0' ) as hat_size ,
SUBSTRING ( monster_header.name, 1 , 1 ) as first_initial ,
case monster_header.evilness
when 'BANKER_STYLE_EVIL' then 'REALLY SCARY'
when 'EVIL' then
case monster_header.strength
when 'REALLY STRONG ' then 'SCARY'
else ' NOT SO SCARY REALLY '
end
when 'SLIGHTLY_EVIL' then 'SLIGHTLY SCARY '
else 'NOT REALLY SCARY AT ALL '
end as scariness
}
where monster_header.sanity < 10
and monster_header.color = 'GREEN'
以@開頭的為注解,除了默認的注解,可以自己添加比如buffer的注解,按F1可以獲得注解的介紹
@AbapCatalog.buffering.status : #ACTIVE
@AbapCatalog.buffering.type : #SINGLE
CSD veiw中,可以使用 inner jion / left jion等join命令,相比ABAP定義更廣泛了,通過as添加別名,使得看起來更具有實際意義。CDS中訪問表的字段使用點號.而不是傳統(tǒng)ABAP中的波浪號~。在SE11中我們定義字段時,左邊是human-friendly names, 比如CUSTOMER / CUSTOMER_NAME,而右邊是 data element ,比如 KUNNR and NAME1,CDS 中只定義human-friendly names,其類型有所取出的數(shù)據(jù)庫表字段類型自動定義。這有點類似于ABAP中通過DATA( )來定義數(shù)據(jù)的結構。所有的字段都放在{}中,在select jion關鍵詞后,在where關鍵詞前。上面例子中,通過LPAD可以將tax_number的值比如3補全成0000000003,通過SUBSTRING來取首字母。字段定義還可以用case語句。最后跟where條件語句,cds中可以用IS NULL / IS NOT NULL來判斷是否為空。
激活后,在se11中可以查看view

2.2 Define View with Association
SAP希望大家更多的是用association而不是jion,這更體現(xiàn)了概念思維,assocation不僅僅是jion,它是數(shù)據(jù)字典存儲的一種可能的jion連接的metadata,實際的jion在association被使用時才創(chuàng)建。
兩張表通過外鍵鏈接對我們來說很容易理解,但這其實與實際不匹配,比如我們下3個不同類型訂單時,我們對header數(shù)據(jù)和item數(shù)據(jù)并沒有有意思地去區(qū)別,因為通常概念中,很明顯一個訂單要有item數(shù)據(jù),否則是沒有意義的。再比如通過表LFA1/LFM1尋找supplier的purchasing related data,通過association,我們可以用Supplier.PurchasingData.BlockingFlag 而不是LFM1 ~ SPERM 。當你創(chuàng)建了association view連接起address和customer,就可以在order item的customer中重用這個association view。
Association View定義如下,monster可能沒有pets,也可能有多個,因此設為[0..*],header和item的關系可以設成[1..*],如果jion兩個主鍵字段,可以用[1..1]。另外,SAP推薦assocation的名字前面加下劃線來區(qū)分CDS view中標準字段。
@AbapCatalog.sqlViewName: 'zv_monsters_ass'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Monsters CDS View with Association'
define view Zcds_Monsters_Association as select from ztmonster_header as monster
association [0..*] to ztmonster_pets as _Pet
on monster.monster_number = _Pet.owner {
key monster.monster_number as MonsterNumber ,
key _Pet.pet_number as PetNumber ,
_Pet.owner as Owner ,
monster.name as OwnerName ,
_Pet.pet_name as Name ,
_Pet.pet_type as Type,
_Pet.pet_species as Species,
_Pet // Make association public
}
2.3 Define View with Parameters
前面建立的CDS view,其中where條件是hard-code的,我們希望能通過參數(shù)來指定where條件,比如傳統(tǒng)ABAP中
SELECT * FROM zv_monster_pars
WHERE color EQ p_color
AND sanity IN s_sanity .
可以通過如下代碼定義參數(shù),參數(shù)后面是其data element。
@AbapCatalog.sqlViewName: 'zv_monsters_pars'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Monster CDS View with Parameters'
define view Zcds_Monsters_Parameters
with parameters p_sanity_low : ZDE_MONSTER_SANITY ,
p_sanity_high: ZDE_MONSTER_SANITY ,
p_color : ZDE_MONSTER_COLOR
as select from ztmonster_header as monster {
key monster.monster_number as MonsterNumber,
monster.name as name ,
monster.color as color ,
monster.sanity as sanity ,
monster.strength as strength
}
where monster.color = :p_color and
sanity between :p_sanity_low and :p_sanity_high
在程序中可以通過如下代碼來調(diào)用
SELECT * FROM zcds_monsters_parameters(
p_color = @p_color ,
p_sanity_low = @s_sanity- l ow,
p_sanity_high = @s_sanity-high )
INTO TABLE @DATA(colorful _mad_monster_tablel)
WHERE strength~ 'REALLY_STRONG '.
2.4 Extend View
在SE11中,我們通過append對table或view進行增強,在CDSview中,對原有的CDS View進行增強可以如下
@AbapCatalog.sqlViewAppendName: 'ZV_MONSTERS_EXT'
@EndUserText.label: 'Monster CDS view extension'
extend view ZCDS_MONSTERS with ZCDS_MONSTERS_EXTENSION {
monster_header.age,
monster_header.monster_count as counts
}
增強后,原CDS View將有增強標記

在原始view中,可以看到append的字段

2.5 Table Function
定義table function如下,table function必須將clinet作為參數(shù)傳入,returns中的字段即為返回的字段,取數(shù)邏輯放在AMDP Class的方法中。
@EndUserText.label: 'Table Function'
define table function ZCDS_tablefun
with parameters @Environment.systemField: #CLIENT
clnt : abap.clnt
returns {
client : s_mandt;
carrname : s_carrname;
connid : s_conn_id;
city_from : s_from_cit;
city_to : s_to_city;
}
implemented by method ZLL_DEMO_AMDP_FUNCTIONS=>GET_flights;
定義AMDP class,繼承接口if_amdp_marker_hdb,
CLASS zll_demo_amdp_functions DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES if_amdp_marker_hdb .
CLASS-METHODS get_flights FOR TABLE FUNCTION zcds_tablefun .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zll_demo_amdp_functions IMPLEMENTATION.
METHOD get_flights
BY DATABASE FUNCTION FOR HDB
LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY
USING scarr spfli.
RETURN SELECT sc.mandt as client, sc.carrname, sp.connid, sp.cityfrom, sp.cityto
from scarr as sc
inner join spfli as sp on sc.mandt = sp.mandt and
sc.carrid = sp.carrid
ORDER BY sc.carrname, sp.connid;
endmethod.
ENDCLASS.
2.6 Authority Checks
在DDL中,我們配置@AccessControl.authorizationCheck: #CHECK,一個完整的CDS View需要 DDL + DCL

選擇模板,代碼如下
@EndUserText.label: 'Authority Check for CDS view'
@MappingRole: true
define role Zdcl_Monsters_Parameters {
grant
select
on
Zcds_Monsters_Parameters
where
// condition;
// -- Example WHERE condition
// -- Two-field mapping to PFCG authorization with filter on read authorization
( color ) = aspect pfcg_auth( z_mon_col, color, ACTVT = '03' ) ;
// and
// -- Equals-or-initial operator
// ( CustomerCountry ) ?= aspect pfcg_auth( S_ACM_DEMO, SACMCNTRY )
// or
// -- Reference to the logged on users name
// CreatedBy = aspect User
// or
// -- Literal condition
// isPublic = 'X';
}