RAP中CDS视图实体的定义
View Entities
2-1.定义视图实体
下图是定义语法
[ROOT]
附加的 ROOT 将 CDS 视图实体 view_entity 定义为 ABAP RESTful 应用程序编程模型中 RAP 业务对象的根实体。
根实体是业务对象层次结构的顶层节点,代表业务对象。
例一:
define root view entity zxtrap_cds_ekko
as select from zxtrap_ekko as ekko
{
key ebeln,
bukrs,
statu,
waers,
bedat,
kdatb,
kdate
}
例二:
define view entity zxtrap_cds_ekpo
as select from zxtrap_ekpo
{
key ebeln,
key ebelp,
bukrs,
matnr,
meins,
@Semantics.quantity.unitOfMeasure : 'meins'
menge,
waers,
@Semantics.amount.currencyCode : 'waers'
netwr
}
2-2.定义关联实体
CDS可以通过association,JOIN等定义连接多表
3-2-1.Association的使用
Association对象可以是表,也可以是视图
[min..max]
定义一个CDS 视图实体的关联目标的基数,它是用一个CDS 关联ASSOCIATION 定义的。方括号 [ ] 是语法的一部分。对于 min 和 max,可以指定正整数(包括 0)和星号 (*):
最大值不能为 0。
最大的星号 * 表示任意数量的行。
min 可以省略(如果省略则设置为 0)。
min 不能是 *。
当在 WHERE 条件中使用 CDS 关联时,必须为最大值指定 1。
如果未明确定义基数,则隐式使用基数为一 ([min..1])。
指定基数以记录数据模型的语义,并且在某些数据库系统中用于优化。
在这些数据库系统中,如果使用显式或隐式“to 1”基数,则由路径表达式生成的左外连接 (LEFT OUTER JOIN) 将被赋予 TO ONE,
如果使用任何其他基数,则将赋予 TO MANY。这些添加的工作方式与在 LEFT OUTER JOIN 中明确指定时的工作方式相同。
这意味着尝试优化并且如果结果集与基数不匹配,则结果可能是未定义的。
例一:
define root view entity zxtrap_cds_ekko
as select from zxtrap_ekko as ekko
association [0..*] to zxtrap_cds_ekpo as _ekpo on ekko.ebeln = _ekpo.ebeln
// association [0..*] to zxtrap_cds_ekpo as _ekpo on $projection.ebeln = _ekpo.ebeln
{
key ebeln,
bukrs,
statu,
waers,
bedat,
kdatb,
kdate,
_ekpo
}
CDS视图可以将关联名称本身放在其元素列表中,而不是访问关联数据源的各个字段。
然后,将关联暴露给CDS视图的使用者,该消费者可以是另一个CDS视图或ABAP Open SQL语句。视图的使用者可以完全访问关联数据源的所有组件。
公开关联有一个先决条件:关联条件字段必须是元素列表一部分
如果将基数设置为[0..1]系统会提示警告
association [0..1] to zxtrap_cds_ekpo as _ekpo on ekko.ebeln = _ekpo.ebeln
在元素列表中使用
define root view entity zxtrap_cds_ekko
as select from zxtrap_ekko as ekko
association [0..*] to zxtrap_cds_ekpo as _ekpo on ekko.ebeln = _ekpo.ebeln
{
key ebeln,
bukrs,
statu,
waers,
bedat,
kdatb,
kdate,
_ekpo.matnr
}
with default filter
define root view entity zxtrap_cds_ekko
as select from zxtrap_ekko as ekko
association [0..*] to zxtrap_cds_ekpo as _ekpo on ekko.ebeln = _ekpo.ebeln
with default filter _ekpo.menge <> 0
{
key ebeln,
bukrs,
statu,
waers,
bedat,
kdatb,
kdate,
_ekpo
}
2-3.定义父子关系
例一:
define view entity ZXTRAP_CDS_EKPO2
as select from zxtrap_ekpo2
association to parent zxtrap_cds_ekko as _ekko on $projection.ebeln = _ekko.ebeln
{
key ebeln,
key ebelp,
bukrs,
matnr,
meins,
@Semantics.quantity.unitOfMeasure : 'meins'
menge,
waers,
@Semantics.amount.currencyCode : 'waers'
netwr,
_ekko
}
define root view entity zxtrap_cds_ekko
as select from zxtrap_ekko as ekko
association [0..*] to zxtrap_cds_ekpo as _ekpo on ekko.ebeln = _ekpo.ebeln
composition [0..*] of ZXTRAP_CDS_EKPO2 as _ekpo2
{
key ebeln,
bukrs,
statu,
waers,
bedat,
kdatb,
kdate,
_ekpo,
_ekpo2
}
2-4. 条件
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'test ekpo'
@Metadata.ignorePropagatedAnnotations: true
@ObjectModel.usageType:{
serviceQuality: #X,
sizeCategory: #S,
dataClass: #MIXED
}
define view entity zxtrap_cds_ekpo
as select from zxtrap_ekpo
{
key ebeln,
//key ebelp,
// bukrs,
// matnr,
// meins,
// @Semantics.quantity.unitOfMeasure : 'meins'
// menge,
waers,
@Semantics.amount.currencyCode : 'waers'
// netwr
sum(netwr) as netwr
}
where ebeln is not initial
and ebelp is not initial
group by ebeln,
waers
having ebeln <> ''
2-5. 表达式
CDS中也支持各种表达式如:
算数表达式
... [-]operand1 [+|-|*|/ [-]operand2 [+|-|*|/ [-]operand3 ... ]] …
聚合表达式
... { MAX( [ALL|DISTINCT] operand )
| MIN( [ALL|DISTINCT] operand )
| AVG( [ALL|DISTINCT] operand AS dtype )
| SUM( [ALL|DISTINCT] operand )
| COUNT( DISTINCT operand )
| COUNT(*) } ...
MIN( operand ):
返回操作数中的最小值
MAX( operand )
返回操作数的最大值。
SUM( operand )
计算操作数的值之和
AVG( operand )
计算操作数的平均值
COUNT( *)
返回结果集中的条目数
COUNT( DISTINCT operand )
返回操作数的不同值的数量
条件表达式
例一:
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'test ekpo'
@Metadata.ignorePropagatedAnnotations: true
@ObjectModel.usageType:{
serviceQuality: #X,
sizeCategory: #S,
dataClass: #MIXED
}
define view entity zxtrap_cds_ekpo
as select from zxtrap_ekpo
{
key ebeln,
// key ebelp,
// bukrs,
// matnr,
// meins,
// @Semantics.quantity.unitOfMeasure : 'meins'
// menge,
waers,
// @Semantics.amount.currencyCode : 'waers'
// netwr,
@Semantics.amount.currencyCode : 'waers'
sum(netwr) as netwr,
@Semantics.amount.currencyCode : 'waers'
max(netwr) as max_netwr,
@Semantics.amount.currencyCode : 'waers'
min(netwr) as min_netwr,
count(*) as col_count,
case when sum(netwr) > min(netwr) then 1 else 0 end as col_case
}
group by
ebeln,
waers
2-6. 函数
CDS中的计量单位转换
unit_conversion
CDS视图中的货币换算
CURRENCY_CONVERSION
define view entity zxtrap_cds_ekpo
as select from zxtrap_ekpo
{
key ebeln,
key ebelp,
bukrs,
matnr,
meins,
@Semantics.quantity.unitOfMeasure : 'meins'
menge,
waers,
@Semantics.amount.currencyCode : 'waers'
netwr,
@Semantics.quantity.unitOfMeasure: 'target_distid'
unit_conversion(quantity => menge,
source_unit => meins,
target_unit => cast('G' as abap.unit)) as target_tance,
cast('G' as abap.unit) as target_distid,
@Semantics.amount.currencyCode : 'target_CUKY'
CURRENCY_CONVERSION(
amount => netwr,
source_currency => waers,
target_currency => cast('USD' as abap.cuky),
exchange_rate_type => 'M',
exchange_rate_date => '20220105'
) as trg_netwr,
cast('USD' as abap.cuky) as target_CUKY
}
CDS视图中的字符串函数
1.字符串处理的一些内置函数
1.1.concat(arg1,arg2)
连接两个字符串的函数,
返回CHAR或STRING类型的结果(取决于arg1,arg2的类型)
删除所有尾随的空白
对应于ABAP语句CONCATENATE,无需添加SEPARATED BY
例
1.2.replace(arg1, arg2, arg3)
字符串替换,
结果类型取决于arg1的类型
对应于ABAP语句,用arg3替换arg1中的arg2的所有匹配项。
例:
1.3.substring(arg,pos,len)
返回字符串arg从,第pos位开始,取len长度的字符串。
结果类型取决于arg的类型
类似于ABAP函数substring()或直接子字符串访问
重要区别:pos表示位置,而不是偏移量!
例:
2.字符串处理的某些内置函数(NW 7.50)
2.1.concat_with_space(arg1,arg2,count)
连接字符串门arg1,arg2,并中中间加入count个空格。
与concat()类似,但在arg1和arg2之间具有计数空间
类似于ABAP语句CONCATENATE,添加了SEPARATED BY
例
2.2.length(arg)
在CDS中得到字符串长度
返回类型为INT4的结果
尾随空格不计算
对应于ABAP内置函数numofchar()
2.3.left(arg,n) and right(arg,n)
取字符串arg的右边(左边)N位长度的字符串
与substring()类似,但返回arg的前n个或后n个字符
left()对应于ABAP表达式arg(n)
CDS视图中的算术函数
在CDS中,可以使用一些计算函数来进行计算,同时还能使用CASE来进行分类处理,ABAP CDS提供了以下这些内置函数来进行处理。
1.div(arg1,arg2)
取除法的模值。
仅输入整数值
(INT1,INT2,INT4,INT8或DEC,CURR,QUAN,小数= 0)
结果类型:arg1类型
结果总是四舍五入为整数值
2.mod(arg1,arg2)
取ARG1除以ARG2的余数。
输入:仅整数类型(INT1,INT2,INT4,INT8)
结果类型:arg1类型
结果可能为负。
3.division(arg1,arg2,dec)
取arg1除以arg2的值,并保留DEC位的小数位数
输入:整数值,带固定小数的值
(类型INT1,INT2,INT4,INTS和DEC,CURR,QUAN,带任意小数位数)
结果类型:带小数点后十进制的DEC,长度取决于arg1的类型
结果总是四舍五入到小数
函数div()和division()之间的主要区别如下:输入:
Div()仅允许输入整数值。Division()仅排除浮点数(二进制或十进制)。
结果:
Div()始终返回整数值作为结果。Division()可让您指定结果的精度。
注意:
关于符号,函数div()和mod()与ABAP运算符DIV和MOD的行为不同。在SQL函数div()中,对参数的数量进行除法然后分配符号(如果参数具有相同的符号,如果符号不同则为负)。因此,MOD的结果可能为负。另一方面,ABAP运算符MOD仅产生正面结果。
4.abs(arg)
返回arg的绝对值,
即总是四舍五入
5.floor(arg)
舍入到下一个较低的整数
即,如果arg> 0,则趋于零;如果arg <0,则远离零
例:
楼层(1.5)= 1
地板(-1.5)=-2
6.ceil(arg)
舍入到下一个更高的整数
即,如果arg> 0,则远离零;如果arg <0,则远离零
例:
ceil(1.5)= 2
ceil(-1.5)=-1
6.1.1.round(arg,pos)
pos> 0:将arg舍入到pos小数位
pos <0:将arg舍入到位置
例:
回合(3.154,2)= 3.15
回合(273.15,-1)= 270
define view entity zxtrap_cds_ekpo
as select from zxtrap_ekpo
{
....
div(10,3) as ZDIV,
mod(10,3) as Zmod,
division(10,3,3) as zdivision,
abs(1.5) as zabs1,
abs(-1.5) as zabs2
}
CDS中的日期函数
在CDS中可以对日期进行计算,增加,减少等操作,以下说明CDS中的日期相关的函数的运用.
1.带日期的计算:
作为ABAP开发人员,我们习惯于使用DATE类型的数据对象进行计算:从另一个日期字段中减去一个日期字段以计算它们之间的天数,或向日期字段添加一个整数值以计算该日期将来的某几天。因为ABAP会自动将D类型的值转换为整数值。数据库级别不存在类似的机制。为此,日期字段无法识别为日期字段。通常,数据库将它们创建为长度为8的普通字符字段。在算术表达式中使用这些字符字段将导致语法错误,而使用CAST进行类型转换将导致错误的结果。
2.dats_is_valid
判断字符串,是不是为有效日期
返回类型为INT4的结果
如果日期包含有效日期,则返回1,否则返回0
3.dats_days_between(date1,date2)
返回类型为INT4的结果
计算两个日期之间的天数(对应于ABAP中的date2 – date1)
4.dats_add_days(date,count,on_error)
返回类型为DATS的结果
将计数天添加到给定日期(对应于日期+ ABAP中的计数)
5.dats_add_months(date,count,on_error)
返回类型为DATS的结果
将计数月份添加到给定的日期(ABAP中没有simpe等效项)
6.一般说明:
所有日期均为YYYYMMDD格式(数据库上的技术格式)
on_error的可能值:“ FAIL”,“ NULL”,INITIAL,“ UNCHANGED”
为了用日期进行计算,从NW 7.5.0开始,CDS中提供了四个内置函数。
例:
define root view entity zxtrap_cds_ekko
as select from zxtrap_ekko as ekko
association [0..*] to zxtrap_cds_ekpo as _ekpo on ekko.ebeln = _ekpo.ebeln
// with default filter _ekpo.menge <> 0
association [0..1] to zxtrapt001 as _t001 on $projection.bukrs = _t001.bukrs
composition [0..*] of ZXTRAP_CDS_EKPO2 as _ekpo2
{
key ebeln,
bukrs,
statu,
waers,
bedat,
kdatb,
kdate,
_ekpo,
_ekpo2,
_t001,
dats_is_valid(ekko.bedat) as BLDAT_V, //判断字符串,是不是为有效日期
dats_days_between(ekko.kdate , ekko.kdatb) as DAYS1, //计算两个日期之间的天数
dats_add_days(ekko.kdate ,10,'FAIL') as JD10, //将计数天添加到给定日期
dats_add_months(ekko.kdate ,10,'FAIL') as JY10 //将计数月份添加到给定的日期
}
投影的定义
例一:
@EndUserText.label: 'the projection of ekko'
@AccessControl.authorizationCheck: #CHECK
define root view entity zcxtrap_cds_ekko
as projection on zxtrap_cds_ekko as _ekko
{
key ebeln,
bukrs,
_t001.butxt,
statu,
bedat,
kdatb,
kdate,
/* Associations */
_ekpo,
_ekpo2
}
CDS SDL - 定义SERVICE
@EndUserText.label: 'service definition'
define service Zui_c_xtrap02 {
expose zcxtrap_cds_ekko as Testapp;
expose zxtrap_cds_ekpo as ekpo;
expose ZXTRAP_CDS_EKPO2 as ekpo2;
}