4. CDS视图核心语法与数据源
CDS(Core Data Services)视图的建模能力,本质上由三部分构成:数据源决定“从哪里取数”,SELECT语句结构决定“取哪些列、如何过滤与聚合”,注解决定“这个视图在ABAP运行时和SAP Fiori中如何被识别与消费”。本节围绕这三点展开,重点讲清关联(Association)、联合(Union)、参数(Parameter)与输入参数(Input Parameter)的语法差异和适用场景。
一、数据源与SELECT列表
CDS视图的 define view 后面紧跟视图名,as select from 指定主数据源。数据源可以是数据库表、其他CDS视图,也可以是带参数的CDS视图。SELECT列表中的字段必须显式命名,若字段来自表达式或函数,必须用 as 指定别名,否则激活时会报“缺少列名”错误。
@AbapCatalog.sqlViewName: 'ZCDS_SALES_01'
@AccessControl.authorizationCheck: #NOT_REQUIRED
define view ZCDS_SalesOrder
as select from vbak as so
{
key so.vbeln as SalesOrder,
so.erdat as CreatedDate,
so.netwr as NetValue,
so.waerk as Currency
}
where so.vbtyp = 'C'
这里 @AbapCatalog.sqlViewName 是必须注解,它决定底层生成的数据库视图名;@AccessControl.authorizationCheck 控制权限检查行为。SELECT列表中的 key 用于标识视图主键,多个key字段共同构成复合主键。
二、关联(Association)
关联不是JOIN,它描述的是“实体之间的语义关系”,只有在路径被实际访问时才生成JOIN。语法为 association [0..1] to Target as _Alias on 条件。基数 [0..1]、[1..1]、[0..*] 表达目标端匹配数量,直接影响运行时是否允许空值。
define view ZCDS_SalesWithCustomer
as select from vbak as so
association [0..1] to kna1 as _Customer
on $projection.Customer = _Customer.kunnr
{
key so.vbeln as SalesOrder,
so.kunnr as Customer,
_Customer.name1 as CustomerName
}
关联的优势在于:同一视图可被多个上层视图复用,且路径 _Customer.name1 只在被选中时才展开为LEFT OUTER JOIN。若需强制内连接,可在路径后加 inner join 关键字。关联还支持在 where 中通过 _Customer.land1 = 'CN' 过滤,但要注意这会隐式改变连接语义。
三、联合(Union)
当需要把结构相同、来源不同的结果集合并时使用 union。CDS中union要求各分支列数、类型、顺序一致,且只能有一个 key 定义在第一个分支上。默认 union 去重,union all 保留重复行。
define view ZCDS_AllDocs
as select from vbak as a
{
key a.vbeln as DocNo,
a.erdat as DocDate,
'SO' as DocType
}
union all
select from likp as b
{
key b.vbeln as DocNo,
b.erdat as DocDate,
'DL' as DocType
}
实际建模中,union常用于合并销售订单与交货单、合并不同公司代码的同类数据。注意union分支中不能直接使用参数,若需参数化,应把参数放在外层视图或使用 where 在分支内引用参数。
四、参数与输入参数
CDS参数分为两类:输入参数(Input Parameter)和普通参数(Parameter)。输入参数用 with parameters 声明,在视图体内通过 :参数名 引用,常用于 where 过滤;普通参数用 with parameters 声明但不带冒号引用,通常用于传递常量或作为计算因子。
define view ZCDS_SalesByDate
with parameters
p_date_from : dats,
p_date_to : dats
as select from vbak as so
{
key so.vbeln as SalesOrder,
so.erdat as CreatedDate,
so.netwr as NetValue
}
where so.erdat between :p_date_from and :p_date_to
调用时通过 ZCDS_SalesByDate(p_date_from = '20240101', p_date_to = '20241231') 传入。输入参数在ABAP CDS中会生成对应的方法参数,在Fiori应用中可绑定为筛选条件。若参数用于 case when 或计算表达式,需注意类型转换,例如 cast(:p_rate as abap.dec(5,2))。
五、基本注解
注解以 @ 开头,写在视图或字段上方。常用注解包括:@AbapCatalog.sqlViewName(必填)、@AccessControl.authorizationCheck(权限检查)、@EndUserText.label(描述文本)、@Semantics.amount.currencyCode(金额与币种关联)、@Semantics.quantity.unitOfMeasure(数量与单位关联)、@UI.lineItem 与 @UI.identification(Fiori列表与详情页字段)。
其中 @Semantics 系列注解直接影响Fiori应用的金额、数量显示格式,若缺失会导致前端无法正确格式化。例如金额字段必须同时标注 @Semantics.amount.currencyCode: 'Currency',并确保Currency字段存在于同一视图中。
六、语法选择与常见陷阱
关联与JOIN的选择:若目标实体是主数据(如客户、物料),且上层视图可能只取部分字段,优先用关联;若需要聚合后再连接,或连接条件复杂且必须立即生效,用JOIN更直接。union与关联不可混用在同一层级,union分支内不能直接引用外层参数。
参数与输入参数的区别:输入参数在ABAP端生成方法参数,可被Fiori筛选器绑定;普通参数通常用于传递常量,不参与运行时筛选。若在 where 中使用 :p_date,必须确保参数类型与字段类型一致,否则激活时报类型不匹配。
@AbapCatalog.sqlViewName;② SELECT列表表达式未指定别名;③ union分支列数或类型不一致;④ 关联的 on 条件中引用了未在SELECT列表中出现的字段;⑤ 金额字段缺少 @Semantics.amount.currencyCode 导致Fiori显示异常。
掌握以上语法后,CDS视图的建模能力就从“单表取数”扩展到“多实体语义关联、多源合并、参数化查询与前端语义标注”。实际项目中,建议先确定数据源与主键,再决定用关联还是JOIN,最后补充注解与参数,这样激活成功率和可维护性都更高。