一、CDS View是什么
CDS View = S/4HANA 时代的 “增强版视图” + 语义模型 + 注解驱动 + 性能下推到 HANA。替代传统 SE11 数据库视图,是 Fiori、OData、RAP、嵌入式分析 的底层数据模型,深度集成了业务语义、访问控制和数据消费能力
核心概念与理解
-
定义:ABAP CDS View 是定义在 ABAP 服务器上的第一等数据模型对象。它在 ABAP 数据字典中创建,激活时会自动在数据库中生成一个对应的 SQL 视图。
-
核心理念:Code Pushdown:它将复杂的数据处理逻辑(如连接、聚合、计算)从 ABAP 应用层“下推”到数据库层执行,减少数据传输,充分利用了 SAP HANA 等数据库的性能优势。
使用场景
-
Fiori 应用/ OData 服务生成:通过
@OData.publish: true注解,可直接将 CDS View 发布为 OData 服务,供 Fiori 应用高效消费。 -
在 ABAP 程序中消费:可直接在
SELECT语句的FROM子句中使用 CDS View,如同使用数据库表一样。 -
数据提取与分析:通过
@Analytics.dataExtraction.enabled: true注解,适合作为数据源提供给 SAP BW/4HANA 或 SAP Analytics Cloud 等分析系统
核心优势(对比 SE11 视图)
- 注解(@):UI、权限、OData、标签全部写在模型里
- 关联(Association):JOIN 可复用,支持导航
- 计算字段 / 聚合 / 参数:比 SE11 强太多
- 性能极高:逻辑下推 HANA,避免 ABAP 层循环
- 直接发布 OData:一行注解暴露服务
二、CDS View 三层架构
- 基础视图(I_xxx) :只做表关联、字段映射、计算 → 对内
- 组合视图(P_xxx):过滤、聚合、业务逻辑 → 对内
- 消费视图(C_xxx):注解、UI、权限、OData → 对外给 Fiori/OData
三、CDS DEMO
开发环境:
- 安装 Eclipse IDE 并配置 ABAP Development Tools (ADT) 插件,安装参考:ADT安装和CDS View入门
-
确保可访问 ABAP NetWeaver 7.4 以上或 SAP BTP ABAP 环境。
1. 基础视图(ZI_DEMO)– 只做表关联、字段映射、计算
@AbapCatalog.sqlViewName: 'ZKJ_CSD_01'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Base View'
@Metadata.ignorePropagatedAnnotations: true
define view ZCDS_DEME_01 as select from sflight inner join scarr on sflight.carrid = scarr.carrid
{
// 主键
key sflight.carrid,
key sflight.connid,
// 原始字段
scarr.carrname,
sflight.seatsmax,
sflight.seatsocc
}
激活后可以在SAP GUI使用SE16N事务代码查看CDS View,名称为'ZKJ_CSD_01'(取决于注解的自定义的名称)

可以看到通过CDS View进行查询的时候会出来一个有数据的视图,数据来源是通过CDS View封装好的SQL逻辑从SFLIGHT物理表和SCARR物理表取数,CDS View底层本质是封装好的一条 SQL 查询+注解、关联、分层建模、能给前端直接用的高级业务视图。
那创建好的ABAP CDS View 是如何被消费的呢?我们以SAP GUI的Report为例:
CDS View:
@AbapCatalog.sqlViewName: 'ZI_DEMO_01'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'test'
@Metadata.ignorePropagatedAnnotations: true
define view ZI_DEMO_VIEW_01 as select from sflight as f
join scarr as c on f.carrid = c.carrid
{
f.carrid,
f.connid,
c.carrname,
f.seatsmax - f.seatsocc as seats_avail // CDS 计算字段
}
SAP GUI ABAP代码:
SELECT * INTO TABLE @DATA(lt_cds_entity) FROM zi_demo_view_01.
cl_salv_table=>factory( IMPORTING r_salv_table = DATA(gr_table) CHANGING t_table = lt_cds_entity ).
gr_table->display( ).
运行效果:

2. 带参数视图(ZP_DEMO)– 过滤 + 参数
带参数 CDS 视图 = 留好过滤入口,调用时再给条件,动态查数据。
CDS VIEW:
@AbapCatalog.sqlViewName: 'ZP_DEMO'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'TEST'
@Metadata.ignorePropagatedAnnotations: true
define view ZP_DEMO_VIEW
with parameters
P_FROM : abap.dats, // 输入开始日期
P_TO : abap.dats // 输入结束日期
as select from sflight
{
key carrid,
key connid,
key fldate,
seatsmax,
seatsocc
}
where fldate between $parameters.P_FROM and $parameters.P_TO
SAP GUI ABAP 代码:
DATA: lt_data TYPE TABLE OF zp_demo.
START-OF-SELECTION.
" 🔥 正确调用带参数CDS
SELECT * FROM zp_demo( p_from = '20250510', p_to = '20250513' )
INTO CORRESPONDING FIELDS OF TABLE @lt_data.
LOOP AT lt_data INTO DATA(ls).
WRITE: / ls-carrid, ls-connid, ls-fldate.
ENDLOOP.
运行结果:

3.消费视图(UI5+ODATA)
通过注解@OData.publish: true发布OData Service 给 Fiori调用
CDS VIEW:
@AbapCatalog.sqlViewName: 'ZI_SO'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Get SO'
@Metadata.ignorePropagatedAnnotations: true
@OData.publish: true
define view ZI_SO_VIEW as select from vbak
{
key vbeln as Vbeln,
erdat as Erdat,
erzet as Erzet,
ernam as Ernam,
vkorg as Vkorg,
vkgrp as Vkgrp
}
Fiori运行效果:

四、核心语法详解
1. 注解(@)– CDS 灵魂
@EndUserText.label: '自定义标签' // 字段/视图显示名
@OData.publish: true // 发布OData V4
@UI.lineItem: true // Fiori列表显示
@AccessControl.authorizationCheck: #REQUIRED // 权限控制
@Consumption.filter.mandatory: true // 必输过滤条件
CDS View(常用) 注解功能附表:
| 注解名称 | 主要作用与应用场景 | 注解示例 |
|---|---|---|
@OData.publish | 将 CDS View 一键发布为 OData v4 服务,供 Fiori 应用直接消费 | @OData.publish: true |
@UI | 为 Fiori Elements 提供 UI 渲染指令(列表报表、筛选字段、详情页布局) | @UI.lineItem: [{position: 10, label: '订单号'}] |
@ObjectModel | 为 OData / RAP 服务定义行为语义(只读、创建启用、关联实体类型) | @ObjectModel.readOnly: true |
@Semantics | 标记字段的业务类型(货币、金额、日期、时间、单位等),确保前端/OData正确解析 | @Semantics.amount.currencyCode: 'Currency' |
@AccessControl.authorizationCheck | 激活权限控制(结合 DCL),SELECT 时自动过滤无权限的行 | @AccessControl.authorizationCheck: #CHECK |
@ClientHandling.type | 控制多客户端行为(按当前客户端过滤、跨客户端查询、忽略客户端字段) | @ClientHandling.type: #CLIENT_DEPENDENT |
@AbapCatalog.sqlViewName | 传统 CDS View 必备:指定底层 SQL 视图名(最多 16 字符) | @AbapCatalog.sqlViewName: 'ZSQL_MYVIEW' |
@AbapCatalog.compiler.compareFilter | 性能优化:避免关联中筛选条件被重复评估 | @AbapCatalog.compiler.compareFilter: true |
@EndUserText.label | 为视图提供面向最终用户的描述文本(推荐所有视图都加) | @EndUserText.label: '销售订单分析视图' |
注:若使用现代 CDS View Entity(
DEFINE VIEW ENTITY),则无需@AbapCatalog.sqlViewName
2. 关联(Association)– 替代 JOIN 并可复用
简单来说,CDS Association 是一种在 Core Data Services (CDS) 中声明并复用两个实体(表或视图)关系的机制。它像一段“关系代码”被嵌入源实体中,为数据的关联查询带来了更强的灵活性、可读性与性能优化潜力,只有你真正用到关联表的字段时,系统才自动关联查询,性能更好、更灵活。
Association的核心是在 SELECT 语句后,使用 ASSOCIATION 关键字定义一段关系,它包含了目标实体、关联名称、关联基数和连接条件。基本语法如下:
ASSOCIATION [min..max] TO target_cds_view AS _assoc_name ON $projection.source_field = _assoc_name.target_field
各部分解释如下:
| 组成部分 | 含义 | 说明 |
|---|---|---|
ASSOCIATION [min..max] | 关联基数 | 用于定义两个实体间关系的类型,代码中的“智能指针”。 |
TO target_cds_view | 目标实体 | 声明此Association要连接到的目标CDS视图或数据库表。 |
AS _assoc_name | 关联名称 | 给这个Association起一个别名,以便在后续查询中引用。 |
ON condition | 连接条件 | 定义源实体和目标实体如何连接的字段匹配规则,类似于SQL中的ON条件。 |
补充说明:关联基数 [min..max] 并不是一个严格的数据库约束,它更像一种“语义提示”或“元数据”。例如:
-
[1..1]: “一个订单必须有且只有一个客户”。 -
[0..*]: “一个客户可以有零个、一个或多个订单”。该基数并不控制最终SQL生成的连接类型是INNER还是OUTER,在设计数据模型时主要用于表达业务关
Association 和 JOIN的区别
- JOIN:不管用不用,都强行关联,性能差
- Association:用到才关联,不用不关联,性能高
创建 EKPO + MAKT 的视图:
define view ZEKPO_WITH_MAKT
as select from ekpo
association [0..1] to makt as _makt
on ekpo.matnr = _makt.matnr
and _makt.spras = $session.system_language
{
key ekpo.ebeln as Ebeln,
key ekpo.ebelp as Ebelp,
ekpo.matnr as Matnr,
ekpo.menge as Menge,
ekpo.meins as Meins,
_makt.maktx as Maktx
}
数据预览:

创建 EKKO + 上方CDS VIEW的视图:
@AbapCatalog.sqlViewName: 'ZEKKO_EKPO_TEST'
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: '采购订单抬头 + 行项目(含物料描述)'
define view ZEKKO_WITH_ITEMS
as select from ekko
association [0..*] to ZEKPO_WITH_MAKT as _items
on ekko.ebeln = _items.Ebeln
{
key ekko.ebeln as Ebeln,
ekko.bsart as Bsart,
ekko.bukrs as Bukrs,
ekko.lifnr as Lifnr,
_items.Ebelp as ItemNo,
_items.Matnr as Material,
_items.Menge as Quantity,
_items.Maktx as MaterialDesc
}
数据预览:

3. 计算字段 & 函数
示例1:算术运算(计算剩余座位)
@AbapCatalog.sqlViewName: 'ZFLTSEAT'
@AccessControl.authorizationCheck: #NOT_REQUIRED
@AbapCatalog.preserveKey: true
@EndUserText.label: '航班座位占用情况'
define view ZFLIGHT_SEATS
as select from sflight
{
key carrid as Airline,
key fldate as FlightDate,
seatsmax as TotalSeats,
seatsocc as OccupiedSeats,
seatsmax - seatsocc as AvailableSeats // 算术运算
}
示例2:类型转换(货币字段规范化)
@AbapCatalog.sqlViewName: 'ZFLTPRICE'
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: '航班价格(格式化)'
define view ZFLIGHT_PRICE
as select from sflight
{
key carrid,
key connid,
key fldate,
// 将价格字段转换为 15 位总长、2 位小数的货币类型
cast( price as abap.curr(15,2) ) as FormattedPrice
}
示例3:字符串处理(拼接、截取)
@AbapCatalog.sqlViewName: 'ZFLTSTR'
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: '航班字符串处理'
define view ZFLIGHT_STRING
as select from spfli
inner join scarr on spfli.carrid = scarr.carrid
{
key spfli.carrid,
key spfli.connid,
// 拼接:航空公司代码 + 航班号
concat( spfli.carrid, spfli.connid ) as FlightId,
// 截取:只取航空公司名称的前 10 个字符
substring( scarr.carrname, 1, 10 ) as AirlineShort
}
示例4:字符串处理(拼接、截取)
@AbapCatalog.sqlViewName: 'ZFLTAGG'
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: '航班聚合统计'
define view ZFLIGHT_AGGREGATE
as select from sflight
{
key carrid,
key connid,
sum( price ) as TotalRevenue, // 总和
count( * ) as FlightCount, // 所有行计数(包含 NULL)
count( fldate ) as FlightDateCount, // 仅非空计数
avg( price ) as AvgPrice // 平均价格(可选)
}
group by carrid, connid
关键说明:
| 操作类别 | 关键函数/语法 | 说明 |
|---|---|---|
| 算术 | + - * / | 字段间直接计算,如 seatsmax - seatsocc |
| 类型转换 | cast( ... as abap.curr(p,s) ) | 也可转换为 abap.dec(p,s)、abap.int4 等 |
| 字符串 | concat( a, b ) | 拼接,等价于 a || b(HANA 风格) |
| 字符串 | substring( str, start, length ) | 截取子串,start 从 1 开始 |
| 聚合 | sum(), count(), avg(), min(), max() | 必须配合 group by 使用非聚合的 key 字段 |
总结
CDS View 是 SAP 现代化的数据建模利器,它用关联导航取代笨重的 JOIN,把计算逻辑和数据关系推给数据库,从而让 ABAP 开发更简洁、更高效。
4258

被折叠的 条评论
为什么被折叠?



