Les vues CDS (Core Data Services) sont la manière moderne de définir des modèles de données dans SAP. Elles permettent des définitions de données sémantiquement riches et réutilisables directement au niveau de la base de données avec une optimisation push-down pour HANA.
Que sont les vues CDS ?
Les vues CDS sont :
- Extensions SQL déclaratives pour la modélisation sémantique de données
- Vues de base de données avec des fonctionnalités étendues (annotations, associations)
- Fondation pour SAP Fiori, RAP et le développement SAP moderne
- Performantes grâce au push-down vers la base de données (HANA)
Syntaxe de base
@AbapCatalog.sqlViewName: 'ZSQL_VIEW_NAME"@AbapCatalog.compiler.compareFilter: true@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'Description de la vue"
define view Z_CDS_VIEW_NAME as select from <source_donnees> { <liste_champs> }Exemples
1. Vue CDS simple
@AbapCatalog.sqlViewName: 'ZSQLCUSTOMERS"@AbapCatalog.compiler.compareFilter: true@AccessControl.authorizationCheck: #NOT_REQUIRED@EndUserText.label: 'Données de base clients"
define view Z_I_Customers as select from kna1{ key kunnr as CustomerId, name1 as CustomerName, ort01 as City, land1 as Country, erdat as CreatedDate}2. Utiliser une vue CDS en ABAP
" Utiliser la vue CDS comme une tableSELECT * FROM z_i_customers INTO TABLE @DATA(lt_customers) WHERE country = 'DE'.
LOOP AT lt_customers INTO DATA(ls_customer). WRITE: / ls_customer-customerid, ls_customer-customername.ENDLOOP.
" Avec déclaration inlineSELECT customerid, customername, city FROM z_i_customers WHERE country = 'DE" INTO TABLE @DATA(lt_german_customers).3. Vue CDS avec JOIN
@AbapCatalog.sqlViewName: 'ZSQLORDERCUST"@AccessControl.authorizationCheck: #NOT_REQUIRED@EndUserText.label: 'Commandes avec données client"
define view Z_I_OrdersWithCustomer as select from vbak as order inner join kna1 as customer on order.kunnr = customer.kunnr{ key order.vbeln as OrderNumber, order.erdat as OrderDate, order.netwr as NetValue, order.waerk as Currency, customer.kunnr as CustomerId, customer.name1 as CustomerName, customer.ort01 as CustomerCity}4. LEFT OUTER JOIN
define view Z_I_CustomersWithOrders as select from kna1 as customer left outer join vbak as order on customer.kunnr = order.kunnr{ key customer.kunnr as CustomerId, customer.name1 as CustomerName, order.vbeln as OrderNumber, order.netwr as OrderValue}5. Champs calculés (Calculated Fields)
@AbapCatalog.sqlViewName: 'ZSQLORDERCALC"@AccessControl.authorizationCheck: #NOT_REQUIRED@EndUserText.label: 'Commandes avec calculs"
define view Z_I_OrderCalculations as select from vbak{ key vbeln as OrderNumber, netwr as NetValue, waerk as Currency,
// Calculs netwr * 1.19 as GrossValue,
// Conditions avec CASE case when netwr >= 10000 then 'HIGH" when netwr >= 1000 then 'MEDIUM" else 'LOW" end as ValueCategory,
// Fonctions de date dats_days_between( erdat, $session.system_date ) as DaysSinceOrder}6. Agrégations
@AbapCatalog.sqlViewName: 'ZSQLCUSTTOTAL"@AccessControl.authorizationCheck: #NOT_REQUIRED@EndUserText.label: 'Chiffre d''affaires client agrégé"
define view Z_I_CustomerTotals as select from vbak{ key kunnr as CustomerId,
// Fonctions d'agrégation sum( netwr ) as TotalOrderValue, count(*) as OrderCount, avg( netwr ) as AverageOrderValue, min( erdat ) as FirstOrderDate, max( erdat ) as LastOrderDate}group by kunnr7. Associations
@AbapCatalog.sqlViewName: 'ZSQLORDERASSOC"@AccessControl.authorizationCheck: #NOT_REQUIRED@EndUserText.label: 'Commandes avec associations"
define view Z_I_Orders as select from vbak as Order association [1..1] to kna1 as _Customer on $projection.CustomerId = _Customer.kunnr association [0..*] to vbap as _Items on $projection.OrderNumber = _Items.vbeln{ key vbeln as OrderNumber, kunnr as CustomerId, erdat as OrderDate, netwr as NetValue,
// Exposer les associations _Customer, _Items}8. Utiliser les associations en ABAP
" Utiliser les expressions de cheminSELECT OrderNumber, OrderDate, NetValue, \_Customer-name1 as CustomerName, \_Customer-ort01 as CustomerCity FROM z_i_orders INTO TABLE @DATA(lt_orders_with_customer).
" Avec WHERE sur l'associationSELECT * FROM z_i_orders WHERE \_Customer-land1 = 'DE" INTO TABLE @DATA(lt_german_orders).9. Paramètres dans les vues CDS
@AbapCatalog.sqlViewName: 'ZSQLORDERPARAM"@AccessControl.authorizationCheck: #NOT_REQUIRED@EndUserText.label: 'Commandes avec paramètre"
define view Z_I_OrdersByDate with parameters p_from_date : abap.dats, p_to_date : abap.dats as select from vbak{ key vbeln as OrderNumber, erdat as OrderDate, netwr as NetValue, kunnr as CustomerId}where erdat >= $parameters.p_from_date and erdat <= $parameters.p_to_date10. Vue paramétrée en ABAP
" Passer les paramètresSELECT * FROM z_i_ordersbydate( p_from_date = '20240101', p_to_date = '20241231' ) INTO TABLE @DATA(lt_orders_2024).
" Avec des variablesDATA: lv_from TYPE d VALUE '20240101', lv_to TYPE d VALUE '20241231'.
SELECT * FROM z_i_ordersbydate( p_from_date = @lv_from, p_to_date = @lv_to ) INTO TABLE @DATA(lt_orders).11. Annotations pour l’UI (Fiori)
@AbapCatalog.sqlViewName: 'ZSQLCUSTUI"@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'Clients pour UI"
@UI.headerInfo: { typeName: 'Client', typeNamePlural: 'Clients', title: { value: 'CustomerName' }}
define view Z_C_Customers as select from z_i_customers{ @UI.facet: [{ position: 10, type: #IDENTIFICATION_REFERENCE }]
key @UI.lineItem: [{ position: 10 }] @UI.identification: [{ position: 10 }] CustomerId,
@UI.lineItem: [{ position: 20 }] @UI.identification: [{ position: 20 }] @UI.selectionField: [{ position: 10 }] CustomerName,
@UI.lineItem: [{ position: 30 }] @UI.selectionField: [{ position: 20 }] City,
@UI.lineItem: [{ position: 40 }] Country}12. Access Control (DCL)
@EndUserText.label: 'Contrôle d''accès pour les clients"@MappingRole: true
define role Z_I_Customers_Role { grant select on Z_I_Customers where Country = aspect pfcg_auth( ZAUTH_OBJ, ZLAND, ACTVT = '03' );}13. UNION et UNION ALL
define view Z_I_AllPartners as select from kna1{ key kunnr as PartnerId, name1 as PartnerName, 'CUSTOMER' as PartnerType}union all select from lfa1{ key lifnr as PartnerId, name1 as PartnerName, 'SUPPLIER' as PartnerType}14. CDS Table Functions (AMDP)
@EndUserText.label: 'CDS Table Function"define table function Z_TF_ComplexLogic with parameters p_date : abap.dats returns { key OrderId : abap.char(10); Amount : abap.curr(15,2); Status : abap.char(1); } implemented by method zcl_complex_logic=>get_orders;CLASS zcl_complex_logic DEFINITION PUBLIC. PUBLIC SECTION. INTERFACES if_amdp_marker_hdb.
CLASS-METHODS get_orders FOR TABLE FUNCTION z_tf_complexlogic.ENDCLASS.
CLASS zcl_complex_logic IMPLEMENTATION. METHOD get_orders BY DATABASE FUNCTION FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY USING vbak.
RETURN SELECT vbeln as orderid, netwr as amount, 'A' as status FROM vbak WHERE erdat = :p_date; ENDMETHOD.ENDCLASS.15. Extend Views
@AbapCatalog.sqlViewAppendName: 'ZSQLCUSTEXT"@EndUserText.label: 'Extension pour les clients"
extend view Z_I_Customers with Z_E_Customers_Extension{ // Champs supplémentaires d'autres tables kna1.brsch as Industry, kna1.kukla as CustomerClass}Types de vues CDS
| Type | Préfixe | Objectif |
|---|---|---|
| Interface View | I_ ou Z_I_ | Modèle de données de base, réutilisable |
| Consumption View | C_ ou Z_C_ | Spécifique UI, avec annotations UI |
| Basic View | R_ ou Z_R_ | Restreint, pour usage interne |
| Extension View | E_ ou Z_E_ | Extensions de vues existantes |
Annotations importantes
// Annotations de catalogue@AbapCatalog.sqlViewName: 'SQL_NAME' // Nom de la vue SQL (max 16 caractères)@AbapCatalog.compiler.compareFilter: true // Optimisation des filtres@AbapCatalog.preserveKey: true // Conserver la clé@AbapCatalog.buffering.status: #ACTIVE // Activer le buffering
// Contrôle d'accès@AccessControl.authorizationCheck: #CHECK // Vérification des autorisations@AccessControl.authorizationCheck: #NOT_REQUIRED
// Métadonnées@EndUserText.label: 'Description"@ObjectModel.representativeKey: 'FieldName"@ObjectModel.semanticKey: ['Field1', 'Field2']
// Analytics@Analytics.dataCategory: #CUBE@Analytics.dataCategory: #DIMENSION
// OData/Fiori@OData.publish: true@UI.headerInfo.typeName: 'Entity"Fonctions CDS
// Fonctions de chaîneconcat( field1, field2 )substring( field, position, length )length( field )upper( field )lower( field )ltrim( field, char )rtrim( field, char )
// Fonctions numériquesabs( field )ceil( field )floor( field )round( field, decimals )div( field1, field2 )mod( field1, field2 )
// Fonctions date/heuredats_days_between( date1, date2 )dats_add_days( date, days )dats_add_months( date, months )$session.system_date$session.user$session.client
// Conversionscast( field as type )currency_conversion( ... )unit_conversion( ... )
// Gestion des nullscoalesce( field, default )Bonnes pratiques
// 1. Noms de champs explicites (CamelCase)@AbapCatalog.sqlViewName: 'ZSQLSALES"define view Z_I_SalesOrders as select from vbak{ key vbeln as SalesOrderId, // Pas : VBELN kunnr as CustomerId, // Pas : KUNNR erdat as CreationDate // Pas : ERDAT}
// 2. Annotations pour la sémantique{ @Semantics.amount.currencyCode: 'Currency" netwr as NetAmount,
@Semantics.currencyCode: true waerk as Currency,
@Semantics.quantity.unitOfMeasure: 'Unit" kwmeng as Quantity,
@Semantics.unitOfMeasure: true vrkme as Unit}
// 3. Cardinalités pour les associationsassociation [1..1] to ... // Exactement uneassociation [0..1] to ... // Zéro ou uneassociation [0..*] to ... // Zéro à plusieursassociation [1..*] to ... // Une à plusieursRemarques importantes / Bonnes pratiques
- Les vues CDS sont la fondation du développement SAP moderne (Fiori, RAP).
- Utilisez les Interface Views (
I_) pour les modèles de base réutilisables. - Utilisez les Consumption Views (
C_) pour les besoins spécifiques à l’UI. - Associations plutôt que JOINs pour des requêtes plus flexibles et performantes.
- Les Annotations contrôlent le comportement, l’UI et les autorisations.
- Activez
@AccessControl.authorizationCheckpour la vérification des autorisations. - Les vues CDS peuvent être utilisées comme des tables normales en ABAP dans
SELECT. - Optimisation HANA : Les calculs sont poussés vers la base de données.
- Utilisez les Paramètres pour des vues flexibles et réutilisables.
- Virtual Data Model (VDM) : Suivez les conventions de nommage SAP pour des modèles cohérents.