Sie sind auf Seite 1von 44

 SQL Functions

These are kind of functions which essentially are make or break. They are
not flexible enough to give you a third option. Simply put they return
LOGICAL or BOOLEAN result.

Sub Species are there as usual.

1. Numeric Functions

FUNCTION DEFINITION OUTPUT

In mathematics, the absolute value or


modulus |x| of a real number x is the
ABS(arg) Absolute amount
non-negative value of x without regard
to its sign

Smallest integer
Hitting the Ceiling of the Floating number not less
CEIL(arg)
Number. than the value of
arg

DIV(arg1, arg2) Conventional Division Quotient

Conventional Division but with an The result is


DIVISION(arg1, arg2, dec) additional feature of specificing rounded to dec
deicmal places decimal places.

MOD(arg1, arg2) Conventional Modulo Operation Remainder

Largest integer number not greater More like


FLOOR(arg)
than the value of arg. scientific numbers

Rounding the
Designated
ROUND(arg, pos) Rounded value of arg.
decimal point
value

2. Below code snippet on ABS, CEIL, FLOOR, DIV, DIVISION, MOD and
ROUND should help you understand the concept better.
@AbapCatalog.sqlViewName: 'ZFLIGHT_SCH_V'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Built In Functions'
define view ZFLG_FNC_DDL as select distinct from sflight as a
{
abs(-2) as Abs_Op,

/*Ceil and Floor*/


ceil(25.3) as Ceil_Op,
floor(25.3) as Floor_Op,

/*Division*/
div(5,3) as Div_Op,
division(5,3,5) as Div_Op2,
mod(5,3) as Mod_Op,

a.price as Flg_Price,
round( a.price,1) as Round_Op
}
Please check each output. Did you notice Ceil is 26 for a number 25.3 while
Floor is 25 for the same number 25.3.

2. String Functions

SAP has been very kind to String somehow. Poor Numbers.


Let’s not talk much but let the code do the talking here.

@AbapCatalog.sqlViewName: 'ZSTR_FN_V1'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Built In Functions'
define view ZFNC_DDL as select distinct from makt as a
{
key a.matnr as Mat_Num,
a.maktx as Mat_Desc,
length( a.maktx ) as Des_Len,
instr( a.maktx, 'est' ) as Des_Find,
concat( a.maktx, a.spras ) as Des_Con,
concat_with_space( a.maktx, a.spras, 2 ) as Des_Con_space,
left( a.maktx, 3 ) as Des_left,
lower( a.maktx ) as Des_lower
}

Part 1 of Strings:
Function Description

Length gives Length of String

finds the position of respective string within


Instr
corresponding the field of the View

Concatenate joining two strings

Concatenate with Third Parameter in this function represents the


Space Number of space between two strings

gives us left most characters equal to argument


Left
passed

Lower converts all into lower case [ Rather Subscript ]

Now, wondering where are the complementing string functions??? They are
below.

@AbapCatalog.sqlViewName: 'ZSTR_FN_V1'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Built In Functions'
define view ZFNC_DDL as select distinct from makt as a
{
key a.matnr as Mat_Num,
a.maktx as Mat_Desc,
right( a.maktx, 5 ) as Des_right,

/*For Strings */
lpad( a.maktx, 6, 'xx' ) as Des_lpad,
rpad( a.maktx, 6, 'y' ) as Des_rpad,
ltrim( a.maktx, 't' ) as Des_ltrim,
rtrim( a.maktx, 't' ) as Des_rtrim,
replace( a.maktx, 'est','ough' ) as Des_replace,
substring( a.maktx, 2, 1 ) as Des_substring,
upper( a.maktx ) as Des_upper
}

Check how conveniently you can play around with the strings using lpad,
rpad, ltrim, rtrim, replace, substring, upper etc. They come really handy in
actual projects.
ABAPers !!! How on this earth can we forget our traditional methods working
with Conversion FMs ??? Isn’t it???

Well, those are replaced by Padding and Trimming – Both sides Left and
Right.

Function Description

first parameter is field, second is the OUTPUT Length


Lpad & Rpad
after padding, string that is to be padded

first parameter is field, second is string or character


Ltrim & Rtrim
that is to be removed

second parameter finds the string to be replaced by


Replace
the third

finds the string that you want – second parameter is


Substring
starting position and third is how many characters

Upper converts all characters of string into Upper case

Points to Remember:

a. In Padding, the Output Length needs to be greater than Length of existing


field to enable padding. Else, we will have a trimmed output.

b. Padding and Trimming can be used for Numerical Values as well.

c. Only a Single Character needs to be given for trimming.

Example:
define view ZFLG_FNC_DDL as select distinct from sflight as a
{
key a.connid as Flg_Connid,

/*For Numericals */
lpad( a.connid, 6, '22' ) as Flg_lpad,
rpad( a.connid, 6, '99' ) as Flg_rpad,
ltrim( a.connid, '0' ) as Flg_ltrim,
a.fldate as Flg_Date,
rtrim( a.fldate, '8' ) as Flg_rtrim
}

Bonus Segment:

Requirement : “Change the data retrieved for Flight Time from Total
Minutes to Hours:Minutes Format”

How about complicating our lives? Actually, it may be the way to simplify.
Let’s give a try.

Initial Code and Output :

@AbapCatalog.sqlViewName: 'ZFLIGHT_SCH_V'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Built In Functions'
define view ZFLG_FNC_DDL as select from spfli as a
left outer join sgeocity as b
on a.cityfrom = b.city
{
key b.city as Source,
key b.city as Destination,
key a.carrid as Flg_ID,
key a.connid as Flg_Conn,
a.fltime as Flg_Time
}

Functions can be handy here…Check out the code below which would suffice
our requirement.
@AbapCatalog.sqlViewName: 'ZFLIGHT_SCH_V'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Flight Schedule Details'
define view ZFLG_FNC_DDL as select from spfli as a
left outer join sgeocity as b
on a.cityfrom = b.city
{
key b.city as Source,
key b.city as Destination,
key a.carrid as Flg_ID,
key a.connid as Flg_Conn,
concat( concat(lpad ( ltrim ( cast( div(a.fltime, 60) as abap.char( 12 ) ), '0' ), 2, '0' ), ':'
),
lpad ( ltrim ( cast( mod(a.fltime, 60) as abap.char( 12 ) ), '0'), 2, '0' ) ) as Flg_Time
}

The above one line string function is just an example of how you can play
around with any requirement. Break the code from center and go outward. It
is self-explanatory.

1. Unit Conversion Functions


2. Currency Conversion Functions
3. Decimal Shift Functions
4. Date and Time Conversion Functions – which decide the fate of
everything in the world, sometimes good and sometimes otherwise.

Seldom we see these being used. But then application of knowledge should
not be seldom.

 First parameter MUST and should be a quantity field.

 Second and Third parameters MUST and should be unit fields.

Point to remember: Never run the CDS where there is absolutely NO


relation between Source and Target Field. Being adventurous has it’s own
risk. Here, DUMP.
@AbapCatalog.sqlViewName: 'ZUNIT_FN_V'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Test Unit Funtions'
define view ZUNIT_FN
as select distinct from mara as a
{
key a.matnr as Material,
a.brgew as MatQuan,
a.meins as SrcUnit,
a.gewei as TgtUnit,
unit_conversion( quantity => brgew,
source_unit => meins,
target_unit => gewei ) as ConvF1
}
where a.matnr > 'CH-6000'
and a.matnr < 'CH-6600';

Creating example was an uphill task.


Reason: Finding test data and executing the scenario was the most
challenging part of this entire blog. I am glad and relived to overcome
anxiety.
CDS View code fetching Material, corresponding unit for conversion and converted field.

As the name says, the currency of the amount/price field is converted from
source (as stored at the database) currency to end user/input currency.

Pretty straight forward to implement. 4 parameters – Mark it “All are


mandatory“. No escape.

Now, let’s give two target currencies. First USD and other INR.

There is some absurd and strange thing. Let’s apply some common sense. The exchange rates
keep fluctuating as a pendulum of the clock. I gave a future exchange date (Note : 31-01-
2019).
Astonishing as it may sound, SAP has been able to predict even the market
exchange price for a FUTURE DATE (31-01-2019 on Jan 28, 2019) !!! Not
sure how it is getting picked. Anyone who is aware please comment and let
us and the rest of the world know.

Forgetting that bug, lets check the next set:

Some background. For certain currencies like JPY, HUF, KRW, COP there is
a difference how the external world stores value than internal.

In TCURX table, JPY is set with 0 decimal. EUR doesn’t exist in the table, that
is, default to 2 decimal.

@AbapCatalog.sqlViewName: 'ZDEC_SHFT_V'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: false
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Test Currency Conversion'
define view ZDEC_SHFT
with parameters p_amt : abap.curr( 5, 2 )
as select distinct
from sflight as a{
key a.carrid as FlgID,
key a.connid as FlgConID,
key a.fldate as FlgDat,
a.currency,
decimal_shift( amount => :p_amt, currency => a.currency ) as DEC_SHFT
}

From the above two pictures it is quite evident that the input : 21.34 was
interpreted differently in accordance with the corresponding currencies.

We would like to end this article here. Yes, we know, we promised four
points. For the last bullet point, we would prepare a detailed tutorial on Date
and Time Functions in our next blog. So, please stay tuned.

Till then enjoy your new found love in the form of ABAP Programming for
S/4HANA and tune back to us for some explanation or the curious currency
conversion function.

DAY, MONTH and YEAR. We are limiting our discussion to first two in this
article. Let’s get started.

1. ADD DAYS
2. ADD MONTHS
3. DAYS BETWEEN TWO DATES
4. DATE VALIDATION

1. ADD DAYS:

Do you recall? There are some numbers on either side of the great “0” on
number line, called as INTEGERS. That’s the hint to define ADD_DAYS in CDS
Views.

Yes, absolutely. ADD_DAYS can be used not just for adding but also
SUBTRACTING.

Thumb rule of ADD_DAYS function is, one needs to pass:


i. First Parameter : Date to which days to be added
ii. Second Parameter : Number of Days to be added
iii. Third Parameter : Error Handling- Four values can be :

 “FAIL” (an error raises an exception)


 “NULL” (an error returns the null value)
 “INITIAL” (an error returns the initial value)
 “UNCHANGED” (an error returns the unmodified value of date)
 2. ADD MONTHS

Straight forward with three parameters. One each for input date,
number of months to be added and error handling respectively.

Names can be misleading . One can even subtract.

 3. DAYS BETWEEN TWO DATES

Don’t be smart here. Never calculate the days between two DATES. It
can ruin your day.

Back to CDS, two inputs, one for first extreme and other for other
extreme.

4. DATE VALIDATION

What more can you ask, this can be used to validate the date and
know whether your DATE was valid ( if not, just WISH to have another
) or NOT.

Output returns either “1” or “0”.

 For all the above functions ONE Code Example is used. But to provide
an enthralling and excruciating experience, we have MORE than ONE
Test Case.

 CODE SNIPPET:
@AbapCatalog.sqlViewName: 'ZDT_TIME_FN_V'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Test Date and Time'
define view ZDT_TIME_FN
with parameters p_add_days : abap.int4,
p_add_months: abap.int4,
@Environment.systemField: #SYSTEM_DATE
p_curr_date : abap.dats
as select from sflight as a {
key a.carrid as FlgId,
key a.connid as FlgConnId,
key a.fldate as FlgDate,
dats_add_days (a.fldate, :p_add_days , 'INITIAL') as Added_DT,
dats_add_months (a.fldate, :p_add_months, 'NULL' ) as Added_MT,
dats_days_between (a.fldate, $parameters.p_curr_date ) as Days_BTW,
dats_is_valid (a.fldate) as Is_Valid
}

Very
IMPORTANT : Observe that parameter “P_CURR_DATE” does not have an asterisk. Me
ans that it is not a mandatory to provide . Then we have two ways to deal. One leave blank
and other to forcefully provide a date. Second case has been dealt in next example.
Wondering why the “-735740” was given in P_ADD_DAYS …..There is
something called as BVA in Software Testing…Go and check it out for
yourself what does that mean.

Now then….Let it be loud and clear there is a BUUUGGG !!! Second consecutive time we
are proud to point out that SAP cannot be foolproof. Look closely. We should have ideally
got INVALID.
Now, let’s analyse what we have done:

Input Date considered Expected Output Observation

-735740 2015-05-20 00010101 00000000 BUG

-735740 2015-05-21 00010102 00010102 As per expectation

BONUS SEGMENT:
(the special segment which we promised above) .. disappointed?

In continuation with the previous topic, in this section we will explore two
more functions.

5. DATS_TIMS_TO_TSTMP

Huge list of parameters (just 5) needs to be passed in order to combine


date and time AND also convert to different timezone.

First input is date, second is time, third timezone, fourth client and finally
error handling.

6. TIMEZONE

Straight as an arrow, just pass the session client and get system’s Time
Zone.

Note: It is very important to pass Client while working in HANA.

TEST CASE 3:
@AbapCatalog.sqlViewName: 'ZDT_DT_TIME_FN_V'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Test Date and Time 2'
define view ZDT_DT_TIME_FN
with parameters @Environment.systemField: #SYSTEM_DATE
p_curr_date : abap.dats
as select from sflconn as a{
key a.agencynum as FlgAgy,
key a.flconn as FlgCon,
a.arrtime as FlgArr,

//Convert Arrival Time


dats_tims_to_tstmp
($parameters.p_curr_date,
a.arrtime,
abap_system_timezone( $session.client,'NULL' ),
$session.client,
'NULL') as Flg_Arr_Conv,

abap_system_timezone( $session.client,'NULL' )
as MyTimeZone
}

As usual we need test and validate. It has become a custom which can be
broken, but I will refrain

VALIDATION:
Time was picked from the database table. However, date was system date.

With that we come to an end of another article. Hope as promised earlier


your fate and mine would change.
Different Aspects:

 Literals
Other name Constants. They are of Two kinds viz Numeric and Character.

Eg. Numeric : 1000, 52 ; Character : ‘SAP Yard’,’Europe’, ‘HANA’, ‘Ruthvik’.

 Fields of Data Sources


If put simple, they are the fields of the database tables. But, they too have
an ALIAS, that is ALIAS. Come on !!! I meant, an alternative name that is in

turn ALIAS. It’s like Alias of Ruthvik is Ruthvik.

VIP (Very Important Point) – ALIAS play a very important role while we
create Associations between different CDS Views/Database Tables.

Do brush up your Associations concepts.

 Parameters
Anything that a user is expected to provide as input to CDS, qualifies as a
parameter. Remember that CDS is PARAMETERISED!!!

The parameter must be prefixed by a colon (:) or $parameters.

In order to code with parameters, the code temple can be obtained


automatically while creating CDS View itself. Huh!! Programmers do not need
to by-heart them

Session variables
ABAPer’s blood sample will surely have “SY-SUBRC”, a system variable.
SAP is very strict, diktat is like “The variable is case-sensitive.
$session.vname, $Session.Vname, and $SESSION.VNAME can all be used. No
other spellings are allowed.” Same goes with CDS, session variables.
Following are examples:

Variable Usage

user Current user name, nominal value of the ABAP system field sy-uname

Current client. The default value is the nominal value of the ABAP
system field sy-mandt. In reads with an Open SQL statement (with the
client statement USING CLIENT) and in calls of an AMDP method from
ABAP (in whose declaration the addition AMDP OPTIONS CDS
SESSION CLIENT is specified), the value specified here.

Text environment language of the current internal session, nominal


system_language
value of the ABAP system field sy-langu

Current system date of the AS ABAP, nominal value of the ABAP


system_date
system field sy-datum

 Case distinction
Self Explanatory. Following can give you an idea :

1
2 Simple case distinction1. ... CASE operand
3 WHEN operand1 THEN result1
4 [WHEN operand2 THEN result2]
5 ...
6 [ELSE resultn]
7 END ...Complex case distinction2. ... CASE WHEN cond_expr1 THEN result1
8 [WHEN cond_expr2 THEN result2]
9 [WHEN cond_expr3 THEN result3]
10 ...
11 [ELSE resultn]
12 END ...
 Conditions
Well, Well, this is interesting. The logical way of coding. How ?
Only two possible results – TRUE or FALSE. RIGHT or WRONG.
ABAP_TRUE or ABAP_FALSE. UNDERSTAND or DONT UNDERSTAND.

The following are the variants:

 Comparisons with relational operators

Operator True if

lhs = rhs Value of lhs is equal to the value of rhs

lhs <> rhs Value of lhs is not equal to the value of rhs

lhs < rhs Value of lhs is less than the value of rhs

lhs > rhs Value of lhs is greater than the value of rhs

lhs <= rhs Value of lhs is less than or equal to the value of rhs

lhs >= rhs Value of lhs is greater than or equal to the value of rhs

 Interval comparisons. Remember RANGES is ABAP ?? Yes, that is


how intervals are captured.Simple in Open SQL, we have ‘BETWEEN‘
as keyword.
When simplified it takes the following form:

1
2 "... lhs >= rhs1 AND lhs <= rhs2 ... ".

 Pattern comparisons. We all know (at least that is expected), how


CS, CP, NS, NP so on work….Don’t know? OKAY. Those are used on
strings or character variables. (Wont be telling more). Basic Rules in
SQL:
– Only character-like data types can be used
– Only character-like literals without domain prefix are allowed
– The wildcard characters % for any strings and _ for any character can
be used in the pattern

Note : Additionally we have something called as ESCAPE character.


Syntax is as follows:

1
2 ... lhs LIKE rhs [ESCAPE esc]...

 Checks on the NULL Value

1
2 .... lhs IS [NOT] NULL ...

Also Read – Create your First SAP OData Service

Time for an example to cover all the above.

1
2 @AbapCatalog.sqlViewName: 'ZFLG_CDS_OP_V'
3 @AbapCatalog.compiler.compareFilter: true
4 @AccessControl.authorizationCheck: #NOT_REQUIRED
5 @EndUserText.label: 'Operations'
6 define view ZFLG_CDS_OP
7 with parameters p_date : abap.dats
8 as select from sflight as a
9 {
10 key a.carrid as FlgCarr,
11 key a.connid as FlgConn,
12 key case ( a.planetype )
13 when '737-400' then 'BOEING'
14 when 'A340-600' then 'AIRBUS'
15 else 'OTHERS'
16 end as FlgType,
17 key a.fldate,
18 case
19 when a.price is null then 'error'
20 when a.price &lt; 200 then 'Budget'
21 when a.price &gt;= 200 and
22 a.price &lt; 400 then 'Business'
23 else 'Very Costly'
24 end as flight_type,
25 $session.system_language as Language
26 }
27 where a.fldate = $parameters.p_date;

Once you code and check what has been used:

**Not Marked in the above screenshot. Literals, Alias. Please search them.

. If you cannot find, leave your comment. We will respond.

Excited to know the result !!! Do a Data Preview.

It just gets longer. Culprit ??? Parameter.

This is an unique feature we shall be missing every time we discuss. Never


Forget

Provide the date. I knew it before hand.. I had already run my code without
parameter.

Result :
Following need a lot of emphasis and examples.

 Arithmetic expressions
 Aggregate expressions
 Type Casting

Hence we have planned to dedicate a separate article for it and handle it in


our next post. Part II of this series. So, please stay tuned.

If you are ready, let us continue from where we left.

1. Arithmetic Expression
Straight Forward. Addition/Subtraction/Multiplication/Division. Let’s
recall BODMAS rule which you learned in your elementary school.
Period.S o WHAT’S new ???

We have a prefix operator ‘-‘, which can be attached to a numeric


field and it translates to

2 'Field Value' * '-1' = -'Field Value'

2. Aggregate Expressions

Most IMPORTANT concept probably of the entire HANA-ABAP.

It assumes a lot of importance in wake of the fact that HANA DB has


Column Based Storage of Data in Tables.

Let’s check what is there in store for us in this part of the story.

Aggregate Function Usage

MAX Finds the Greatest value of a particular field

MIN Finds the Least value of a particular field of operand

AVG Finds the Average value of a particular field

SUM Sum of a particular field

If DISTINCT operand is specified, the number of distinct values of


COUNT
operand; if * is specified, the number of rows in the results set.

Also Read – Create your First SAP OData Service

This requires us to do some programming to understand in depth and


convincingly.
1

2 @AbapCatalog.sqlViewName: 'ZFLG_CDS_OP_V'

3 @AbapCatalog.compiler.compareFilter: true

4 @AccessControl.authorizationCheck: #NOT_REQUIRED

5 @EndUserText.label: 'Operations'

6 define view ZFLG_CDS_OP

7 as select from sflight as a

8{

9 key a.carrid as FlgCarr,

10 max( a.price ) as MaxPrice,

11 min( a.price ) as MinPrice,

12 avg( a.price ) as AvgPrice,

13 sum( a.price ) as SumPrice,

14 count( * ) as TotalCount

15 }

OH WAIT !! I have a committed some crime here.

Yupp, no excuse. There needs to be Community Service. What is it? Discuss


Group By.

GROUP BY

We at SAPYard always believe in unconventional explanations. Let’s


understand with the help of an unassuming example.
Eg. Say there is a group of animals. Need to have a way to differentiate
them. What you do? Group them. Like, Flock of Birds, Herd of Zebra, Group
of Female Lions – a PRIDE, Group of Male lions – a Coalition.

Effectively you put things of similar objects together, so that we can


easily take a count, find the extremes like minimum or maximum, look for
the median like average and so on.

Hope you have some idea now, why we need Group By.
Back to example. I modified adding group by ‘CARRID’. Meaning we shall be
finding all the Aggregate Function value for each ‘CARRID’.

2 @AbapCatalog.sqlViewName: 'ZFLG_CDS_OP_V'

3 @AbapCatalog.compiler.compareFilter: true

4 @AccessControl.authorizationCheck: #NOT_REQUIRED

5 @EndUserText.label: 'Operations'

6 define view ZFLG_CDS_OP

7 as select from sflight as a

8{

9 key a.carrid as FlgCarr,

10 max( a.price ) as MaxPrice,

11 min( a.price ) as MinPrice,

12 avg( a.price ) as AvgPrice,

13 sum( a.price ) as SumPrice,

14 count( * ) as TotalCount

15 } group by a.carrid

16
Now let’s see the initial output:

Total Count for Flight Carrier ‘AA’ is 26 and ‘DL’ is 39.

 NOTE: The format of Average Price is converted in Decimal and we


had no control of how exactly we could display. But, we can. That’s
in next section. Type Casting.

Important Considerations while Using Group By:

i) All the Key fields defined in the CDS needs to be part of Group By
Clause.

I included another field ‘CONNID’ as a key field and see the difference.

2 @AbapCatalog.sqlViewName: 'ZFLG_CDS_OP_V'

3 @AbapCatalog.compiler.compareFilter: true

4 @AccessControl.authorizationCheck: #NOT_REQUIRED

5 @EndUserText.label: 'Operations'

6 define view ZFLG_CDS_OP

7 as select from sflight as a


8{

9 key a.carrid as FlgCarr,

10 max( a.price ) as MaxPrice,

11 min( a.price ) as MinPrice,

12 avg( a.price ) as AvgPrice,

13 sum( a.price ) as SumPrice,

14 count( * ) as TotalCount

15 } group by a.carrid, a.connid

We see that now the aggregate functions behave differently, because all
calculations are done by first picking Carrier ID and then Connection ID.
Please note the total count is 26 in both cases for Flight Carrier ‘AA’.
Similarly the total count is 39 for Flight Carrier ‘DL’.

ii) The Group By can be enhanced by adding HAVING.

1
2 @AbapCatalog.sqlViewName: 'ZFLG_CDS_OP_V'
3 @AbapCatalog.compiler.compareFilter: true
4 @AccessControl.authorizationCheck: #NOT_REQUIRED
5 @EndUserText.label: 'Operations'
6 define view ZFLG_CDS_OP
7 as select from sflight as a
8{
9 key a.carrid as FlgCarr,
10 key a.connid as FlgConn,
11 max( a.price ) as MaxPrice,
12 min( a.price ) as MinPrice,
13 avg( a.price ) as AvgPrice,
14 sum( a.price ) as SumPrice,
15 count( * ) as TotalCount
16 } group by a.carrid, a.connid
17 having a.carrid = 'AA'

3. Type Casting Expressions

Another important concept that is quite handy while manipulating data is


Type Casting. The original data type can be changed to another (infact forced
to change). The following is the curated list (out of a longer list) that can be
useful:

Data Type Description

abap.char( len ) CHAR with length len

abap.clnt[(3)] CLNT

abap.cuky( len ) CHAR with length len

abap.curr(len,decimals) CURR with length len and decimals decimal places

abap.dats[(8)] DATS

abap.dec(len,decimals) DEC with length len and decimals decimal places

abap.fltp[(16,16)] FLTP

abap.int1[(3)] INT1

abap.int2[(5)] INT2

abap.int4[(10)] INT4

abap.int8[(19)] INT8

abap.lang[(1)] LANG

abap.numc( len ) NUMC with length len

abap.quan(len,decimals) QUAN with length len with decimals decimal places

abap.raw(len) RAW

abap.sstring(len) SSTRING

abap.tims[(6)] TIMS
abap.unit( len ) CHAR with length len
Authorizations in CDS Views
Access Control or Authorization in another dimension worth mention
when it comes to SAP ABAP CDS (Core Data Services). Let’s see what is
on offer in CDS (exiting feature) which gives us an opportunity to explore the
options available to limit the access.

Are you new to CDS? Check Frequently Asked Questions in CDS View for
Beginners.

Also Read – Deep Dive into CDS Views

Before we start it is customary for us to know some jargons (textbook

definitions, excuse me )

DCL: Data Control Language(DCL) is used for controlling privileges in


Database operations.

Two Kinds of Privileges are provided to any user:


1. System, and
2. Object.

1. System Access or privilege to use any SAP Server is mostly taken


care by SAP Security Folks (we don’t need to bother much about this,
but if you are adventurous to know what roles and authorizations have
been given to you, go to SU01D T-Code to explore yourself).
2. Next Authorization Objects or Access to certain T-Codes are given on
need basis. We can create them in SU21 and use them (This can be
another topic of interest altogether).

GRANT: Used for providing any user access privileges or other privileges for
the database operations.

REVOKE: Used for taking back permissions from any user.


ROLE: Special permission created by system admin for accessing
(display/change/create) any particular T-Code or ABAP Object. These shall be
maintained in T-Code PFCG.

For now, we shall concentrate only about ABAP CDS View Authorization.

Getting our hands dirty is the way forward. Following steps will give an
experience of how DCL, elder brother of SQL can protect DDL, his younger.

STEP 1: Simple Sample CDS View was created with join between SFLIGHT
and SFLCONNPOS.

Note – Authorization Check Annotation has been given “#NOT_REQUIRED”


in Access Control.

1
2 @AbapCatalog.sqlViewName: 'ZCDS_ACCNTRL_DDL'
3 @AbapCatalog.compiler.compareFilter: true
4 @AccessControl.authorizationCheck: #NOT_REQUIRED
5 @EndUserText.label: 'CDS to Test Access Control'
6 define view ZCDS_TEST_ACCESS_CTRL as
7 select from sflight as a
8 inner join sflconnpos as b
9 on a.carrid = b.carrid
10 {
11 key a.carrid as MyFlightCarrier,
12 b.agencynum as MyAgencyNumber
13 }
Also Read: Write your first Program in S/4HANA.

STEP 2: Follow the below to create a DCL object for CDS View.

By default the following screen appears once you finish creating [good

feature by Eclipse for lazy people (like me) so that we don’t code]
What we noticed (from experience) is that we have 3 approaches available
for us to utilize. Do not worry, each of it has been covered below.

Approach 1 : Using just the View Name [Smarter people say Full
Access]

No Restrictions apply here. Just go and just provide your CDS View Name.
Nothing much to tell other than that WARNING !!!

It is best seen from the below description I got from the editor :
This warning tells that the User (ABAP developer) has not been mapped to
this DCL.

Also Read – Is BDC still available in S/4HANA?

What we can infer is that the above approach 1 is somewhat not much useful
for us. Thus, let’s fast forward to Approach 2.

Approach 2 : Using the Where Clause [Experts say using Literal


Conditions]

Before we deep dive, let’s see that data preview of the CDS Views:
The result set has entries for the following Flight Carriers:

Amused how I got it ??? Follow this : Right Top Corner of Data Preview ->
Add Filter -> Click on MyFlightCarrier -> Click on ” … ” -> Voila you got it !!!

Now if you are still not exhausted, continue to make a change in DCL.
Do the following:

Code Snippet :

1
2 @EndUserText.label: 'role_label'
3 @MappingRole: true
4 define role role_name {
5 grant select on ZCDS_TEST_ACCESS_CTRL
6 where MyFlightCarrier = 'DL' ;
7 }

Run Data Preview to see the Magic (well not really, you wrote the code and

got the output, no big deal Ahh!).

Be Happy anyway. You have done something (well me in this case).

Also Check: Complete custom program with SELECT OPTIONs and


APPLY_FILTER in AMDP.
Next, very important. Let’s be into some serious business now. T-
Code PFCG.

Approach 3 : Using PFCG authorizations [I say the same as others do]

Before you begin this, I suggest you to have a look on what is PFCG for some
important information.

But, more importantly for us is T-Code SU21. Navigate to find Auth Object
S_CARRID (as shown below with details).

Now time to muscle our efforts into DCL. Use this :


1
2 @EndUserText.label: 'role_label'
3 @MappingRole: true
4 define role role_name {
5 grant select on ZCDS_TEST_ACCESS_CTRL
6 where ( MyFlightCarrier ) =
7 aspect pfcg_auth (s_carrid, carrid, actvt='03');
8 }

Data Preview of CDS View:

All said and done. Now question remains, what have we achieved here?
Nothing. Why? That’s because we have not mapped our user ID
exclusively for this authorization object.

So, what we need to do is :


1. Create own authorization objects
2. Tell Basis Folks to assign that to a particular ID
3. Check the difference between ID with and without authorization.

Also Read: What is Code Push Down?

Conclusions:

There are other possibilities other than above three approaches namely,

Fourth Approach : Combination of Literal and PFCG authorizations

Code :

1
2 @EndUserText.label: 'role_label'
3 @MappingRole: true
4 define role role_name {
5 grant select on ZCDS_TEST_ACCESS_CTRL
6 where ( MyFlightCarrier ) = <span class="token keyword">aspect</span> pfcg_auth
7 <span class="token punctuation">(</span>s_carrid<span class="token
punctuation">,</span> carrid<span class="token punctuation">,</span> actvt=<span
class="token string">'03'</span><span class="token punctuation">)</span> <span
class="token keyword">and</span>
MyFlightCarrier = 'LH' ;

Fifth Approach : Inherited Authorization

Code : Need to Explore still. Let me know in comment section.

Sixth Approach : Current User Authorization

CDS View :

1
2 @AbapCatalog.compiler.compareFilter: true
3 @AbapCatalog.sqlViewName: 'ZCDS_ACCNTRL_DDL'
4 @AccessControl.authorizationCheck: #CHECK
5 @EndUserText.label: 'CDS to Test Access Control'
6 define view ZCDS_TEST_ACCESS_CTRL as
7 select from sflight as a
8 inner join sflconnpos as b
9 on a.carrid = b.carrid
10 {
11 key $session.user as MyName,
12 key a.carrid as MyFlightCarrier,
13 b.agencynum as MyAgencyNumber
14 }

DCL :

1
2 @EndUserText.label: 'role_label'
3 @MappingRole: true
4 define role role_name {
5 grant select on ZCDS_TEST_ACCESS_CTRL
6 where MyName ?= aspect user; }

Few interesting things.

We can have multiple DCL for same CDS views. Try it.

Note: Use same CDS view name in all DCL sources, but have different role
names.
SEGW is the t-code to create OData Projects and eventually publish an
OData Service.

But would you not be surprised if we say, you can create your OData Projects
without going to SEGW transaction? Today, we would show you how you can
expose CDS View as OData Services with just some Annotations (i.e
SQL code).

Introduction
We have substantially explored the CDS views with major functionalities.
CDS provides another magical strength to the users to expose the views as
OData services. There is a conventional way to create a service in SEGW
importing the view you created.

This article presents a technique to expose a view as a gateway service just


by maintaining a cool annotation. No need to create service through SEGW.
Sounds amazing? Let’s see how we can achieve that.

Technical Environment
For CDS views we have used Eclipse Luna.
OData version 2 has been used for gateway application.

Step – I :
Create a view with a left outer join between tables VBAP and MARA. We have
considered VBAP as ‘soitem’ and MARA as ‘prod’. A left outer join between
two will allow you to select any fields from these two tables. For simplicity,
we took only the fields mentioned in the key.
Fig.1-Create First View

Step – II :
Create a second view with Association. Associations in CDS views are more
like associations in Gateways. You create an association to conceptually
join or associate one data source to a target data source on a
condition provided. If data sources can be envisaged as Entities of OData
service then associations are joining two entities conceptually.
Fig.2- Create view with Association and OData Annotation

Take special note of the Annotation at the 6th line: @OData.publish: true.

This is the magic spell for our article today.

Step – III :
Now our view is ready. With the DDL view we should be able to see data
from Header table VBAK, Item table VBAP and Product table MARA.
Fig.3- DDLS view
Fig.3- Data from the view

Step – IV :
Note, once you activate the view you will be able to see an icon beside the
annotation (6th line) “@OData.Publish: true” which reads that you need to
register the service through /IWFND/MAINT_SERVICE.
Fig.4- OData Exposure in View

Step – V :
Now, as instructed go to transaction /IWFND/MAINT_SERVICE in the gateway
system to register the service created through CDS.
Fig.5- Find Service in /IWFND/MAINT_SERIVCE

Step – VI :
Once the service is found, click on the service to register and save it in the
appropriate package. Note we have not used SEGW to create any
service. This service got automatically generated due to OData
Annotation maintained.

Fig.6- Register Service


Step – VII :
Now test your service through /IWFND/GW_CLIENT transaction using
proper OData query. Note, for navigation unlike usual gateway, we are using
‘to_<association name>’ in the query to navigate to the second data set.
Since we created vbeln as an association condition in our
‘ZTEST_ASSOC_VIEW2’ the value needs to be passed through OData query
for data fetching.
Fig.7- Test Gateway Data Fetch

Limitations
Please also be informed that this service can only provide GET operation.
No other CRUD operations can be done with this CDS view OData Exposure.

Usually, CDS views are created for fetching data (GET operations) and
therefore even with the above limitation, this method of exposing CDS views
as OData service is very helpful. This also shows the power of Annotations
(New SQL) in the Core Data Services.

Das könnte Ihnen auch gefallen