CDS(Core Data Service)是 SAP 推出的核心数据服务,是一种基于 SQL 的数据建模语言,用于在数据库层定义语义丰富的数据模型。CDS 不仅仅是一个视图定义,它提供了:
语义层:在数据库层添加业务语义
性能优化:计算下沉到数据库层执行
代码复用:定义一次,多处使用
权限控制:集成数据访问控制(DCL)
元数据丰富:通过注解(Annotation)添加业务属性
CDS View 核心优势
1. 性能优化 - 计算下沉
聚合、过滤、关联等操作在数据库层执行
减少应用层与数据库层的数据传输
HANA 列式存储天然适合大规模计算
2. 按需加载 - Association
传统 JOIN 立即加载所有关联表
CDS Association 按需触发,只在访问时才连接
多表关联时性能提升显著
3. 代码复用 - 定义一次多处使用
视图可被其他 CDS View 引用
减少重复代码
便于维护和修改
4. 语义丰富 - 注解机制
添加业务语义(UI、搜索、权限)
集成 Fiori Elements 自动化 UI
支持 OData 服务自动生成
5. 权限控制 - DCL
行级别权限控制
与 SAP 权限对象集成
数据安全性保障
6. 参数化支持
动态传入参数
提高查询灵活性
减少视图数量
7. 标准化 - SAP 官方推荐
S/4HANA 标准基于 CDS 构建
新功能优先支持 CDS
未来发展方向
CDS View vs 传统 View
特性
CDS View
传统 View(SE11)
定义方式
DDL 源代码
图形化界面
存储位置
ABAP Dictionary
ABAP Dictionary
关联方式
Association(按需)
Join(立即)
参数支持
✓
✗
聚合函数
✓
有限
权限控制
DCL
有限
注解支持
✓
✗
计算下沉
✓
✗
性能
优
一般
复用性
高
低
实际应用场景
报表取数优化
Fiori 应用数据层
CDS View 的两种语法
1. CDS View (经典语法)
@AbapCatalog.sqlViewName: 'ZSALES_SQL' define view Z_SALES_ORDER as select from vbak { key vbeln, erdat, netwr }
2. CDS View Entity (新语法,推荐)
define view entity Z_SALES_ORDER as select from vbak { key vbeln, erdat, netwr }
新语法优势:
不需要 @AbapCatalog.sqlViewName 注解
不在数据库中创建 SQL View
支持更多新特性
性能更好
新语法优势:
不需要 @AbapCatalog.sqlViewName 注解
不在数据库中创建 SQL View
支持更多新特性
性能更好
CDS 基础语法
SELECT 语句
基本查询
define view entity Z_MATERIAL_LIST as select from mara { key matnr, " 物料号 maktx, " 物料描述 mtart, " 物料类型 matkl, " 物料组 meins " 基本单位 }
指定字段别名
define view entity Z_MATERIAL_LIST as select from mara { key matnr as Material, maktx as Description, mtart as MaterialType, matkl as MaterialGroup, meins as BaseUnit }
使用表别名
define view entity Z_SALES_DETAIL as select from vbak as h " 头表 inner join vbap as i " 行项目 on h.vbeln = i.vbeln { key h.vbeln as SalesOrder, key i.posnr as Item, h.erdat as CreatedOn, i.matnr as Material, i.netwr as NetValue }
WHERE 条件
基本条件
define view entity Z_ACTIVE_MATERIALS as select from mara { key matnr, maktx, mtart } where lvorm = ' ' " 未删除 and mtart = 'FERT' " 成品
参数化条件
define view entity Z_MATERIAL_BY_TYPE with parameters p_matnr : matnr, p_mtart : mtart as select from mara { key matnr, maktx, mtart } where matnr = $parameters.p_matnr and mtart = $parameters.p_mtart
使用输入参数
define view entity Z_ORDERS_BY_DATE with parameters p_date_from : sydatum, p_date_to : sydatum as select from vbak { key vbeln, erdat, netwr } where erdat >= $parameters.p_date_from and erdat <= $parameters.p_date_to
KEY 字段声明
单主键
define view entity Z_MATERIAL_KEY as select from mara { key matnr, " 主键 maktx, mtart }
@AbapCatalog.sqlViewName: 'ZMATERIAL_SQL' @AbapCatalog.preserveKey: true define view Z_MATERIAL_KEY as select from mara { key matnr, maktx }
preserveKey: true:SQL View 使用 CDS 定义的 Key
preserveKey: false:SQL View 使用数据库表的 Key
CDS 关联(ASSOCIATION)
ASSOCIATION 概述
ASSOCIATION 是 CDS 的核心特性之一,它定义了视图之间的关联关系。与传统 JOIN 不同,ASSOCIATION 是按需加载的,只有在访问关联数据时才会执行数据库连接。
优势
性能优化:避免不必要的表连接
代码简洁:定义一次,多处使用
语义清晰:明确表达业务关系
灵活访问:支持延迟加载
基本语法
定义 ASSOCIATION
define view entity Z_SALES_WITH_MATERIAL as select from vbak as h association [1..1] to vbap as _Items on h.vbeln = _Items.vbeln { key h.vbeln as SalesOrder, h.erdat as CreatedOn, _Items.posnr as Item, _Items.matnr as Material, _Items.netwr as NetValue }
关联基数
基数
含义
使用场景
[0..1]
最多关联一个
可选关联
[1..1]
只能一一对应
必须关联
[0..n]
关联任意数量
可选一对多
[1..n]
至少关联一个
必须一对多
示例:订单与行项目
define view entity Z_ORDER_WITH_ITEMS as select from vbak as _Order association [1..*] to vbap as _Items on _Order.vbeln = _Items.vbeln { key _Order.vbeln as OrderNumber, _Order.erdat as CreatedOn, _Order.netwr as OrderValue, _Items.posnr as ItemNumber, _Items.matnr as Material, _Items.kwmeng as Quantity }
define view entity Z_SALES_REPORT as select from Z_SALES_WITH_MATERIAL as _Sales { key _Sales.SalesOrder, _Sales.CreatedOn, _Sales._Items.Material, " 访问关联 _Sales._Items.NetValue }
多表关联
三层关联示例
define view entity Z_COMPLETE_SALES as select from vbak as _Order association [1..1] to kna1 as _Customer on _Order.kunnr = _Customer.kunnr association [1..*] to vbap as _Items on _Order.vbeln = _Items.vbeln association [0..1] to mara as _Material on _Items.matnr = _Material.matnr { key _Order.vbeln as OrderNumber, _Order.erdat as CreatedOn, _Customer.name1 as CustomerName, _Items.posnr as Item, _Material.maktx as MaterialDesc, _Items.netwr as NetValue }
通过关联过滤
define view entity Z_SALES_BY_CUSTOMER with parameters p_kunnr : kunnr as select from vbak as _Order association [1..1] to kna1 as _Customer on _Order.kunnr = _Customer.kunnr { key _Order.vbeln, _Order.erdat, _Customer.name1 } where _Order.kunnr = $parameters.p_kunnr
Association vs Join
特性
Association
Join
加载时机
按需加载
立即加载
性能
优
一般
代码复用
高
低
灵活性
高
低
适用场景
关联表可能不被访问
必须关联所有表
CDS 内置函数
字符串函数
CONCAT - 字符串拼接
define view entity Z_STRING_CONCAT as select from mara { key matnr, concat( matnr, maktx ) as full_desc, concat( concat( matnr, ' - ' ), maktx ) as formatted_desc }
SUBSTRING - 截取子串
define view entity Z_SUBSTRING_EXAMPLE as select from mara { key matnr, substring( matnr, 1, 4 ) as prefix, " 前4位 substring( matnr, 5, 10 ) as suffix " 从第5位开始取10位 }
UPPER / LOWER - 大小写转换
define view entity Z_CASE_EXAMPLE as select from mara { key matnr, upper( maktx ) as upper_desc, lower( maktx ) as lower_desc }
LENGTH - 字符串长度
define view entity Z_LENGTH_EXAMPLE as select from mara { key matnr, length( maktx ) as desc_length }
REPLACE - 字符串替换
define view entity Z_REPLACE_EXAMPLE as select from mara { key matnr, replace( maktx, 'OLD', 'NEW' ) as replaced_desc }
数学函数
ROUND - 四舍五入
define view entity Z_ROUND_EXAMPLE as select from vbap { key vbeln, key posnr, netwr, round( netwr, 0 ) as rounded_value, " 四舍五入到整数 round( netwr, 2 ) as rounded_2dec " 四舍五入到2位小数 }
CEIL / FLOOR - 向上/向下取整
define view entity Z_CEIL_FLOOR_EXAMPLE as select from vbap { key vbeln, key posnr, netwr, ceil( netwr ) as ceil_value, " 向上取整 floor( netwr ) as floor_value " 向下取整 }
ABS - 绝对值
define view entity Z_ABS_EXAMPLE as select from bseg { key belnr, key buzei, dmbtr, shkzg, case shkzg when 'S' then dmbtr when 'H' then -dmbtr end as signed_amount, abs( dmbtr ) as absolute_amount }
日期函数
当前日期/时间
define view entity Z_DATE_EXAMPLE as select from vbak { key vbeln, erdat, $session.system_date as system_date, " 系统日期 $session.user_date as user_date " 用户日期 }
日期运算
define view entity Z_DATE_CALC as select from vbak { key vbeln, erdat, dats_add_days( erdat, 30 ) as due_date, " 加30天 dats_add_months( erdat, 3 ) as quarter_end, " 加3个月 dats_days_between( erdat, $session.system_date ) as days_open }
日期提取
define view entity Z_DATE_PARTS as select from vbak { key vbeln, erdat, year( erdat ) as order_year, month( erdat ) as order_month, day( erdat ) as order_day }
转换函数
CAST - 类型转换
define view entity Z_CAST_EXAMPLE as select from mara { key matnr, cast( matnr as char(20) ) as matnr_char, cast( brgew as abap.dec(13,2) ) as weight_dec }
类型转换函数
define view entity Z_CONVERSION_EXAMPLE as select from mara { key matnr, unit_conversion( quantity => 1, source_unit => meins, target_unit => 'KG' ) as weight_kg }
COALESCE 函数
COALESCE 用于处理 NULL 值,提供默认值:
define view entity Z_COALESCE_EXAMPLE as select from mara { key matnr, coalesce( maktx, 'No Description' ) as material_desc, coalesce( matkl, 'UNASSIGNED' ) as material_group }
嵌套 COALESCE
define view entity Z_COALESCE_NESTED as select from mara { key matnr, coalesce( maktx, coalesce( mfrpn, 'No Description' ) ) as desc_with_fallback }
CDS 聚合与分组
聚合函数
常用聚合函数
函数
说明
示例
sum()
求和
sum( netwr )
count()
计数
count( * )
avg()
平均值
avg( netwr )
min()
最小值
min( netwr )
max()
最大值
max( netwr )
示例:销售汇总
define view entity Z_SALES_SUMMARY as select from vbap { key vbeln as SalesOrder, sum( netwr ) as TotalValue, count( * ) as ItemCount, avg( netwr ) as AvgItemValue, min( netwr ) as MinItemValue, max( netwr ) as MaxItemValue } group by vbeln
示例:物料统计
define view entity Z_MATERIAL_STATS as select from mara { key mtart as MaterialType, count( * ) as MaterialCount, count( distinct matkl ) as GroupCount } group by mtart
GROUP BY 分组
单字段分组
define view entity Z_SALES_BY_YEAR as select from vbak { key year( erdat ) as SalesYear, sum( netwr ) as TotalValue, count( * ) as OrderCount } group by year( erdat )
多字段分组
define view entity Z_SALES_BY_YEAR_MONTH as select from vbak { key year( erdat ) as SalesYear, key month( erdat ) as SalesMonth, sum( netwr ) as TotalValue, count( * ) as OrderCount } group by year( erdat ), month( erdat )
HAVING 条件
define view entity Z_HIGH_VALUE_ORDERS as select from vbap { key vbeln as SalesOrder, sum( netwr ) as TotalValue } group by vbeln having sum( netwr ) > 10000
CASE 条件表达式
简单 CASE
define view entity Z_MATERIAL_TYPE_DESC as select from mara { key matnr, mtart, case mtart when 'FERT' then 'Finished Product' when 'HALB' then 'Semi-Finished' when 'ROH' then 'Raw Material' when 'HALB' then 'Trading Goods' else 'Other' end as material_type_desc }
搜索 CASE
define view entity Z_PRICE_CATEGORY as select from vbap { key vbeln, key posnr, netwr, case when netwr >= 10000 then 'High' when netwr >= 1000 then 'Medium' when netwr >= 100 then 'Low' else 'Micro' end as price_category }
CASE 与聚合结合
define view entity Z_SALES_BY_STATUS as select from vbak { key vbeln, sum( case when netwr > 0 then netwr else 0 end ) as positive_value, sum( case when netwr < 0 then abs( netwr ) else 0 end ) as negative_value, count( case when netwr > 0 then 1 end ) as positive_count } group by vbeln
CDS 参数化视图
输入参数定义
基本参数
define view entity Z_MATERIAL_BY_TYPE with parameters p_matnr : matnr, p_mtart : mtart as select from mara { key matnr, maktx, mtart } where matnr = $parameters.p_matnr and mtart = $parameters.p_mtart
默认值参数
define view entity Z_ORDERS_DEFAULT_DATE with parameters p_date : sydatum default $session.system_date as select from vbak { key vbeln, erdat, netwr } where erdat = $parameters.p_date
define view entity Z_ORDERS_DATE_RANGE with parameters p_date_from : sydatum, p_date_to : sydatum as select from vbak { key vbeln, erdat, netwr } where erdat >= $parameters.p_date_from and erdat <= $parameters.p_date_to
模糊查询
define view entity Z_MATERIAL_SEARCH with parameters p_search : char(40) as select from mara { key matnr, maktx, mtart } where maktx like $parameters.p_search
在 ABAP 中调用参数化视图
DATA: lt_result TYPE TABLE OF zmaterial_by_type.
SELECT * FROM zmaterial_by_type( p_matnr = '000000000000000001', p_mtart = 'FERT' ) INTO TABLE @lt_result.
CDS 视图组合
UNION - 合并查询
基本 UNION
define view entity Z_ALL_DOCUMENTS as select from vbak { key vbeln as DocumentNumber, 'Sales Order' as DocumentType, erdat as CreatedOn, netwr as Value } union select from likp { key vbeln as DocumentNumber, 'Delivery' as DocumentType, erdat as CreatedOn, 0 as Value }
UNION ALL
define view entity Z_ALL_MOVEMENTS as select from mseg where shkzg = 'S' { key mblnr, key zeile, 'Debit' as MovementType, menge, dmbtr } union all select from mseg where shkzg = 'H' { key mblnr, key zeile, 'Credit' as MovementType, menge, dmbtr }
INTERSECT - 交集
define view entity Z_COMMON_MATERIALS as select from marc where werks = '1000' { key matnr } intersect select from marc where werks = '2000' { key matnr }
EXCEPT - 差集
define view entity Z_ONLY_IN_PLANT_1000 as select from marc where werks = '1000' { key matnr } except select from marc where werks = '2000' { key matnr }
define view Z_SALES_ORDER_HEADER as select from vbak as _Header association [1..1] to kna1 as _Customer on _Header.kunnr = _Customer.kunnr { @UI.lineItem: [{ position: 10, label: 'Sales Order' }] @UI.selectionField: [{ position: 10 }] key _Header.vbeln as SalesOrder,
@Semantics.currencyCode: true _Header.waerk as Currency }
搜索注解示例
@Search.searchable: true define view entity Z_SEARCHABLE_MATERIAL as select from mara { @Search.defaultSearchElement: true @Search.fuzziness.threshold: 0.7 key matnr as Material,
@Search.defaultSearchElement: true @Search.fuzziness.threshold: 0.8 maktx as Description,
@Search.ranking: #HIGH mtart as MaterialType }
CDS 权限控制(DCL)
DCL 概述
Data Control Language (DCL) 用于定义 CDS 视图的数据访问权限。它与 CDS 视图配合使用,实现行级别的权限控制。
基本 DCL 定义
简单权限控制
@EndUserText.label: 'Sales Order Authorization' define role Z_SALES_ORDER_AUTH { grant select on Z_SALES_ORDER_HEADER where ( SalesOrg ) = aspect pfcg_auth( S_VBAK_VKO, VKORG ); }
多条件权限
define role Z_SALES_AUTH_MULTI { grant select on Z_SALES_ORDER_HEADER where ( SalesOrg ) = aspect pfcg_auth( S_VBAK_VKO, VKORG ) and ( Division ) = aspect pfcg_auth( S_VBAK_SPART, SPART ); }
权限注解集成
@AccessControl.authorizationCheck: #CHECK define view entity Z_SECURED_SALES as select from vbak { key vbeln, vkorg, netwr }
DCL 使用场景
基于组织架构的权限
define role Z_ORG_AUTH { grant select on Z_ORGANIZATIONAL_DATA where ( CompanyCode ) = aspect pfcg_auth( F_BUKRS, BUKRS ); }
基于角色的权限
define role Z_ROLE_AUTH { grant select on Z_SENSITIVE_DATA where ( DataCategory ) = aspect pfcg_auth( Z_DATA_CAT, CATEGORY ); }
CDS 性能优化
计算下沉
CDS 的核心优势是将计算下沉到数据库层执行,减少数据传输量。
聚合计算下沉
define view entity Z_SALES_AGGREGATE as select from vbap { key vbeln as SalesOrder, sum( netwr ) as TotalValue, count( * ) as ItemCount, avg( netwr ) as AvgValue } group by vbeln
条件计算下沉
define view entity Z_PRICE_WITH_DISCOUNT as select from vbap { key vbeln, key posnr, netwr, netwr * 0.9 as discounted_price, " 计算在数据库层 case when netwr >= 10000 then 'High' when netwr >= 1000 then 'Medium' else 'Low' end as price_category }
关联优化
使用 Association 替代 Join
" 低效:立即加载所有关联 define view Z_BAD_EXAMPLE as select from vbak inner join vbap on vbak.vbeln = vbap.vbeln inner join kna1 on vbak.kunnr = kna1.kunnr { vbak.vbeln, vbap.posnr, kna1.name1 }
" 高效:按需加载关联 define view entity Z_GOOD_EXAMPLE as select from vbak as _Order association [1..*] to vbap as _Items on _Order.vbeln = _Items.vbeln association [1..1] to kna1 as _Customer on _Order.kunnr = _Customer.kunnr { key _Order.vbeln, _Items.posnr, _Customer.name1 }
减少字段传输
" 低效:传输所有字段 define view Z_ALL_FIELDS as select from mara { * }
" 高效:只选择需要的字段 define view entity Z_MINIMAL_FIELDS as select from mara { key matnr, maktx, mtart }
索引优化
使用索引字段过滤
define view entity Z_INDEXED_QUERY as select from vbak { key vbeln, erdat, netwr } where vbeln like '100%' " 使用主键索引 and erdat = '20240101' " 使用日期索引
避免全表扫描
" 低效:全表扫描 define view Z_FULL_SCAN as select from vbak { key vbeln, netwr } where netwr > 0 " 非索引字段
" 高效:使用索引字段 define view entity Z_INDEX_SCAN as select from vbak { key vbeln, netwr } where vbeln = '1000000001' " 主键索引
CDS 最佳实践
1. 命名规范
视图命名
CDS View Entity: Z_<模块>_<描述> (例:Z_SD_SALES_ORDER)
SQL View: Z<描述>SQL (例:ZSALESORDSQL)
接口视图: I_<描述> (例:I_SALESORDER)
消费视图: C_<描述> (例:C_SALESORDER)
字段命名
使用业务字段名,不要使用技术字段名
使用有意义的别名
保持一致性
" 好的命名 define view entity Z_SALES_ORDER as select from vbak { key vbeln as SalesOrder, erdat as CreatedOn, kunnr as Customer, netwr as NetValue }
" 不好的命名 define view entity Z_SO as select from vbak { key vbeln, erdat, kunnr, netwr }
" 好的设计:按需加载 define view entity Z_SALES_ORDER as select from vbak as _Order association [1..*] to vbap as _Items on _Order.vbeln = _Items.vbeln association [1..1] to kna1 as _Customer on _Order.kunnr = _Customer.kunnr { key _Order.vbeln, _Order.erdat, _Items.posnr, _Customer.name1 }
" 不好的设计:立即加载所有关联 define view Z_SALES_ORDER_BAD as select from vbak inner join vbap on vbak.vbeln = vbap.vbeln inner join kna1 on vbak.kunnr = kna1.kunnr { vbak.vbeln, vbap.posnr, kna1.name1 }
4. 性能优化
避免 SELECT *
" 低效 define view Z_BAD as select from mara { * }
" 高效 define view entity Z_GOOD as select from mara { key matnr, maktx, mtart }
使用参数化视图
define view entity Z_PARAMETERIZED with parameters p_matnr : matnr as select from mara { key matnr, maktx } where matnr = $parameters.p_matnr
5. 代码组织
视图层次结构
基础视图(表关联) ↓ 接口视图(业务字段) ↓ 消费视图(UI 注解)
示例:销售订单视图层次
" 1. 基础视图:表关联 define view entity ZI_SALES_ORDER_BASE as select from vbak as _Header association [1..*] to vbap as _Items on _Header.vbeln = _Items.vbeln { key _Header.vbeln, _Header.erdat, _Header.kunnr, _Items.posnr, _Items.matnr, _Items.netwr }
" 2. 接口视图:业务字段 define view entity ZI_SALES_ORDER as select from ZI_SALES_ORDER_BASE { key vbeln as SalesOrder, erdat as CreatedOn, kunnr as Customer, posnr as Item, matnr as Material, netwr as NetValue }
define view entity Z_NO_DUPLICATES as select from vbak as _Order association [0..1] to ( select from vbap { vbeln, sum( netwr ) as total_value } group by vbeln ) as _Items on _Order.vbeln = _Items.vbeln { key _Order.vbeln, _Items.total_value }