CDS Core Data Services S4 CDS view--2

 

7.2 怎么加注释

首先要看懂注释,comparefilter 一般都是true,这样在association 里的join只被验证一次,如果是FALSE就会不停的被验证。

preservekey, 验证和数据库表的key是否一致。

authorizationcheck, 需要验证权限。不过我们没有设access control,所以只有个warning。

5579e7d6f4f44d54a71c08cf1a7c9bd2.png

我们可以加view注释:

basic表示这个view是直接建在数据库表上的。

5c823e80cd8d4f458ddd21de3c3c2b5f.png

再来加元素注释:

比如对于值字段,要加个单位的:

在单位上添加注释:true,在值上面添加注释,要把单位的别名加上。

@semantics.quantity.unitOfMeasure:'OrderUnit'
menge as OrderQuantity,
@Sementics.unitOfMeasure: true
meins as OrderUnit

扩展注释:

@OData.publish: true

这个要发布起来还是挺复杂的。UI5可用。要启用服务。

要到GUI里面。/iwfnd/maint_service里配置。 

8. Union 和 Join

8.1 Union

Union要求两个表的字段数相同,字段名匹配,顺序一致。

如果两个union的view还有association的话,那底层的association和基数以及对应的目标表都得一致才行。

define view ... as
select 
 from demo_1
      {a as ch1, b as ch2, c as ch3}
union
select 
 from demo_2
      {d as ch1, f as ch2, g as ch3}

对于Union来讲,两个表中的重复项会被消除。

Union All才不会消除重复项。 

21917b89d0c1472ea7152b6ee4454b72.png

 

8.2 Join(inner/left outer/right outer/cross)

两表字段不同。

f8cfe55628564717a3f92f440bd5147a.png

define view zdemoJoin as select from ekpo as po
inner join eban as pr
      on po.banfn = pr.banfn
    and  po.bnfpo = pr.bnfpo {
         po.ebeln as PN,
         po.matnr as Matrial,
         pr.banfn as PRnum

}

2cf7f87063c2422c97c3e1e2e88cc8a1.png

 c87b447bd1cb4ab0ba657c37f9fd7930.png

 ccfa2c501b1e4c7f81090b3913110780.png

8.3 association 关联 

建模CDS view之间的关系的。

define view ZI_PO
 as select from ekko
 association [0..*] to ZI_PU as _PU on $projection.PurchaseOrder = _PU.PurchaseOrder
{ key ebelen as POrder,
      bsart as ordertype,
      
      @objectModel.association.type :[#TO_COMPOSITION_CHILD]

      —PU
}

关键词 association

基数[0..*]可以有0或者无穷个对应。关联到另一个CDS view上,然后得给一个别名,以下划线开头的。

同时这个被关联的CDS view的值可以直接发布到现有的CDS view下面。

基数的关联关系,如下图所示。1 表示最少有0条,最多有1条对应。

基数
[1]01
[0..1]01
[1..1]11
[0..*]0不限
[1..*]1不限
 01

那么association和join的区别是什么?

这个其实有点像HANA里面的refrential join。

在左外连接中:

ac0c111457d94a938060561ba77e58d5.png

 我需要关联左右两个表。但是其实我只关心左表的数据。右表我要连接,但是我不关心它的数据。这时候,如果把数据都拿过来,其实是耗费性能的一件事。

那么我就用association。

join会去把所有的数据选出来,展示出来。但是association你得点击了才去选,而且只选一条。而且association要填基数。这点需要你了解表关系。

 

9. 货币和单位转换

9.1 变量

系统提供很多变量,比如$Session.user 就是sy-uname,系统当前用户名。

$Session.client就是sy-mandt。当前client。

$Session.system_date这个很有用 sy-datum

$Session.system_language sy-langu

define view ZI_PO
 as select from ekko
 association [0..*] to ZI_PU as _PU on $projection.PurchaseOrder = _PU.PurchaseOrder
{ key ebelen as POrder,
      bsart as ordertype,
      
      @objectModel.association.type :[#TO_COMPOSITION_CHILD]

      —PU
}
where enarm = $Session.user

9.2 货币、单位转换

直接在数据库层级进行单位的转换。这些功能怎么实现的呢?

货币转换就是把一种货币金额转换为另一种货币金额。从美元转人民币啥的。

货币转换的function有四个强制参数和6个可选参数。

货币转换参数
amount*CURR

source_currency

*

CUKY

target_currency*CUKY
exchange_rate_date*DATS
exchange_rate_typeOP CHAR 4
client *  OPCLNT
roundOP CHAR
decimal_shiftOP

CHAR

decimal_shiftOPCHAR
error_handlingOPCHAR 20
define view zi_pr_quan_conv
with parameters p_DispCurr : waers_curc

as select from eban
{
 key banfn,
 key bnfpo,
    @semantics.amount.currencycode: 'TransCurrency'
    preis,
    @semantics.currencycode: true
    waers as TransCurrency,
    badat as ReqDate,

    @Semantics.amount.currencyCode: 'DisplayCurr'
    currency_conversion ( amount => preis,
                          source_currency => waers,
                          target_currency => :p_DispCurr,
                          exchange_rate_date => badat
                        )
as DispAmount,
@Semantics.currencyCode: true
:p_DispCurr as DisplayCurr

}

2c6a94bead2b4264ab16985329723389.png

 

单位转换就比如从KG转到磅重。有三个强制参数。

单位转换
quantity*QUAN,DEX,INT1,INT2,INT4,FLTP
source_unit*

UNIT

target_unit*UNIT
clientOPCLNT
error_handlingOPCHAR 20

f611d351c3b34ca2b29b499f388823d1.png

define view ZI_POHeader
as select from ekko
association [0..*] to ZI_POItem as _POItem on $projection.PurchaseOrder = _POItem.PurchaseOrder
association [1..1] to ZO_POCus as _POCus on $projection.Supplier = _POCus.Supplier
{
 key ebeln as PurchaseOrder,
     case (bsart)
     when 'RQ' then 'external'
     when 'UB' then 'Stock'
     else 'other'
     end as PurOrderType,
     ekorg as Purorg,
     _POCus.SupplierName as SupplierName,
     aedat as Creatdate,
     waers as DocCur,
     rlwrt as Totalval,
     currency_conversion (amount => rlwrt,
                          source_currency => wares,
                          target_currency => cast('CNY' as waers),
                          exchange_rate_date =>aedat ) as Totalcnyvalue,

     }

 

10. Client的处理

 @CLientHandling 可以选择处理特定client的数据。

select * from ZPO 
client specified 
into table It_PO where client = '010'

用clientHandling也是一样的:有两个注释可以用。

type有三个值可以用。

继承就是说从数据源来说明client的相关与否。如果view里面用到的数据源(即使只有一个)是基于client相关的。那么这个view就是client dependent的。如果view里面的所有数据源都是与client不相关的,那它就是client_independent .

@ClientHandling.type: #INHERITED |
#CLIENT_DEPENDENT |
#CLIENT_INDEPENDENT

@ClientHandling.algorithm #AUTOMATED |
#SESSION_VARIABLE |#NONE

 algorithm里面就要说明从哪个client来的了,怎么去取数据了。

如果值为#AUTOMATED,view的On 条件和其他语句都会被底层数据源的client列隐式的扩展。

如果是#SESSION_VARIABLE,我们有一个session 变量$Session.client也是会被隐藏式的加到where条件里,会自动选变量$Session.client的值,这个和#AUTOMATED有点像,但是性能会更好。因为其实你是写出来了这个where语句了。或者你可以用USING CLIENT这个语句明写出来。

#NONE这个是专门给非client相关的view用的,是默认CLIENT_INDEPENDENT的算法值。

 

举例: 一个采购订单和采购订单行项目的CDS view是client相关的,因为它用的底层的表是client相关的。那我们就可以在这个CDS VIEW里加两个注释:加到define view之前。

1) @ClientHandling.type: #INHERITED

2) @ClientHandling.algorithm #AUTOMATED

90c821db35e04cd3a74a9c7668b09a84.png

 

11. Access Control

对于权限控制来讲,就是说你要有应用的权限和数据的权限。

 在ABAP里权限设置的语句如下:

loop at lt_podata into ls_podata.
authority-
check object 'M_BEST_EKO' "基于采购组织来定权限
      ID 'ACTVT' FIELD '03'
	  ID 'EKORG' FIELD ls_podata-ekorg.
	  
IF  sy-subrc = 0.
 "执行逻辑
ENDIF.
endloop。

 在CDS view里的权限设置如下:一般role和cdsview应该有一样的名字。不过也可以不一样。

@MappingRole: true是默认把这个role给所有用户。

是用aspect pfcg_auth 条件可以用直接使用ABAP里面的权限字段。

@EndUserText.label : 'PO Access Control'
@MappingRole: true

define role ZI_POHDR 
{ grant 
    select 
      on ZI_PUOrder
         where (PurOrganization ) ?= aspect pfcg_auth( M_BEST_EKO, EKORG, actvt = '03');
}

如果不用aspect,也可以指定一些字段:

grant 
  select 
     on
       ZI_PURODER
        where PurOrganizaion = '0010' ;

设置好了之后,CDS抬头有个注释:@AccessControl.authozationcheck: #CHECK(默认是这个)

这就说明需要检查权限。

当然,除了#CHECK,还有#NOT_REQUIRED(有权限就检查,没有就不检查)和#NOT_ALLOWED ( 不执行权限检查)

d209ea5424b848fcab838433911c638a.png

 e47c501c57ce45f7b3a0a36ed4243ce1.png

 这个是根据你PFCG里面的权限对象来搞的。去到这个权限对象里面能看到权限字段是哪些。这个例子里面是有两个权限对象ACTVT和EKORG。

激活这个DCL role之后,再跑CDS view就会被限制了。

11.1 层级CDS view及其对应的access control

0e19c7bb676d4dbcad8e538f24f6d1a0.png

 当选择view a的数据,显然会对应到Role_a的管控:

select * from view_a into table @data(lt_view_a)

如果我选择view_b的数据,那么因为view_b的数据从view_a来的。

select * from view_b into table @data(lt_view_b) 这里也是只有role_b会被用到。

 

但是如果说我想让role_b去集成role_a怎么搞?下面就是role_b有自己的权限限制,同时继承了role_a。

@MappingRole:true
define role Role_b
{

 grant selection view_b 
  where PurOr = '0001'
 and inheriting conditions from entity Role_a;


}

实际情况下会有很多的CDS view从其他的view拿数据,同时拿完后还会和其他的view join.

这时候如果去写权限,会很麻烦,因为可能拿不到你想要的数据,数据在上层被限制住了。

这时候 可以去SACMSEL去执行 CDS Access Control Runtime Simulator。去测试用户权限。

 

12. VDM Virtual Data Model

一般情况下,咱知道,数据都是存储在数据库表中的。数据库表有一个非常复杂的结构。一般咱都是不明白这个表中到底存的是什么乱七八糟的数据,得有个专家帮你解释才行。

作为一个技术顾问,你得花点力气才能知道数据存在那里,怎么存的,存的什么数据。

为了解决这个问题呢,就搞了个Virtual Data Model。

其实也就是个CDS view,和其中的数据。VDM构建了一个中心数据模型。以前要到各个表里面去看数据,不过现在从CDS view里能看到数据是怎么关联的。

因为现在有了这个association

同时也可以给一些字段别名,这样你就能很清楚知道里面是什么数据了。

讲到这,好像也不知道VDM的结构是啥样。

455560a45e8448a1bdf68d84843c273f.png

 这个不就是BW里面的概念么Composite provider。

52499b9280cc469aa66d700fec732b1a.png

对于其他的字段,最好也有命名方式。

bdeef328549e46c48c8544a4d0bcb276.png

来总结一下以上所有:

e45c7202066949528220c60d3483be5b.png

 

 

 

 

 

13. 扩展CDS VIEW

 

14. AMDP

 以一个class的模板创建了一个可以用SQL来实现的在HANA数据库上的database procedure的AMDP方法。

当这个AMDP方法被调用的时候,一个database procedure就在HANA DB上生成了。

整个流程就是: 

6606bb2749de40508aa038773ba8aee0.png

 当这个存储过程建立了。其实也就是说这个AMDP方法可以被其他程序调用的。但是限制是什么呢?

1. SQL 语句集成到ABAP语法检查中

2. SQL debug也集成到ABAP debug中

3. 存储过程自动建在HANA 数据库中,不用delivery units去做生命周期管理

CLASS amdp_class DEFINITION。
PUBLIC SECTION.

*Marker interface with SAP HANA DB as database
INTERFACES IF_AMDP_MARKER_DB_TYPE.
METHODS amdp_method.


ENDCLASS.

CLASS amdp_class IMPLEMENTATION.

*AMDP method
METHOD amdp_method BY DATABASE PROCEDURE 

 FOR db_type
 LANGUAGE db_language
 OPTIONS db_options
 USING db_entity.

ENDMETHOD.

ENDCLASS.

cd4c64327247405d946d66bb5133a706.png

创建一个program来调用这个方法:

0483fbaf78c047f3b5991e210baed967.png

 15. oData Services和 UI5 (Smart Template)

 

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaomici

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值