ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

ABAP CDS视图详解:从数据读取到业务建模的演进与选型

ABAP CDS视图详解:从数据读取到业务建模的演进与选型 最近在项目里被同事问得最多的一个问题就是ABAP CDS 视图到底解决了什么问题我直接用 Open SQL 和函数读取数据不行吗到了 RAP 场景里它又扮演什么角色说实话这个问题的本质不是“CDS 视图能不能查数据”而是对“目的”的理解没对齐——它不是一个简单的查询替代品而是在 S/4HANA 里把数据读取逐步升级为业务建模、行为建模和事件发布的基础设施。这篇就把这个演进过程拆开讲清楚顺带把基础视图、消费视图、扩展视图、RAP 和分析场景的选型思路一起理一遍给正在做 S/4HANA 开发或刚接触 CDS 的同学一份可落地的参考。1. CDS 视图解决的核心问题从“读表”到“表达业务”1.1 为什么 Open SQL 已经能 JOIN还要多建一层 CDS 视图传统 ABAP 开发里大部分取数逻辑都写在程序内部函数里几段 SELECT报表里再来两层 LOOP 拼接数据。这种写法不是不能跑痛点在于“口径不统一、逻辑不可复用、权限分散维护”。举个例子MARA、MAKT、MARC 这三张表A 程序 JOIN 一次取物料描述B 报表里又 JOIN 一次C 接口里可能再 JOIN 一遍。某天 MAKT 新增了语言字段或者 MARC 里某个字段的口径调整你得到多少个程序里去改改漏一个报表数据对不上业务部门就来投诉。CDS 视图解决的就是这个问题它把“读数据”从一段一段散落的程序逻辑提升为“数据模型”。你只需要在 CDS 视图里定义一次“物料 文本 工厂视图”的组装方式后续 ABAP 程序、OData 服务、分析工具都通过这个模型去读取。用一个厨房的类比来说以前是每个人自己抄菜谱出菜顺序和用料全看个人发挥CDS 视图是先把标准菜谱定在墙上所有人都照这个执行。不是说 CDS 视图能让查询“自动变快”而是它能让你的查询逻辑“只维护一份”。还有个更实际的价值可审计性。当业务方质疑“报表里的库存数量口径不对”时你不需要在几十个程序里逐个排查直接定位到那个埋下错误口径的 CDS 视图就完了。这种维护性收益在项目里往往比性能收益更明显。所以我对“视图可以加快查询速度吗”这类问题的回答通常是它不一定让单次查询更快但能让整个系统“改起来更快”。1.2 关联Association与路径表达式CDS 的“小外键”CDS 视图里有一个和普通 Open SQL 完全不同的概念Association。普通 JOIN 是在写 SQL 时就完全确定数据关系而 Association 相当于先在模型里声明一段关系等上层真正用到时才被解析成 JOIN。语法大致长这样define view entity ZI_Material as select from mara as Material association [1..1] to makt as _Text on $projection.MaterialID _Text.matnr and _Text.spras $session.system_language { key Material.matnr as MaterialID, Material.mtart as MaterialType, _Text.maktx as Description }注意这里的_Text并不是在读取 ZI_Material 时一定会生成 JOIN只有在你真正通过路径表达式引用_Text.maktx的时候框架才会把关联带出来。这种“按需关联”的能力让上层视图可以优雅地复用底层模型又不会因为每层都写 JOIN 把 SQL 撑爆。但我在项目里见过不少反面案例底层视图关联了十几张表上层视图再往下关联两三层最后一条简单报表查询数据库层解析出的 SQL 有上百行。性能问题往往不是 CDS 本身的问题而是关联用得没有节制。我的建议是底层基础视图尽量扁平关联尽量在上层消费视图里展开。等你在上线前用 SAT 或 HANA PlanViz 看到那些被展开的 SQL 时就会理解这句话有多重要。还有一个容易踩的坑在 RAP 场景里Association 的基数cardinality如果写错比如把[1..1]写成[*]可能导致查询结果翻倍或者取数失败而且编译期通常不报错。排查这类问题非常头大因为它表现出的症状往往是“某个字段值不对”而不是“视图有问题”。1.3 注解CDS 视图的业务语义开关普通数据库视图只有字段和 SQLCDS 视图不一样的地方在于它可以携带大量注解。注解不改变数据但会告诉各种框架“这个视图是干什么用的”。选型时最相关的几类注解大致有这几种注解类别典型写法作用基础注解AbapCatalog.sqlViewName、EndUserText.label定义 SQL 视图名、显示标签语义注解ObjectModel.*定义对象模型语义供 RAP / OData 识别分析注解Analytics.dataCategory: #CUBE、Analytics.query: true标记为分析立方体 / 分析查询消费注解Consumption.*定义消费属性如默认过滤、排序UI 注解UI.*定义 Fiori 界面呈现方式如果只是给 ABAP 程序做 SELECT基础注解就够了。但如果这个视图要给 Fiori 用、给分析用、或者作为 RAP 业务对象的数据源缺少对应注解往往会导致框架不认它。我之前帮同事排查过一个分析模型不可见的问题Cube 视图数据完全正常但 SAP Analytics Cloud 里就是找不到模型最后发现是忘了加Analytics.dataCategory: #CUBE系统根本不知道它该往“分析模型”里注册。所以我把“选型”的第一步定为确定消费端是谁然后才能确定要加哪些注解。这个顺序一旦颠倒后面补注解、改模型的成本会很大。2. 选型基础视图、复合视图、消费视图和扩展视图分清楚再上手2.1 基础视图Base View封装复杂查询的第一层基础视图是 CDS 视图体系里最底层的一层通常直接建在透明表上完成字段选择、JOIN、口径过滤这些“脏活累活”。在设计基础视图时我一般会遵循几个原则第一字段要克制。不要无脑 SELECT *CDS 视图不像透明表那样“反正都读出来了”每层字段越多后续依赖它的上层视图越难裁剪。第二逻辑要底平。把复杂的 JOIN、字段转换放在基础视图完成但不要把业务规则塞进来比如状态判断、金额计算公式这些。基础视图只做“干净的原始数据”业务化加工放在上层。第三命名要规范。项目里一般用前缀区分场景比如ZI_接口、ZC_消费、ZA_分析、ZX_扩展。一个没有命名纪律的 CDS 视图体系过半年就没人敢动了。一个最简单的基础视图可以是这样的AccessControl.authorizationCheck: #CHECK EndUserText.label: 物料基础视图 define view entity ZI_Material as select from mara as Material { key Material.matnr as MaterialID, Material.mtart as MaterialType, Material.matkl as MaterialGroup }这里没有加太多注解因为它只是最底层的数据来源。等上层有具体消费需求时再逐层补语义。2.2 复合视图与消费视图面向不同消费端复合视图和消费视图这两个概念在不同团队里叫法可能略有差异但实践上可以这么理解复合视图是把多个基础视图关联起来形成一个完整的业务模型比如“物料主数据 工厂信息 库存信息”消费视图则是在复合模型之上针对某一个消费端Fiori UI、OData 服务、分析工具做最终的字段裁剪和展示定义。消费视图往往带参数、带搜索字段、带默认排序。比如一个 Fiori 报表的消费视图可能定义了默认日期区间、默认排序字段。这里就牵涉到命名习惯I_开头的接口视图更多承担“业务数据接口”角色C_开头的消费视图负责面向 UI 和外部服务。实际项目中很多人为了少建一个对象直接在接口视图上发布 OData。短期看能用但一旦界面需要补字段、加过滤就得动接口视图影响面会变大。所以哪怕项目赶进度我也建议保留“消费视图”这一层。它就像 API 和页面之间的适配层短期看是多了一个对象长期看是给接口视图加了保护层。2.3 扩展视图Extend View标准功能增强的规范入口S/4HANA 项目里最常见的需求之一是给标准 CDS 视图补一个自定义字段。正确做法是用EXTEND VIEW定义扩展视图而不是复制标准视图去改。前提是标准视图本身允许扩展也就是它标注了类似Metadata.allowExtensions的注解。简化示例大概是这样的标准视图端Metadata.allowExtensions: true define view entity I_Product as select from ... { key Product as ProductID, ... }项目端再写一个扩展视图define view entity ZI_I_Product_Ext as extend view I_Product { my_custom_field1 as MyField1, my_custom_field2 as MyField2 }不同 ABAP 版本的扩展视图语法会有些差异但核心动作都是EXTEND不是修改原视图。这里有几个常见的坑第一扩展视图只能追加字段和关联不能修改已有字段的值或类型。第二字段名一定要带项目前缀否则 SAP 升级时可能与标准字段冲突。第三扩展完视图之后如果要在 Fiori 界面看到新字段通常还需要在投影视图或消费视图里把新字段再带出来不是“扩展了就立刻出现”。我见过一个同事直接复制标准视图到 Z 包去改看起来省事但系统升级时这个 Z 视图就跟标准结构脱节了维护成本极高。正确的做法永远是能扩展就扩展不能扩展就做投影绝对不要动标准对象本身。2.4 选型对照表一张表看懂视图类型视图类型典型名称前缀主要消费端关键注解是否支持写操作基础视图ZI_ / ZD_ABAP 程序、上层 CDS 视图基础注解否复合视图ZC_OData / Fiori、上层模型ObjectModel、Consumption否消费视图ZC_ / C_Fiori、外部服务UI、OData.publish通过 RAP 支持扩展视图ZX_标准视图增强Metadata.allowExtensions标准端否Cube / 维度视图ZA_分析工具、SAC、BWAnalytics否分析查询视图ZA_ / C_报表、分析消费端Analytics.query否选型最核心的一句话让视图类型匹配它的消费端。用分析 Cube 去做普通报表查询或者用基础视图撑 Fiori UI后面都会出现“这也不行那也不行”的尴尬局面。3. RAP 场景下 CDS 视图的角色从只读查询到业务对象再到事件发布3.1 只读业务对象直接消耗 CDS 查询RAP 是 S/4HANA 里主流的服务编程模型。很多人一听 RAP 就以为是“新接口方式”其实 RAP 的关键在于“业务对象”这个概念一个业务对象不仅包含数据还包含数据上的行为。只读场景下CDS 视图基本可以独立撑起一个 Fiori 列表。给视图加上OData.publish: true新版本更推荐通过 Service Definition 显式发布发布 OData 服务后Fiori Elements 就能直接消费。这里要特别提一下 RAP 里的视图分层。接口视图定义业务对象的“数据契约”消费视图面向具体应用有些场景还会加投影视图来裁剪字段权限。如果只是只读应用三层不全是可行的但项目里经常需要保留消费视图。为什么因为接口视图往往承担着“复用”的职责如果每个页面都直接在接口视图上做个性化接口视图的语义就会越来越膨胀。消费视图在这里起到的作用就是给每个页面一个“专属入口”。3.2 写操作BDEF 里如何基于 CDS 视图定义行为当业务对象需要增删改时RAP 引入了 BDEFBehavior Definition。在 BDEF 里你可以定义 create、update、delete、action、validation、determination甚至定义动态特性控制。一个典型的理解方式是CDS 视图提供数据契约BDEF 定义数据契约上的行为ABAP 类实现这些行为。define behavior for ZI_Material alias Material { create; update; delete; action SetStatus parameter ZC_STATUS; }然后在行为实现类里写MODIFY ENTITIES来做增删改。很多老 ABAP 开发者刚转 RAP 时很不习惯为什么不能直接用UPDATE mara因为一旦绕过 BDEF 直接更新表RAP 框架的权限控制、校验逻辑、业务事件全部失效数据一致性就没有保障了。从这个角度看RAP 里面的 CDS 视图和传统报表视图的定位完全不同。传统报表视图关注“怎么查”R
返回列表