AMDP selects false records contrary to OpenSQL

2.1k Views Asked by At

I am learning AMDP and I found out that the result obtained from this is very different from normal select query in ABAP AS. I am using below code in 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;

followed by APPLY_FILTER function. This query return multiple values in BUKRS_VF field. If I use normal select query like below:

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.

it generates required result.

Can anybody tell me why this difference between AMDP and normal select query?

3

There are 3 best solutions below

1
On

I just found out that adding

MANDT field solves the issue. i have added an pass by value parameter in method and used in query as

where a.mandt = im_mandt.

Dont know whether this is the correct solution.Please advise.

2
On

Many discrete useful pieces were given, but I am here to give a comprehensive answer to the question.

First of all, ABAP CDS views do not respect client data automatically like it is done in OpenSQL. BTW, the same is true for HANA CDS but judging on indirect indicators of your question it was about ABAP CDS based on HANA backend, rather that HANA CDS. Ya?

What is the proper way of client handling in ABAP CDS views?

  1. @ClientHandling.type #CLIENT_DEPENDENT annotation must be added to view. Default type is #INHERITED but for more straightforwardness it's better make it explicitly dependent.
  2. @ClientHandling.algorithm is an optional field and can be omitted. There is a complex set of rules which determines how the client is calculated but in your case you can just don't specify it, implicit #AUTOMATED way will be used and client column will be implicitly added to ON conditions of your JOIN.
  3. Client column must exist in view and should be either

    • selected via SELECT statement with either name or alias

    • have MANDT name manually set

    • if the latter is absent CLIENT column is used

    • if neither CLIENT nor MANDT column is not found the syntax error is thrown

  4. No other actions needed, client is addressed implicitly like in OpenSQL case.

But! Here we are speaking about AMDP procedure, not simple CDS, so the things are more tricky.

The first and foremost, for all this to work a special CDS SESSION CLIENT CURRENT AMDP declaration is mandatory in a method signature:

 AMDP OPTIONS READ-ONLY     
              CDS SESSION CLIENT CURRENT

the declaration makes implicit passing of $session.client var into the implementation of AMDP procedure. In the default CURRENT syntax variant it is equal to sy-mandt value of ABAP AS.

After that you can use $session.client explicitly with tables inside AMDP

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

or implicitly with client-dependent views

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

You don't HAVE to add the MANDT parameter to get the client number in AMDP/generated SQL script. Rather, you can use SESSION_CONTEXT('CLIENT')

So, your above query would look like the following:

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');

There are many more things you can achieve using SESSION_CONTEXT. Used properly, it's a powerful tool at your disposal.

Best Regards, Gopal Nair.