最近遇到了一個詭異的問題:從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)
通過調試器觀察資料,可以得到:
如圖所示,表MHCB至少存在多個clabs > 0的行。
接着,把SQL變成:
SELECT matnr, charg, lgort, werks, clabs FROM zci_test
INTO TABLE @DATA(gt_mchb)
結果中的clabs全部 = 0:
這下可頭疼了...百思不得其解之下,前往了SCN提問。
在熱心網友的提示下,我使用事務ST05追蹤了這兩個SQL,意外地發現了原因。以下是第一段Open SQL語句的追蹤結果:
注意紅框内的部分。雖然我的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,點選菜單欄的 附加——代理對象(也可能被翻譯成“替代對象”等..),在彈出視窗中檢視:
進入Eclipse檢視該對象:
相關閱讀:使用PlanViz進行ABAP CDS性能分析