ABAP on HANA之CDS Association和Path Expression

本文阐述了ABAP CDS association的概念,并且展示了在CDS视图中和SQL语句中写路径表达式(Path Expression)代码的方法。我也会解释如何在CDS asociation中指定inner join——默认情况下是left outer join,以及如何为association添加过滤。

 

对于CDS的相关开发,SAP希望我们使用association而不是join,因为association更加接近“概念思维”。基本上,association本身不是join,它只是有关join连接可能性的元数据,它会按需成为join。真实的join会在路径表达式使用association的时候被创建。

 一个简单的CDS association例子,它看起来和left outer join没区别:

@AbapCatalog.sqlViewName: 'ZCDS_ASSOC11'
define view zcds_assoc1 as select from scarr as sca
   association [0..1] to spfli as _spfli 
   on sca.carrid = _spfli.carrid   
   { * }

暴露CDS association的例子:

@AbapCatalog.sqlViewName: 'ZCDS_ASSOC41'
@AccessControl.authorizationCheck: #NOT_REQUIRED
define view zcds_assoc4 as select from sairport as sair
    association [1..*] to spfli as _spfli on
        $projection.airportfrom = _spfli.airpfrom
    {     
       sair.id as airportfrom,
       sair.name,
       sair.time_zone,
      -- exposing association
      _spfli
    }

在下面的例子里,你可以看到SPFLI表对SFLIGHT表和SAIRPORT表的association。通过别名alias _sfli和SFLIGHT和_sair,SAIRPORT的全部字段暴露在projection列表中。当路径表达式用于调用association时,会根据选择字段创建join条件:spfli.carrid = sflight.carrid and spfli.connid = sflight.connid and on spfli.airport = sairport.id。

@AbapCatalog.sqlViewName: 'ZCDS_ASSOC21'
@AccessControl.authorizationCheck: #NOT_REQUIRED
define view zcds_assoc2 as select from spfli 
   association to sflight as _sfli on 
        spfli.carrid = _sfli.carrid and
        spfli.connid = _sfli.connid
    association [1..1] to sairport as _sair on
        $projection.airportfrom = _sair.id
    {
      spfli.carrid,
      spfli.connid,
      spfli.airpfrom as airportfrom,
      -- exposing association
      _sfli,
      _sair    
    }

在下面的例子里,定义association时使用了上面的CDS entity,ZCDS_ASSOC2 :


@AbapCatalog.sqlViewName: 'ZCDS_ASSOC31'
@AccessControl.authorizationCheck: #NOT_REQUIRED
define view zcds_assoc3 as select from scarr
        association [1..1] to zcds_assoc2  as _cdsassoc on
         $projection.carrierid = _cdsassoc.carrid
      {
         scarr.carrid as carrierid,
     -- Exposing Association    
         _cdsassoc
      } 

Open SQL语句中的路径表达式:在SQL语句中调用CDS association,需要使用如下的路径表达式。在上面的CDS association中,通过_cdsassoc暴露了完整的projection列表。


DATA(w_dbfeature) = cl_abap_dbfeatures=>use_features( 
 requested_features = VALUE #( ( cl_abap_dbfeatures=>views_with_parameters ) ) ).
IF w_dbfeature IS NOT INITIAL.
  SELECT  carrierid ,
          \_cdsassoc\_sfli-fldate AS flightdate,
          \_cdsassoc\_sair-name AS flightname
        FROM zcds_assoc3
        WHERE carrierid = @carrid
        INTO TABLE @DATA(t_data1).
ENDIF.

CDS视图中的路径表达式:


@AbapCatalog.sqlViewName: 'ZCDS_ON_ASSOC1'
define view zcds_on_assoc with parameters airport: S_FROMAIRP  as select from zcds_assoc2 as cds2
    {
      cds2.carrid,
      cds2.connid,
      cds2.airportfrom,    
      cds2._sair.name, -- use inner join...by default association uses left outer join
      cds2._sfli.planetype
    }
 where cds2.airportfrom = :airport 

如我所提到的那样,在被路径表达式调用时,CDS association会默认创建left outer join。

在SPFLI表数据中,没有RTM机场的航班。

 

当我们输入参数airport = RTM的时候 ,下面的CDS视图的查询结果会是一条RTM机场的数据,但是这条记录里没有carrid。


@AbapCatalog.sqlViewName: 'ZCDS_ON_ASSOC41'
define view zcds_on_assoc4 with parameters airport: S_FROMAIRP as select from zcds_assoc4 as cds_assoc
    {
      cds_assoc.airportfrom,
      cds_assoc.name,
      cds_assoc.time_zone,    
      cds_assoc._spfli.carrid -- use inner join...by default association uses left outer join
    }
 where cds_assoc.airportfrom = :airport 

运行上面的CDS视图:

 

data preview中的结果:

 

为了把默认的left outer join变成inner join,我们需要使用[inner],如下:


@AbapCatalog.sqlViewName: 'ZCDS_ON_ASSOC41'
define view zcds_on_assoc4 with parameters airport: S_FROMAIRP as select from zcds_assoc4 as cds_assoc
    {
      cds_assoc.airportfrom,
      cds_assoc.name,
      cds_assoc.time_zone,    
      cds_assoc._spfli[inner].carrid -- use inner join...by default association uses left outer join
    }
 where cds_assoc.airportfrom = :airport 

如果运行它,输入参数RTM,得到的结果为空:

 

目前,还不可以在CDS association中使用right outer join。

CDS association中的过滤例子如下:

@AbapCatalog.sqlViewName: 'ZCDS_ASSOC_FILT'
define view ZCDS_ASSOC_FILTER  as select from zcds_assoc2 as cds2
    {
      cds2._sair[ id = 'TYO' ].name,
      cds2._sfli.planetype
    }

CDS视图的输出结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ᝰ随心ꦿེএ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值