最近遇到了一個詭異的問題:從CDS視圖中取得的數據,和從透明表中取得的數據,會有不一樣的值。在這裏記錄下問題的表現和解決方案,以供參考。html
系統版本:S/4HANA OP1610sql
涉及表:MCHB數據庫
本文連接:http://www.cnblogs.com/hhelibeb/p/7346984.htmlpost
最近寫了一個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也好,統統查不到任何數據..ui
測試系統中毫無疑問是有着相應的數據的,怎麼會取不到呢。難道是條件語句出錯?抱着試試看的態度,我去掉了DDL代碼中的where條件。url
@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值呢?spa
爲了進一步證實兩者查詢結果的不一致,我寫下了如下的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查看該對象: