1

我正在学习 AMDP,我发现由此获得的结果与 ABAP AS 中的普通选择查询非常不同。我在 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 函数。此查询在 BUKRS_VF 字段中返回多个值。如果我使用如下的普通选择查询:

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 和普通选择查询之间存在这种差异?

4

3 回答 3

3

我刚刚发现添加

MANDT 字段解决了这个问题。我在方法中添加了按值传递参数并在查询中用作

其中 a.mandt = im_mandt。

不知道这是否是正确的解决方案。请指教。

于 2020-04-16T04:54:18.090 回答
2

给出了许多离散的有用部分,但我在这里对这个问题给出一个全面的答案。

首先,ABAP CDS 视图不像在 OpenSQL 中那样自动尊重客户端数据。顺便说一句,HANA CDS 也是如此,但根据您问题的间接指标判断,它是关于基于 HANA 后端的 ABAP CDS,而不是 HANA CDS。是吗?

在 ABAP CDS 视图中处理客户端的正确方法是什么?

  1. @ClientHandling.type #CLIENT_DEPENDENT必须添加注释才能查看。默认类型是#INHERITED,但为了更简单,最好让它显式依赖。
  2. @ClientHandling.algorithm是一个可选字段,可以省略。有一组复杂的规则决定了客户端的计算方式,但在您的情况下,您可以不指定它,#AUTOMATED将使用隐式方式,并且客户端列将隐式添加到ON您的 JOIN 条件中。
  3. 客户列必须存在于视图中,并且应该是

    • 通过带有名称或别名的 SELECT 语句选择

    • 手动设置 MANDT 名称

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

    • 如果没有找到 CLIENT 和 MANDT 列,则抛出语法错误

  4. 不需要其他操作,客户端像在 OpenSQL 案例中一样被隐式处理。

但!这里我们说的是 AMDP 程序,而不是简单的 CDS,所以事情比较棘手。

首先也是最重要的,为了让所有这些工作,一个特殊的CDS SESSION CLIENT CURRENT AMDP 声明在方法签名中是强制性的:

 AMDP OPTIONS READ-ONLY     
              CDS SESSION CLIENT CURRENT

该声明将 var 隐式传递$session.client到 AMDP 过程的实现中。在默认CURRENT语法变体中,它等于sy-mandtABAP AS 的值。

之后,您可以$session.client显式使用 AMDP 中的表

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

或隐式地使用依赖于客户端的视图

lt_vbak = APPLY_FILTER ("Z_CDS_VIEW", :iv_where);
于 2020-04-20T13:26:19.910 回答
1

您无需添加 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 可以实现更多的事情。使用得当,它是您可以使用的强大工具。

最好的问候,戈帕尔奈尔。

于 2020-04-20T03:37:02.767 回答