ABAP CDS Annotations Reference for On-Premise Systems
This reference lists the CDS annotations on-premise developers write most, with their allowed values, where they go and what they change at runtime. It covers both DDIC-based views (DEFINE VIEW) and CDS view entities (DEFINE VIEW ENTITY) on SAP NetWeaver 7.50 and S/4HANA.
| Annotation | Allowed values | Scope | Effect | Release / notes |
|---|---|---|---|---|
@AbapCatalog.sqlViewName | Name, max 16 characters | View | Name of the generated CDS database view in DDIC | DDIC-based views (DEFINE VIEW) only. Not allowed with DEFINE VIEW ENTITY. |
@AbapCatalog.compiler.compareFilter | true, false | View | Same filter on an association in several path expressions creates one join instead of several | DDIC-based views; view entities always behave this way. |
@AbapCatalog.preserveKey | true, false | View | true keeps the KEY elements of the CDS view as key of the database view | DDIC-based views only. |
@AbapCatalog.viewEnhancementCategory | [#NONE], [#PROJECTION_LIST], [#UNION], [#GROUP_BY] | View | Controls which CDS view extensions are allowed | Array value. Needed when the view uses aggregates or UNION and should be extensible. |
@AccessControl.authorizationCheck | #CHECK, #NOT_REQUIRED, #NOT_ALLOWED, #PRIVILEGED_ONLY | View | Whether a DCL role (DEFINE ROLE) must restrict ABAP SQL access | #CHECK gives a syntax warning if no role exists. Access control applies to ABAP SQL, not to direct database access. |
@EndUserText.label | Text, max 60 characters | View, element, parameter | Translatable label shown in tools and UIs | Element labels override the data element text. |
@EndUserText.quickInfo | Text | Element, parameter | Tooltip text | Translatable. |
@ClientHandling.type | #INHERITED, #CLIENT_DEPENDENT, #CLIENT_INDEPENDENT | View | Declares whether the view is client-specific | DDIC-based views and table functions. View entities handle the client implicitly. |
@ClientHandling.algorithm | #AUTOMATED, #SESSION_VARIABLE, #NONE | View | How the client is applied in the generated SQL | #SESSION_VARIABLE uses the HANA session variable CDS_CLIENT. |
@Metadata.allowExtensions | true, false | View | Allows metadata extensions (DDLX) to add annotations | Typical for UI annotations kept out of the DDL. |
@Metadata.ignorePropagatedAnnotations | true, false | View | Stops element annotations from being inherited from data sources | Use when inherited UI or semantics annotations are wrong for this view. |
@VDM.viewType | #BASIC, #COMPOSITE, #CONSUMPTION, #TRANSACTIONAL | View | Classifies the view in the virtual data model | Documentation only for the runtime; used by SAP naming and release contracts. |
@ObjectModel.representativeKey | Element name | View | Marks the most specific key element, e.g. the item in an item view | Needed for value helps and analytics on multi-key views. |
@ObjectModel.text.element | [ 'ElementName' ] | Element | Links a code to its text element in the same view | Alternative: @ObjectModel.text.association to a text view. |
@ObjectModel.foreignKey.association | '_AssociationName' | Element | Declares the association that checks or describes the field value | Used by analytics and value helps. |
@ObjectModel.usageType.serviceQuality | #A, #B, #C, #D, #X, #P | View | Performance class of the view | #A cheapest, #D heaviest, #X for extraction, #P for hierarchy or helper views. |
@ObjectModel.usageType.sizeCategory | #S, #M, #L, #XL, #XXL | View | Expected row count class | Rough sizing hint, not enforced. |
@ObjectModel.usageType.dataClass | #TRANSACTIONAL, #MASTER, #ORGANIZATIONAL, #CUSTOMIZING, #META, #MIXED | View | Kind of data the view returns | Used for caching and classification. |
@Semantics.amount.currencyCode | 'CurrencyElement' | Element | Links an amount to its currency key field | Required for CURR fields in view entities, which check the reference strictly. |
@Semantics.quantity.unitOfMeasure | 'UnitElement' | Element | Links a quantity to its unit field | Required for QUAN fields in view entities. |
@Semantics.currencyCode | true | Element | Marks the element as a currency key | Set on the CUKY element referenced by amounts. |
@Semantics.unitOfMeasure | true | Element | Marks the element as a unit key | Set on the UNIT element referenced by quantities. |
@Semantics.text | true | Element | Marks the element as a language-dependent text | Used with text views and @ObjectModel.text. |
@Semantics.systemDateTime.lastChangedAt | true | Element | Marks the last changed time stamp | RAP uses it for ETag and change tracking. |
@Analytics.dataCategory | #CUBE, #DIMENSION, #FACT, #AGGREGATIONLEVEL | View | Role of the view in the analytic model | Cubes need measures with an aggregation default. |
@Analytics.query | true | View | Makes the view an analytical query for the analytic engine | Classic approach. Newer releases use transient view entities with provider contract analytical_query. |
@Analytics.dataExtraction.enabled | true | View | Allows extraction through ODP, for example to BW or Datasphere | Add delta annotations for change data capture. |
@DefaultAggregation | #SUM, #MIN, #MAX, #COUNT_DISTINCT, #NONE, #FORMULA | Element | Default aggregation of a measure | Newer releases prefer @Aggregation.default with the same values. |
@OData.publish | true | View | Generates an SAP Gateway OData V2 service for the view | Legacy approach for DDIC-based views: register the generated service in /IWFND/MAINT_SERVICE. Not used for RAP. |
@UI.lineItem | [{ position: 10, importance: #HIGH, label: '...' }] | Element | Column in a Fiori elements list or table | Usually placed in a metadata extension. |
@UI.identification | [{ position: 10 }] | Element | Field in the identification area of an object page | Referenced by a facet of type #IDENTIFICATION_REFERENCE. |
@UI.selectionField | [{ position: 10 }] | Element | Filter field in the list report filter bar | Combine with a value help. |
@UI.headerInfo | { typeName: '...', typeNamePlural: '...', title: { value: 'Element' } } | View | Object page header and list title | View-level annotation. |
@UI.facet | [{ id: '...', purpose: #STANDARD, type: #IDENTIFICATION_REFERENCE, label: '...', position: 10 }] | Element | Sections of an object page | Placed on any element, often the key. |
@Consumption.valueHelpDefinition | [{ entity: { name: 'ValueHelpView', element: 'Element' } }] | Element, parameter | Assigns a value help view | The value help view must be exposed in the service. |
@Consumption.filter | { selectionType: #SINGLE | #INTERVAL | #RANGE, multipleSelections: true, mandatory: true } | Element | Filter behaviour in analytical queries and UIs | Mostly evaluated by analytics. |
@Search.searchable | true | View | Enables free-text search on the view | Needs at least one element with defaultSearchElement. |
@Search.defaultSearchElement | true | Element | Element included in the free-text search | Add @Search.fuzzinessThreshold for fuzzy search on HANA. |
@Environment.systemField | #CLIENT, #SYSTEM_DATE, #SYSTEM_TIME, #SYSTEM_LANGUAGE, #USER | Parameter | ABAP SQL passes the matching system value when no actual parameter is given | Introduced with 7.50. #CLIENT prevents passing the client explicitly. |
Values are from the ABAP keyword documentation section on ABAP CDS SAP annotations and the framework-specific annotation docs. Annotation support differs between SAP_BASIS 7.50, ABAP Platform 7.5x for S/4HANA and view entities (7.55 and later); check the ADT element info (F2) on your system.
Review your CDS views
Send us a CDS view and its DCL and we will check annotations, references and access control for your release.
Optional. The tool and every export work without this. No spam.
How to use it
Search by annotation name or by what you want to achieve, for example authorization, currency, text or filter. The scope column tells you whether the annotation goes before DEFINE (view), before an element in the select list, or before a parameter. The notes column flags annotations that only work in DDIC-based views. In ADT, place the cursor on an annotation and press F2 to see the definition and allowed values for your exact release, and use code completion after the @ sign to list what your system supports.
Version differences and gotchas
CDS view entities, available from ABAP Platform 7.55, drop several AbapCatalog and ClientHandling annotations because they have no generated SQL view: @AbapCatalog.sqlViewName, preserveKey and the ClientHandling annotations are not allowed. View entities also check amount and quantity references strictly, so CURR and QUAN fields need @Semantics.amount.currencyCode and @Semantics.quantity.unitOfMeasure. @OData.publish is the older shortcut to a Gateway V2 service and is not used with RAP, where you write a service definition and binding instead.
- Migrating DEFINE VIEW to DEFINE VIEW ENTITY: remove sqlViewName and ClientHandling.
- @Analytics.query true is the classic query; newer releases use transient view entities.
- @DefaultAggregation is being replaced by @Aggregation.default.
Authorization check in practice
@AccessControl.authorizationCheck: #CHECK means you intend to write a DCL role with DEFINE ROLE that maps PFCG authorization objects to view fields, for example a condition on the sales organization with an aspect pfcg_auth to V_VBAK_VKO. Without a role, #CHECK gives a syntax warning and the view returns all rows. #NOT_REQUIRED means no role is needed, #NOT_ALLOWED blocks roles, and #PRIVILEGED_ONLY allows only privileged access. Access control runs for ABAP SQL reads. An SQL console or a direct database user bypasses it, which matters when you expose views to reporting tools.
How to check the result in the system
Activate the view in ADT and read the warnings: missing currency references and missing DCL roles show up there. For a DDIC-based view, check the generated SQL view in SE11 under the sqlViewName. Use the ADT data preview to confirm text, filter and value help behaviour, and compare results for a user with and without the relevant PFCG authorization to confirm the DCL role applies. For UI annotations, open the service in the Fiori elements preview of the service binding or check the OData $metadata document.
Frequently Asked Questions
What is an annotation in an ABAP CDS view?
An annotation is metadata written with @ before the view, an element or a parameter. Some change how the view is generated or checked (AbapCatalog, AccessControl), some describe meaning (Semantics, ObjectModel) and some are read by frameworks such as analytics, search or Fiori elements (Analytics, Search, UI, Consumption).
What are the values of @AccessControl.authorizationCheck?
The common values are #CHECK (a DCL role should restrict access), #NOT_REQUIRED (no role needed), #NOT_ALLOWED (roles are not allowed) and #PRIVILEGED_ONLY. With #CHECK and no role, the view is readable by everyone with a syntax warning.
Can I use @AbapCatalog.sqlViewName in a view entity?
No. DEFINE VIEW ENTITY creates no separate DDIC SQL view, so sqlViewName, preserveKey and ClientHandling annotations are not allowed. Remove them when you migrate a DDIC-based view to a view entity.
Why does my amount field show a currency error?
View entities require every CURR field to reference a currency key. Annotate the amount with @Semantics.amount.currencyCode: 'CurrencyField' and include that CUKY field in the select list. Quantities need @Semantics.quantity.unitOfMeasure the same way.
If you want your team to query these CDS views in plain English on your own servers, with the same DCL rules applied, Netray can set that up.
Related Tools
ABAP CDS View Skeleton Generator
Fill in table, fields, aliases and one association to get CDS view DDL in both the classic DDIC-based and the view entity syntax.
Developer ToolsABAP New Open SQL Syntax Reference by Release (7.40 to 7.58)
Look up each ABAP SQL feature with the classic form, the new syntax and the SAP_BASIS release that first allows it, from 7.40 SP05 to 7.58.
SAPSAP Gateway OData Transaction Codes Reference (SEGW, /IWFND/)
Every Gateway transaction you need to build, activate, test and debug OData services, with where it runs (hub or backend) and the mistake people make with it.
Developer ToolsABAP ALV Layout, Field Catalog and Color Codes Reference
Side by side: how to do checkbox, hotspot, colors, subtotals, toolbar buttons, top of page and refresh in CL_GUI_ALV_GRID and in CL_SALV_TABLE, plus the C1 to C7 color codes.
More Developer Tools tools
See all- ABAP CDS Table Function with AMDP Generator
- SAP Sales Order ABAP SELECT Generator (VBAK, VBAP, VBFA)
- SAP Sales Order Create BAPI ABAP Generator (BAPI_SALESORDER_CREATEFROMDAT2)
- SAP ABAP Open Items SELECT Generator
- SAP ACDOCA SQL Query Generator
- SAP QM Inspection Lot ABAP SELECT Generator
- SAP Quality Notification Pareto SQL Query Generator
- SAP QM Usage Decision BAPI Skeleton
- ABAP Custom Exception Class Generator
Keep exploring
Free tools
- ABAP CDS View Skeleton GeneratorFill in table, fields, aliases and one association to get CDS view DDL in both the classic DDIC-based and the view entity syntax.
- ABAP CDS Table Function with AMDP GeneratorBuilds the three parts of a CDS table function: the DDL definition with client handling and parameters, the AMDP class with SQLScript, and the ABAP SQL call that consumes it.
- ABAP Naming Convention TemplateA fill-in development standard that defines prefixes for variables, parameters, classes, DDIC objects, programs and CDS views.
ERP fixes and how-tos
- Private AI layer for SAP S/4HANA on-premise: released APIs, CDS and a local modelAdd a private AI assistant to SAP S/4HANA on-premise or private edition: released APIs, CDS views, ODP, retrieval index, local LLM and access control.
- API Creation Process in SAP S/4HANA: From CDS View to OData ServiceHow to create a custom API in SAP S/4HANA: CDS view entity, service definition, service binding, activation, authorization and when to use the Business Hub.
- SAP S/4HANA Standard Reports: Fiori, Embedded Analytics and CDS ViewsWhere standard reports live in SAP S/4HANA: Fiori analytical apps, embedded analytics and CDS views, with examples for sales reporting and Group Reporting in finance.