Core data services(如下簡稱CDS)能夠指兩樣東西,一個是HANA CDS,一個是ABAP CDS。html
如咱們所知,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視圖開發過程當中,咱們經過編輯器(一般是ADT)在ABAP層聲明瞭咱們的字段結構和annotations。激活後,系統會自動地在數據庫層生成全部的SQL視圖。spa
ABAP CDS視圖提供多種SQL命令和函數的支持,若是你想要了解細節和所有的可用特性,建議你看這篇文章:ABAP CDS Feature Matrix。3d
在ABAP CDS Table Function的開發過程當中,咱們將字段結構、參數(可選)、association等經過類/方法定義爲實體。經過AMDP咱們能夠直接在ABAP層寫存儲過程,而且把它封裝在類/方法中,更多介紹能夠看以前的文章:ABAP中的AMDP(ABAP-Managed Database Procedures 。code
由於AMDP直接運行數據庫腳本,因此須要作幾個額外的步驟而且會使用到腳本語言(在HANA中即SQL Script)。稍後在示例部分咱們會討論配置的細節。htm
經過上文介紹的這兩種開發技術,咱們能夠開始開發一個技術示例了。按本文的例子作下去,你將會能夠建立你本身的ABAP CDS Table Function,而且爲不能直接經過ABAP CDS實現的需求提供解決方案。爲了實現示例,咱們會使用數據庫視圖SFLIGHTS,這一視圖提供了航班鏈接的細節。blog
每一個航空公司提供世界上不一樣城市的航班鏈接,用戶想要在單一字段中看到某一特定航空公司支持的全部城市,內容以逗號分隔。由於每家航空公司的城市數是不一樣的,咱們須要一個邏輯來拼接城市們,不管有查詢結果多少條數據。教程
在常規的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:
編輯生成的實體,包含如下內容:
結果應該是:
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.
在方法實現中咱們須要引入某些配置選項:
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 有少量改動