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 有少許改動