ABAP CDS Table Function介紹與示例


Core data services(以下簡稱CDS)可以指兩樣東西,一個是HANA CDS,一個是ABAP CDS

如我們所知,HANA CDS只支持HANA數據庫,ABAP CDS理論上支持多種數據庫供應商,結果是,ABAP CDS相比之下要少一些功能。因此,在某些情況下,無法使用ABAP CDS解決問題時,可以使用一種變通的方法,即通過ABAP Managed Database Procedures (AMDP)創建ABAP CDS Table Function

 

本文鏈接:http://www.cnblogs.com/hhelibeb/p/8057788.html

注:本文的主要理論內容已經包含在之前的AMDP介紹文章:ABAP中的AMDP(ABAP-Managed Database Procedures ) 中,相比它,本文更像一個step by step教程。

ABAP CDS視圖

在通常的ABAP CDS視圖開發過程中,我們通過編輯器(通常是ADT)在ABAP層聲明了我們的字段結構和annotations。激活后,系統會自動地在數據庫層生成所有的SQL視圖。

ABAP CDS視圖提供多種SQL命令和函數的支持,如果你想要了解細節和全部的可用特性,建議你看這篇文章:ABAP CDS Feature Matrix

ABAP CDS Table Function

在ABAP CDS Table Function的開發過程中,我們將字段結構、參數(可選)、association等通過類/方法定義為實體。通過AMDP我們可以直接在ABAP層寫存儲過程,並且把它封裝在類/方法中,更多介紹可以看之前的文章:ABAP中的AMDP(ABAP-Managed Database Procedures

因為AMDP直接運行數據庫腳本,所以需要做幾個額外的步驟並且會使用到腳本語言(在HANA中即SQL Script)。稍后在示例部分我們會討論配置的細節。

通過上文介紹的這兩種開發技術,我們可以開始開發一個技術示例了。按本文的例子做下去,你將會可以創建你自己的ABAP CDS Table Function,並且為不能直接通過ABAP CDS實現的需求提供解決方案。為了實現示例,我們會使用數據庫視圖SFLIGHTS,這一視圖提供了航班連接的細節。

場景

每個航空公司提供世界上不同城市的航班連接,用戶想要在單一字段中看到某一特定航空公司支持的所有城市,內容以逗號分隔。因為每家航空公司的城市數是不同的,我們需要一個邏輯來拼接城市們,無論有查詢結果多少條數據。

在常規的ABAP CDS內我們可以使用CONCAT函數,但是使用它的時候,我們需要定義固定數量的字段,既然CDS視圖不能實現此處需要的處理動態邏輯,要如何處理呢?

這是一個使用ABAP CDS Table Function的絕佳場景,因為我們可以使用簡單的數據庫函數STRING_AGG(String Aggregation)。這個功能在SQL Script中可用,但是目前還是不支持ABAP CDS視圖。

開發

打開你的HANA Studio(或者ADT),創建一個新的Core Data Services -> Data Definitio。

選擇project,package並且定義名字和描述:

選擇傳輸請求,然后點擊Next。在模板中選擇最后一個選項“Define Table Function with Parameters”,然后點擊Finish:

 編輯生成的實體,包含以下內容:

  • 字段:
    • Client
    • Airline Code
    • Airline Name
    • Cities To
  • : ZCL_FLIGHTS_DEMO_CDS
  • 方法: FLIGHTS_CONNECTIONS

結果應該是:

define table function ZDEMO_FLIGHTS_TABLE_FUNCTION
returns
{
  client       : abap.clnt;
  airline_code : s_carr_id;
  airline_name : s_carrname;
  cities_to    : abap.string;
}
implemented by method
  ZCL_FLIGHTS_DEMO_CDS=>FLIGHTS_CONNECTIONS;

 當然,現在ZCL_FLIGHTS_DEMO_CDS還不存在。下一步,讓我們創建它:

讓類包含IF_AMDP_MARKER_HDB接口。這一步會把你的ABAP類轉換為AMDP類,並且允許在類的方法內寫存儲過程。

  PUBLIC SECTION.
    INTERFACES if_amdp_marker_hdb.

在方法實現中我們需要引入某些配置選項:

  • BY DATABASE FUNCTION: 會將方法標記為table function,還有一個選項是通過 BY DATABASE PROCEDURE標記為存儲過程.
  • FOR HDB: 設定數據庫類型為HDB (HANA數據庫).
  • LANGUAGE SQLSCRIPT: HANA數據庫存儲的語言.
  • OPTIONS READ-ONLY: 存儲過程內不允許修改數據.
  • USING: 定義table function中消費的數據庫表、視圖或者存儲過程。在本例中,只訪問SFLIGHTS 視圖.
  METHOD flights_connections 
    BY DATABASE FUNCTION
    FOR HDB
    LANGUAGE SQLSCRIPT
    OPTIONS READ-ONLY
    USING sflights.

    <<你的代碼>>

  ENDMETHOD.

讓我們准備好查詢分割邏輯的兩個SELECT語句。

第一個SLECT需要獲取Client, Airline Code, Airline Name和City To字段,並通過DISTINCT關鍵字去重,因為我們會找到在不同的連接日期的相同的航空公司的城市記錄,如圖:

AMDP的優點之一是你可以將SELECT的查詢結果傳輸至“內表”,並且可以執行新的SELECT來讀取它的數據。讓我們應用這一功能的優點,並且將第一個SELECT的語句的查詢結果命名為itab_cities.

    itab_cities =
      SELECT DISTINCT 
             sflights.mandt    as client,
             sflights.carrid   as airline_code,
             sflights.carrname as airline_name,
             sflights.cityto   as city_to
        FROM sflights;

在第二個SELECT中,我們要從itab_cities中讀取數據並且實現數據庫方法STRING_AGG來聚合多個城市和航空公司。為了實現這一功能我們需要基於Client,Airline Code和Name字段GROUP BY條目。寫法是:

    RETURN
      SELECT client,
             airline_code,
             airline_name,
             STRING_AGG(city_to, ', ' ORDER BY city_to) as cities_to
        FROM :itab_cities
       GROUP BY client,
                airline_code,
                airline_name;

注意:table function應永遠有返回參數,所以記着在最后一個SELECT語句前放一個RETURN語句。另外,注意我們將字段名轉換為前文中ABAP CDS Table Function聲明的字段名,如果你沒有提供一個合適的別名,激活的時候編譯器會給出提示。

 

ZCL_FLIGHTS_DEMO_CDS的最終版本是這樣的:

CLASS zcl_flights_demo_cds DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    INTERFACES if_amdp_marker_hdb.

    CLASS-METHODS:
      flights_connections FOR TABLE FUNCTION zdemo_flights_table_function.

  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

CLASS zcl_flights_demo_cds IMPLEMENTATION.

  METHOD flights_connections
    BY DATABASE FUNCTION
    FOR HDB
    LANGUAGE SQLSCRIPT
    OPTIONS READ-ONLY
    USING sflights.

    itab_cities =
      SELECT DISTINCT 
             sflights.mandt    as client,
             sflights.carrid   as airline_code,
             sflights.carrname as airline_name,
             sflights.cityto   as city_to
        FROM sflights;

    RETURN SELECT client,
             airline_code,
             airline_name,
             STRING_AGG(city_to, ', ' ORDER BY city_to) as cities_to
        FROM :itab_cities
       GROUP BY client,
                airline_code,
                airline_name;

  ENDMETHOD.

ENDCLASS.

在Data Preview中的結果:

 

英文原文:Concatenate multiple records in a single field using ABAP CDS Table Function 有少許改動


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM