天天看點

ABAP CDS 替換對象(Replacement Objects)引起的資料錯誤

最近遇到了一個詭異的問題:從CDS視圖中取得的資料,和從透明表中取得的資料,會有不同的值。在這裡記錄下問題的表現和解決方案,以供參考。

系統版本:S/4HANA OP1610

涉及表:MCHB

本文連結:http://www.cnblogs.com/hhelibeb/p/7346984.html

最近寫了一個CDS視圖:

@AbapCatalog.sqlViewName: 'ZCI_TEST'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'QAQ'
define view ZTEST001_11 as select from mchb
{
matnr,
charg,
lgort,
werks,
clabs
}
where clabs > 0      

一段簡單得不能再簡單的代碼。但是在測試系統上使用時,問題發生了:無法從這個CDS view中查詢到任何資料。

無論是通過Open SQL代碼查詢也好、在SE16中查詢也好、将CDS view替換為CDS entity也好,通通查不到任何資料..

測試系統中毫無疑問是有着相應的資料的,怎麼會取不到呢。難道是條件語句出錯?抱着試試看的态度,我去掉了DDL代碼中的where條件。

@AbapCatalog.sqlViewName: 'ZCI_TEST'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'QAQ'
define view ZTEST001_11 as select from mchb
{
matnr,
charg,
lgort,
werks,
clabs
}      

這下子資料出現了,之前查不出資料的原因也出現了:在這個視圖中,所有行的clabs值均為初始值0。但在表MCHB中是存在clabs > 0 的記錄的,為什麼會僅僅因為通過CDS視圖查詢便得不到正确的clabs值呢?

為了進一步證明二者查詢結果的不一緻,我寫下了以下的SQL:

SELECT matnr, charg, lgort, werks, clabs FROM mchb 
INTO TABLE @DATA(gt_mchb)      

通過調試器觀察資料,可以得到:

ABAP CDS 替換對象(Replacement Objects)引起的資料錯誤

如圖所示,表MHCB至少存在多個clabs > 0的行。

接着,把SQL變成:

SELECT matnr, charg, lgort, werks, clabs FROM zci_test 
INTO TABLE @DATA(gt_mchb)       

結果中的clabs全部 = 0:

ABAP CDS 替換對象(Replacement Objects)引起的資料錯誤

這下可頭疼了...百思不得其解之下,前往了SCN提問。

在熱心網友的提示下,我使用事務ST05追蹤了這兩個SQL,意外地發現了原因。以下是第一段Open SQL語句的追蹤結果:

ABAP CDS 替換對象(Replacement Objects)引起的資料錯誤

注意紅框内的部分。雖然我的Open SQL中的FROM的目标是表MCHB,但ST05的記錄表明,實際上目标被重定向(Redirected)到了視圖“NSDM_V_MCHB”。

那麼,什麼是重定向呢?查閱文檔可以得知:

A CDS view can be assigned to a transparent database table and classic database view in ABAP Dictionary as a replacement object using the name of its CDS entity. A prerequisite is that the structure type defined by the CDS view matches the structure of the database table or classic view ...

也就是說,在系統支援替代對象的情況下,我們在ABAP Dictionary看到的表或者視圖,和在程式中通過Open SQL通路到的對象,未必是一個東西。SAP可以将一個替代對象(Replacement Objects)配置設定給标準的表和視圖。如這個詞的字面所示,當替代對象存在時,大部分對資料庫表的查詢通路會被重定向到替代對象之上。具體内容可以查閱文檔。

開發者也可以自己建立替代對象,但隻能配置設定給自定義表或視圖。

這一功能的存在和應用似乎和SAP對資料模型的調整有關。

相關note: 2206980 - Material Inventory Managment: change of data model in S/4HANA

      2242679 - Redirect inconsistency - Proxy Substitution

作為開發者,在建立CDS視圖的時候,我們需要意識到替代對象存在的可能性...如果一個資料庫表或視圖存在替代對象,而我們在寫DDL代碼的時候沒有注意這一點,便有可能從不準确的資料源擷取資料,進而産生錯誤。

要糾正上文中的CDS視圖代碼,就要把其中的MCHB改為NSDM_E_MCHB。

要如何得知一個資料庫表或者視圖是否存在代理對象呢?以表MCHB為例,可以進入事務SE11,點選菜單欄的 附加——代理對象(也可能被翻譯成“替代對象”等..),在彈出視窗中檢視:

ABAP CDS 替換對象(Replacement Objects)引起的資料錯誤

進入Eclipse檢視該對象:

ABAP CDS 替換對象(Replacement Objects)引起的資料錯誤

相關閱讀:使用PlanViz進行ABAP CDS性能分析

繼續閱讀