CDS 视图快速构建器
用 mcp-abap-adt 连接器完成「填模板 → 生成 DDL → 语法检查 → 写入 → 激活 → 数据验证」的完整闭环。
0. 硬规则(不可绕过)
- 不新建请求号(CTS transport)。可传输包必须用户提供
transport_request;没有就先问,或用ListTransports列出用户自己名下可修改的请求让他挑。禁止调CreateTransport自作主张。 - 不新建 DDIC 对象(表、结构、数据元素、域、表类型)。视图需要的新字段用
cast/ 内置类型表达;确需新 DDIC 对象,停下来问。 - 不写业务数据。建视图属于开发对象,但任何
INSERT/UPDATE/DELETE业务表动作都不做。 - 不重写已运行的视图。改已有视图时先
GetDdl拉现有源码,在原文基础上增量改。 - 对象名
Z/Y开头,≤ 30 字符,不含连字符(用户惯用ZDY*前缀时沿用)。
1. 输入:参数模板
让用户填 assets/view-request-template.md(或按其字段口述)。最少必填四项:视图名、包、类型、数据源。
缺失字段按下列默认补全,不要逐项追问:
| 参数 | 默认值 |
|---|---|
| 视图语法 | view entity(新语法)。系统不支持时回退 DDIC-based,见 §4 |
package |
$TMP(本地对象,免请求号) |
transport_request |
空 → 仅当包为 $TMP 可用;否则必须问 |
| 主语言 | ZH(用户环境);@EndUserText.label 用中文 |
| 访问控制 | #NOT_REQUIRED(除非用户明确要权限校验) |
| VDM 层次 | 单表 → #BASIC;有 join/association → #COMPOSITE;UI/报表用 → #CONSUMPTION |
| 客户端处理 | 默认继承(view entity 不写 mandt,不加 client 参数) |
2. 建模前:先查真字段,绝不猜
- 数据源是表 →
GetTable;是结构/其他视图 →GetStructure/GetDdl。拿到真实字段名与类型。 - S/4 上库存类表带替换对象(MARD→
nsdm_e_mard、MSEG→nsdm_e_mseg、MBEW→mbv_mbew),跟着用同一套视图,细节见abap-s4-stock-nsdm技能。 - 拿不准字段值域/检查表 → 用
abap-adt-field-value-range技能(GetStructure看with foreign key,DD07T查域固定值)。 - 可选:
GetSqlQuery抽样几条数据确认字段有值、确认 join 键对得上。
3. 生成 DDL
按 type 从 references/ddl-templates.md 取对应骨架,填入注解与字段。注解速查见 references/annotations.md。
固定写进头部的注解(缺了在 HANA 上会有告警或激活失败):
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: '<中文标签>'
@Metadata.ignorePropagatedAnnotations: true
生成后自检清单:
- key 字段全部排在选择列表最前(view entity 强制要求)
- 每个字段有唯一别名;join/association 的表必须起别名
- 数量字段挂
@Semantics.quantity.unitOfMeasure,金额挂@Semantics.amount.currencyCode,且单位/币种字段必须在同一视图里存在 - view entity 不要写
@AbapCatalog.sqlViewName(写了报错),也不要 selectmandt - 末尾字段无逗号;每个注解块以
;或,正确收尾
4. 写入 SAP:四步顺序
1) CreateDdl(ddl_name, package_name, transport_request?, description, master_language="ZH")
→ 只建空壳,此时还没有源码
2) UpdateDdl(ddl_name, ddl_source, transport_request?, activate=false)
→ 写源码,先别激活
3) CheckDdl(ddl_name, version="inactive")
→ 有错就改源码重跑 UpdateDdl + CheckDdl,循环到干净
4) ActivateDdl(ddl_name)
→ 激活;报 inactive 残留时补调一次
UpdateDdl默认activate=false,不要图省事直接 true:先 Check 再 Activate,失败不会留残局。- 首次调用常遇
CSRF token validation failed→ 先调一次GetSession再继续。 - 若激活报"不支持 view entity / 语法不识别" → 系统版本老,改走 DDIC-based(
define view+@AbapCatalog.sqlViewName,名字 ≤16 位)重来,并告诉用户回退了。 - 详见
references/adt-cds-pitfalls.md。
5. 可选延伸(用户要才做)
| 需求 | 动作 |
|---|---|
| UI 注解外置 | CreateMetadataExtension 建 DDLX,再 UpdateMetadataExtension 写 @UI.* 代码 |
| 暴露 OData | CreateServiceDefinition(define service ... { expose ...; })→ CreateServiceBinding(默认 ODATA_V4_UI) |
| 表函数实现 | DDL 里 implemented by method <类>=>方法;AMDP 类用 CreateClass + UpdateClass 另建,不在本视图内写 ABAP |
| 视图单元测试 | CreateCdsUnitTest |
6. 交付前验证
ActivateDdl之后用GetDdl(version="active")确认拉到的是激活版。GetSqlQuery跑一条SELECT * FROM <视图> WHERE ...确认能出数(可加row_number: 5)。- 输出交付报告:视图名、包名、请求号、类型、激活状态、字段名与来源表、验证 SQL 与返回行数;失败则贴出
CheckDdl的原始报错。
7. 失败清理
- 只建了空壳没写源码 →
DeleteDdl(ddl_name, transport_request?)删掉再重来。 - 激活失败但对象已存在 → 改源码走
UpdateDdl+CheckDdl循环,不要删了重建(会留下重复 E071 条目)。 - 锁冲突(
User xxx is currently editing):ADT 侧解锁通常无效,让用户 SM12 删锁或等会话超时(~30min);REST 兜底做法见adt-rest-object-write技能。