最近遇到了一個詭異的問題:從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查看該對象: