簡體   English   中英

AMDP 選擇與 OpenSQL 相悖的虛假記錄

[英]AMDP selects false records contrary to OpenSQL

我正在學習 AMDP,我發現由此獲得的結果與 ABAP AS 中的普通 select 查詢有很大不同。 我在 AMDP 中使用以下代碼:

ex_gt_data = select a.vbeln,
                   a.kunnr,
                   a.bukrs_vf,
                   b.erdat,
                   b.lsmeng,
                   b.posnr,
                   b.matnr
                   from vbak as a
                   join vbap as b
                   on a.vbeln = b.vbeln;

其次是 APPLY_FILTER function。 此查詢在 BUKRS_VF 字段中返回多個值。 如果我使用正常的 select 查詢,如下所示:

SELECT a~vbeln,
     a~bukrs_vf,
     a~kunnr,
     b~erdat,
     b~lsmeng,
     b~posnr,
     b~matnr
     FROM vbak AS a
     JOIN vbap AS b
     ON a~vbeln = b~vbeln
     INTO TABLE @DATA(lt_vbak)
     WHERE a~vbeln IN @s_vbeln.

它產生所需的結果。

誰能告訴我為什么 AMDP 和普通 select 查詢之間存在這種差異?

我剛剛發現添加

MANDT 字段解決了這個問題。 我在方法中添加了按值傳遞參數並在查詢中用作

其中 a.mandt = im_mandt。

不知道這是否是正確的解決方案。請指教。

給出了許多離散的有用部分,但我在這里對這個問題給出一個全面的答案。

首先,ABAP CDS 視圖不像在 OpenSQL 中那樣自動尊重客戶端數據。 順便說一句,HANA CDS 也是如此,但根據您問題的間接指標判斷,它是關於基於 HANA 后端的 ABAP CDS,而不是 HANA CDS。 是嗎?

在 ABAP CDS 視圖中處理客戶端的正確方法是什么?

  1. @ClientHandling.type #CLIENT_DEPENDENT注釋必須添加到視圖中。 默認類型是#INHERITED ,但為了更直觀,最好讓它顯式依賴。
  2. @ClientHandling.algorithm是一個可選字段,可以省略。 一組復雜的規則決定了客戶端的計算方式,但在您的情況下,您可以不指定它,將使用隱式#AUTOMATED方式,並且客戶端列將隱式添加到您的 JOIN 的ON條件中。
  3. 客戶列必須存在於視圖中,並且應該是

    • 通過帶有名稱或別名的 SELECT 語句選擇

    • 手動設置 MANDT 名稱

    • 如果后者不存在,則使用 CLIENT 列

    • 如果沒有找到 CLIENT 和 MANDT 列,則拋出語法錯誤

  4. 不需要其他操作,客戶端像在 OpenSQL 案例中一樣被隱式處理。

但是,這里我們說的是 AMDP 程序,而不是簡單的 CDS。 所以事情變得更加棘手。

首先,要使這一切正常工作,方法簽名中必須使用特殊的CDS SESSION CLIENT CURRENT AMDP 聲明:

 AMDP OPTIONS READ-ONLY     
              CDS SESSION CLIENT CURRENT

該聲明將$session.client var 隱式傳遞到 AMDP 過程的實現中。 在默認的CURRENT語法變體中,它等於 ABAP AS 的sy-mandt值。

之后,您可以將$session.client顯式用於 AMDP 中的表

SELECT * FROM vbak WHERE vbak.mandt = $session.client;

或隱式地使用依賴於客戶端的視圖

lt_vbak = APPLY_FILTER ("Z_CDS_VIEW", :iv_where);

您無需添加 MANDT 參數即可在 AMDP/生成的 SQL 腳本中獲取客戶端編號。 相反,您可以使用 SESSION_CONTEXT('CLIENT')

因此,您的上述查詢將如下所示:

ex_gt_data = select a.vbeln,
                   a.kunnr,
                   a.bukrs_vf,
                   b.erdat,
                   b.lsmeng,
                   b.posnr,
                   b.matnr
                   from vbak as a
                   join vbap as b
                   on a.vbeln = b.vbeln
                   and a.mandt = SESSION_CONTEXT('CLIENT');

使用 SESSION_CONTEXT 可以實現更多的事情。 使用得當,它是您可以使用的強大工具。

最好的問候,戈帕爾奈爾。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM